test_print_next.py file-level

at sha256:c · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:8 docs: queue board-identity follow-ups so they survive the session Capt… · aaronrene · Sep 5, 2026
1 """Unit — print_next extract + format (§ONS.12 / §NXP.8)."""
2
3 from __future__ import annotations
4
5 from pathlib import Path
6
7 from tools.governance_hygiene.next_regen import extract_paste_fence_body
8 from tools.print_next.extract import (
9 CURRENT_NEXT_HEADING,
10 PROVENANCE_LINE_TEMPLATE,
11 PROVENANCE_SEPARATOR,
12 CurrentNextError,
13 CurrentNextResult,
14 extract_current_next,
15 format_current_next,
16 format_provenance_line,
17 )
18
19 VALID = """# Handover
20
21 ### Paste-ready prompt — demo
22
23 ```text
24 Phase demo.
25 Model: Auto
26 ```
27 """
28
29 FIXED_READ_AT = "2026-09-04T12:00:00Z"
30
31
32 def _write(tmp: Path, text: str) -> Path:
33 path = tmp / "docs" / "OVERSEER-HANDOVER.md"
34 path.parent.mkdir(parents=True, exist_ok=True)
35 path.write_text(text, encoding="utf-8")
36 return path
37
38
39 def _format(result: CurrentNextResult, **kwargs) -> str:
40 defaults = {
41 "repo_name": "test-git",
42 "repo_root_abs": "/tmp/repo",
43 "read_at": FIXED_READ_AT,
44 }
45 defaults.update(kwargs)
46 return format_current_next(result, **defaults)
47
48
49 def test_valid_handover_heading_and_body(tmp_path: Path) -> None:
50 path = _write(tmp_path, VALID)
51 result = extract_current_next(path, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None)
52 assert isinstance(result, CurrentNextResult)
53 assert result.heading == CURRENT_NEXT_HEADING
54 assert "Model: Auto" in result.fence
55 human = _format(result)
56 # §NXP.3.1 twelve-step layout: heading, blank, provenance, blank, fence.
57 assert human.startswith(CURRENT_NEXT_HEADING + "\n\n")
58 lines = human.splitlines(keepends=True)
59 assert lines[0] == CURRENT_NEXT_HEADING + "\n"
60 assert lines[1] == "\n"
61 assert lines[2].startswith("**Source:** ")
62 assert lines[3] == "\n"
63 assert lines[4] == "```text\n"
64 assert human.endswith("```\n")
65 assert "```text\nPhase demo.\nModel: Auto\n```\n" in human
66
67
68 def test_missing_file(tmp_path: Path) -> None:
69 missing = tmp_path / "docs" / "OVERSEER-HANDOVER.md"
70 result = extract_current_next(
71 missing, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None
72 )
73 assert isinstance(result, CurrentNextError)
74 assert result.reason == "handover_missing"
75
76
77 def test_heading_missing_even_if_other_fence(tmp_path: Path) -> None:
78 text = "# No paste heading\n\n```\nsome fence\nModel: Auto\n```\n"
79 path = _write(tmp_path, text)
80 result = extract_current_next(path, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None)
81 assert isinstance(result, CurrentNextError)
82 assert result.reason == "heading_missing"
83
84
85 def test_fence_missing(tmp_path: Path) -> None:
86 text = "### Paste-ready prompt — x\n\nNo fence here.\n"
87 path = _write(tmp_path, text)
88 result = extract_current_next(path, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None)
89 assert isinstance(result, CurrentNextError)
90 assert result.reason == "fence_missing"
91
92
93 def test_fence_empty(tmp_path: Path) -> None:
94 text = "### Paste-ready prompt — x\n\n```text\n \n```\n"
95 path = _write(tmp_path, text)
96 result = extract_current_next(path, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None)
97 assert isinstance(result, CurrentNextError)
98 assert result.reason == "fence_empty"
99
100
101 def test_model_missing(tmp_path: Path) -> None:
102 text = "### Paste-ready prompt — x\n\n```text\nNo model label here.\n```\n"
103 path = _write(tmp_path, text)
104 result = extract_current_next(path, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None)
105 assert isinstance(result, CurrentNextError)
106 assert result.reason == "model_missing"
107
108
109 def test_current_next_heading_exact() -> None:
110 assert CURRENT_NEXT_HEADING == "## CURRENT NEXT — paste this"
111
112
113 def test_reuses_extract_paste_fence_body(tmp_path: Path) -> None:
114 helper = extract_paste_fence_body(VALID)
115 assert helper is not None
116 path = _write(tmp_path, VALID)
117 outcome = extract_current_next(path, repo_relative_path="docs/OVERSEER-HANDOVER.md", lane=None)
118 assert isinstance(outcome, CurrentNextResult)
119 assert outcome.fence == helper
120
121
122 # --- §NXP.8 unit ---
123
124
125 def test_provenance_template_and_separator() -> None:
126 assert PROVENANCE_SEPARATOR == " · "
127 assert " · " in PROVENANCE_LINE_TEMPLATE
128 assert PROVENANCE_LINE_TEMPLATE == (
129 "**Source:** `{repo_name}` · `{repo_root_abs}` · `{doc_rel}` · lane `{lane}` · read `{read_at}`"
130 )
131
132
133 def test_provenance_fallbacks_unknown_name_and_dash_lane() -> None:
134 line = format_provenance_line(
135 repo_name=None,
136 repo_root_abs="/abs/root",
137 doc_rel="docs/OVERSEER-HANDOVER.md",
138 lane=None,
139 read_at=FIXED_READ_AT,
140 )
141 assert line == (
142 f"**Source:** `unknown` · `/abs/root` · `docs/OVERSEER-HANDOVER.md` · "
143 f"lane `-` · read `{FIXED_READ_AT}`"
144 )
145
146
147 def test_read_at_format_second_precision_z() -> None:
148 from tools.print_next.extract import utc_read_at
149 import re
150
151 stamp = utc_read_at()
152 assert re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", stamp)
153
154
155 def test_twelve_step_layout_byte_order(tmp_path: Path) -> None:
156 path = _write(tmp_path, VALID)
157 result = extract_current_next(path, repo_relative_path="docs/H.md", lane="product")
158 assert isinstance(result, CurrentNextResult)
159 human = _format(result, repo_root_abs="/r", read_at=FIXED_READ_AT)
160 expected_prov = (
161 f"**Source:** `test-git` · `/r` · `docs/H.md` · lane `product` · read `{FIXED_READ_AT}`"
162 )
163 assert human == (
164 f"{CURRENT_NEXT_HEADING}\n\n{expected_prov}\n\n```text\nPhase demo.\nModel: Auto\n```\n"
165 )
166
167
168 def test_board_name_violation_reused_not_forked() -> None:
169 from tools.workspace.board_names import (
170 board_name_violation,
171 check_next_unconfigured_advisory,
172 status_board_name_advisory,
173 )
174 import inspect
175
176 # Advisory helpers must call board_name_violation (no forked predicate).
177 src = inspect.getsource(check_next_unconfigured_advisory)
178 assert "board_name_violation" in src
179 src2 = inspect.getsource(status_board_name_advisory)
180 assert "board_name_violation" in src2
181 assert board_name_violation(
182 repo_name="test-git",
183 handover_basename="OVERSEER-HANDOVER.md",
184 roadmap_basename="ROADMAP.md",
185 strict=True,
186 )