8OI-512 / FS-518 regression coverage — :func:`oct.scaffold.run_scaffold`
9must materialise the full Option C project skeleton (directories, bundled
10files, ``.gitignore`` / ``.octignore`` entries including ``.venv/``) and
11behave idempotently (already-present paths land in ``skipped`` rather
12than being overwritten). ``dry_run=True`` must be strictly side-effect
15The ``include_venv`` flag and its health-warning companion are covered
16in :mod:`test_scaffold_venv`.
20- Verify full skeleton materialisation (directories and bundled files).
21- Verify idempotent re-runs land existing paths in ``skipped``.
22- Verify ``dry_run=True`` produces no filesystem side-effects.
29 L3 — assertion details
34- ``dry_run=True`` → no filesystem changes; messages populated.
35- All documented files appear in ``result.created`` on first run.
36- A second ``run_scaffold`` call on the same directory creates nothing
37 new and produces no duplicate-file errors.
40from __future__
import annotations
42from pathlib
import Path
50 """OI-512: dry_run emits plan messages and never touches the disk."""
51 result = run_scaffold(
"demo", tmp_path, dry_run=
True, include_venv=
False)
52 assert isinstance(result, ScaffoldResult)
53 assert result.created == []
54 assert not (tmp_path /
"demo").exists()
55 assert any(
"DRY RUN" in m
for m
in result.messages)
59 """FS-539: docs/, tests/, .option_c/, .option_c/logs/ all appear."""
60 result = run_scaffold(
"demo", tmp_path, include_venv=
False)
61 project = tmp_path /
"demo"
70 assert (project / sub).is_dir(), sub
71 assert project
in result.created
or (project /
"docs")
in result.created
75 """FS-539: debug_config + octrc land under .option_c/ with expected shape."""
76 run_scaffold(
"demo", tmp_path, include_venv=
False)
77 project = tmp_path /
"demo"
78 debug_cfg = project /
".option_c" /
"debug_config.json"
79 octrc = project /
".option_c" /
"octrc.json"
80 assert debug_cfg.is_file()
81 assert octrc.is_file()
83 assert '"_schema_version": "2.0"' in debug_cfg.read_text(encoding=
"utf-8")
84 assert '"sphinx_output"' in octrc.read_text(encoding=
"utf-8")
88 """FS-503 / FS-504: .gitignore and .octignore both include .venv/."""
89 run_scaffold(
"demo", tmp_path, include_venv=
False)
90 project = tmp_path /
"demo"
91 gitignore = (project /
".gitignore").read_text(encoding=
"utf-8")
92 octignore = (project /
".octignore").read_text(encoding=
"utf-8")
93 assert ".venv/" in gitignore
94 assert ".venv/" in octignore
96 assert ".env" in gitignore
97 assert "*.pem" in gitignore
101 """OI-512: a second run must skip everything, not overwrite."""
102 first = run_scaffold(
"demo", tmp_path, include_venv=
False)
104 second = run_scaffold(
"demo", tmp_path, include_venv=
False)
106 project = tmp_path /
"demo"
107 assert (project /
".option_c" /
"octrc.json")
in second.skipped
108 assert (project /
".option_c" /
"debug_config.json")
in second.skipped
109 assert (project /
".option_c" /
"oc_status.json")
in second.skipped
113 """OI-512: the return type must be a ScaffoldResult with the documented fields."""
114 result = run_scaffold(
"demo", tmp_path, include_venv=
False)
115 assert hasattr(result,
"created")
116 assert hasattr(result,
"skipped")
117 assert hasattr(result,
"messages")
118 assert hasattr(result,
"venv_path")
120 assert result.venv_path
is None
test_scaffold_writes_debug_config_and_octrc(Path tmp_path)
test_scaffold_is_idempotent(Path tmp_path)
test_scaffold_result_is_dataclass(Path tmp_path)
test_scaffold_creates_core_directories(Path tmp_path)
test_scaffold_writes_gitignore_with_venv(Path tmp_path)
test_dry_run_creates_nothing(Path tmp_path)