Files
will 25592fa6c2
ci / test (push) Successful in 6m14s
WillTools 2026-09-09 -- clean snapshot of the development repo for review
History-free snapshot of the private development repository at 77a82eb.
Code, docs and the public catalogue only: no plant or job knowledge
layers, no client, job or producer names (tools/scrub.py clean against
the widened term list; a second word-level grep clean). The intro deck is
left out because its slide images cannot be checked for job drawings.
2026-09-09 08:35:15 -05:00

1354 lines
54 KiB
Python

# -*- coding: utf-8 -*-
"""What the Reinforcing Suggestion button says, tested without Revit.
The button script itself cannot be exercised here -- it imports the Revit
API at module scope, as every pyRevit script does. So every sentence it
prints that could be wrong lives in `vibe.reinforcereport`, and this is
where those sentences are held to account.
The tests are mostly about DISTINCTIONS rather than formatting: that "no
donors were offered" never reads like "no donor matches", that a piece
measured to have nothing never reads like a piece nobody measured, that a
partial cover reads as an answer, and that a match resting on an
approximated outline can never print the bare word "exact".
No real panel marks appear anywhere in here. The names are P1 / P2 / T1.
"""
import re
import pytest
from vibe import foldreport as fold
from vibe import reinforcecore as core
from vibe import reinforcematch as match
from vibe import reinforcereport as R
# --------------------------------------------------------------- formatting
def test_a_stored_length_converts_feet_to_inches_once():
"""`length_in` takes FEET off a record and prints INCHES."""
assert R.length_in(2.5) == '30.00 in'
assert R.length_in(None) == '—'
def test_a_covers_distance_is_printed_without_converting_again():
"""`distance_in` takes INCHES -- `reinforcebind.covers` already
crossed the seam. A second conversion here is the 12x error this
project has paid for once, so the two formatters are named for what
they TAKE and are tested apart."""
assert R.distance_in(2.5) == '2.50 in'
assert R.distance_in(None) == '—'
# The whole point, as arithmetic: same number in, twelve times apart
# out. Nothing may ever route a covers distance through `length_in`.
assert R.length_in(2.5) != R.distance_in(2.5)
def test_rect_is_absolute_inches_both_axes():
"""Feet on the record, inches on the page, absolute from the start of
the piece -- never a fraction of panel length."""
assert R.rect((6.5, 10.583, 0.0, 8.0)) == '78.00..127.00 x 0.00..96.00'
assert R.rect(None) == '—'
def test_feature_label_names_what_bounds_a_strip():
assert R.feature_label({'kind': R.OPENING}) == 'opening'
assert R.feature_label({'kind': R.STRIP_X,
'between': R.VOID_VOID}) == \
'strip between two openings (along length)'
assert R.feature_label({'kind': R.STRIP_Y, 'between': R.VOID_EDGE,
'edge': 'y1'}) == \
'strip, opening to top (across height)'
# ------------------------------------------------- exactness and the asterisk
def test_exact_match_prints_exact():
assert R.exactness({'donor': 'P1', 'exact': True,
'approximate': False}) == 'exact'
def test_approximate_exact_match_is_always_starred():
"""HARD RULE: a piece flagged `outline_approximate` may never be
presented as an exact edge-condition match."""
got = R.exactness({'donor': 'P1', 'exact': True, 'approximate': True})
assert got == 'exact*'
assert got != 'exact'
def test_inexact_match_prints_the_distance_in_inches():
"""The distance arrives in inches and prints as inches, unconverted."""
assert R.exactness({'donor': 'P1', 'exact': False,
'distance': 0.25, 'approximate': False}) \
== 'off 0.25 in'
def test_a_tiny_distance_never_prints_as_a_rounded_zero():
"""`off 0.00 in` reads as exact. Only `exact` may."""
got = R.exactness({'donor': 'P1', 'exact': False, 'distance': 0.002,
'approximate': False})
assert got == 'off <0.01 in'
assert '0.00' not in got
def test_the_grain_note_says_the_numbers_are_not_measured_to_a_hundredth():
"""Two decimals is what was asked for; 0.01 in of precision is not
what it means, and the page says so where the numbers are rather than
in a footnote nobody reaches."""
note = R.GRAIN_NOTE
assert 'inches' in note
assert '1/8 in' in note
assert '0.01 in' in note
def test_short_label_distinguishes_the_two_kinds_of_strip():
assert R.short_label({'kind': R.STRIP_X,
'between': R.VOID_EDGE}) == 'strip to an edge'
assert R.short_label({'kind': R.STRIP_X,
'between': R.VOID_VOID}) == 'strip between openings'
def test_uncovered_feature_has_no_exactness():
assert R.exactness({'donor': None}) == '--'
# ------------------------------------------------------- index and staleness
def test_index_line_always_says_when_it_was_built():
cache = {'built_at': '2026-08-30 09:00:00', 'pieces': {'P1': {}}}
line = R.index_line(cache, {'built': 0}, False, False)
assert '2026-08-30 09:00:00' in line
assert 'cache' in line
def test_index_line_says_never_when_it_never_was():
line = R.index_line({'pieces': {}}, None, False, False)
assert 'never' in line
def test_index_line_reports_a_full_rebuild_as_such():
line = R.index_line({'built_at': 'x', 'pieces': {}}, {'built': 5},
True, True)
assert 'FULL REBUILD' in line
def test_staleness_note_names_the_edit_the_signature_cannot_see():
note = R.staleness_note(False)
assert 'opening moved or resized in place' in note
assert 'shift-click' in note.lower()
def test_staleness_note_is_withdrawn_after_a_full_rebuild():
note = R.staleness_note(True)
assert 'stale' in note
assert 'shift-click' not in note.lower()
def test_coverage_note_keeps_unmeasured_apart_from_empty():
notes = R.coverage_note({'coverage_unjudged': ['P9'], 'audited': True})
assert len(notes) == 1
assert 'could not be measured' in notes[0]
assert 'nobody knows what they have' in notes[0]
def test_coverage_note_says_when_the_outline_audit_never_ran():
notes = R.coverage_note({'audited': False})
assert any('never been run' in n for n in notes)
def test_coverage_note_is_silent_when_there_is_nothing_to_say():
assert R.coverage_note({'audited': True}) == []
# ------------------------------------------------------------- target states
def test_unjudged_target_does_not_read_as_no_suggestions():
head, _lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'unjudged'})
assert judged is False
assert 'could not be measured' in head
assert 'not "no suggestions"' in head
def test_measured_but_featureless_target_is_a_measured_answer():
head, _lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features'})
assert judged is False
assert 'was measured and has nothing to reinforce' in head
assert 'not a failure to look' in head
# ------------------------------------ the featureless-target search, in words
#
# Owner, 2026-09-01, after this exact report stayed silent about it: "这件儿
# 不应该你告诉我,应该reinforce告诉我。" `target_status == 'no_features'` used
# to stop at the sentence above. These hold the rest of the sentence to
# account -- what the report says once `shape_search_for` has actually run.
def _search(eligible=(), secondary=(), degenerate=False, considered=None):
return {'ran': True,
'considered': (considered if considered is not None
else len(eligible) + len(secondary)),
'eligible': list(eligible), 'secondary': list(secondary),
'degenerate': degenerate}
def _donor_row(name, tier='featureless', t=0.0, l=0.0, w=0.0,
design='WP2.0', master=False):
return {'name': name, 'tier': tier, 'thickness_diff_in': t,
'length_diff_ft': l, 'width_diff_ft': w,
'design_number': design, 'master': master}
def test_no_features_with_no_shape_search_reads_exactly_as_before():
"""An info dict with no `shape_search` key -- an older caller, or a bare
fixture -- must not change what the pinned test above already checks."""
head, lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features'})
assert judged is False
assert lines == []
assert 'was measured and has nothing to reinforce' in head
def test_no_features_reports_the_inverted_search_and_the_count():
_head, lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features',
'shape_search': _search(eligible=[_donor_row('P2')])})
assert judged is False
assert any('search inverted' in l for l in lines)
assert any('1 featureless donor(s) found' in l for l in lines)
def test_no_features_with_nobody_eligible_says_so_plainly():
_head, lines, _judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features',
'shape_search': _search(considered=4)})
assert any('Nobody survived the filter' in l for l in lines)
def test_no_features_with_only_donors_that_have_openings():
"""Requirement 3: a donor WITH openings is not obviously wrong when the
target has none -- it is offered, but the report says why it is second
best rather than presenting it as an ordinary match."""
_head, lines, _judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features',
'shape_search': _search(
secondary=[_donor_row('P9', tier='has_features')])})
assert any('No donor in the pool is also featureless' in l
for l in lines)
assert any('DO have openings of their own' in l for l in lines)
def test_no_features_flags_a_degenerate_ranking_instead_of_a_false_order():
_head, lines, _judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features',
'shape_search': _search(
eligible=[_donor_row('A'), _donor_row('B')], degenerate=True)})
assert any('cannot be told apart' in l for l in lines)
assert not any('ranked by thickness' in l for l in lines)
def test_no_features_notes_the_secondary_tier_alongside_the_eligible_one():
_head, lines, _judged = R.target_block(
{'target': 'T1', 'target_status': 'no_features',
'shape_search': _search(
eligible=[_donor_row('P2')],
secondary=[_donor_row('P9', tier='has_features')])})
assert any('featureless donor(s) found' in l for l in lines)
assert any('further' in l and 'openings of their own' in l
for l in lines)
def test_shape_search_rows_put_featureless_before_has_features():
search = _search(eligible=[_donor_row('P2')],
secondary=[_donor_row('P9', tier='has_features', l=0.5)])
rows = R.shape_search_rows(search)
assert rows[0][0] == 'P2' and rows[0][1] == 'no openings'
assert rows[1][0] == 'P9' and rows[1][1] == 'has openings'
def test_shape_search_rows_mark_a_master_donor():
search = _search(eligible=[_donor_row('P2', master=True)])
rows = R.shape_search_rows(search)
assert R.MASTER_MARK in rows[0][0]
def test_target_not_in_model_is_said_out_loud():
head, _lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'not_in_model'})
assert judged is False
assert 'not in this model' in head
def test_ordinary_target_is_judged_and_counts_its_features():
head, lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'ok',
'target_features': [{}, {}, {}]})
assert judged is True
assert '3 feature(s)' in head
assert lines == []
def test_target_flags_are_reported_without_blocking_the_run():
_head, lines, judged = R.target_block(
{'target': 'T1', 'target_status': 'ok', 'target_features': [{}]},
reinforced=1, on_hold=1)
assert judged is True
assert any('TICKET_IS_REINFORCED' in line for line in lines)
assert any('ON_HOLD' in line for line in lines)
def test_approximate_target_outline_is_flagged():
_head, lines, _judged = R.target_block(
{'target': 'T1', 'target_status': 'ok', 'target_features': [{}],
'target_approximate': True})
assert any('outline is approximated' in line for line in lines)
# ------------------------------------------------------------- the verdicts
def _suggestion(status, uncovered=(), needed=0, proposals=(), n=4,
donor_count=3, cover_count=0):
return match.Suggestion(status, proposals, uncovered, donor_count, n,
needed, cover_count)
def test_no_donors_says_nothing_was_judged():
head, lines = R.verdict(_suggestion(match.NO_DONORS, uncovered=(0, 1, 2, 3),
donor_count=0),
{'considered': 255, 'donors': 0})
assert 'NOT JUDGED' in head
body = ' '.join(lines)
assert 'not one comparison was made' in body
assert 'nothing was examined' in body
def test_a_cold_db_says_run_a_snapshot_not_no_match():
"""An empty donor index reads NO_DONORS -- but a COLD DB (nothing indexed
yet) must say "run a Snapshot", never "no donor matches" and never a silent
all-clear. This is the cardinal sin the distinction exists to prevent."""
head, lines = R.verdict(
_suggestion(match.NO_DONORS, uncovered=(0, 1, 2, 3), donor_count=0),
{'considered': 0, 'donors': 0, 'cold_db': True})
assert 'NOT JUDGED' in head
assert 'Snapshot' in head
body = ' '.join(lines)
assert 'no pieces at all' in body
# it explicitly contrasts itself with the all-clear and the no-match reads
assert 'not "all clear"' in body
assert 'Snapshot' in body
def test_a_cold_db_names_a_schema_discard_when_that_is_why():
"""When the old index was thrown away by a schema bump, `cold_reason`
carries the load error and the verdict says the index has to be rebuilt --
a different fix from a never-snapshotted index, so it says so."""
head, lines = R.verdict(
_suggestion(match.NO_DONORS, donor_count=0),
{'cold_db': True, 'cold_reason': 'schema 5, expected 6'})
body = ' '.join(lines)
assert 'schema 5, expected 6' in body
assert 'rebuilt' in body
def test_a_cold_db_and_an_ordinary_no_donors_never_read_the_same():
"""A cold DB and a pool that was there but wholly filtered out are two
different findings with two different fixes; the headline separates them."""
cold = R.verdict(_suggestion(match.NO_DONORS, donor_count=0),
{'considered': 0, 'donors': 0, 'cold_db': True})
filtered = R.verdict(_suggestion(match.NO_DONORS, donor_count=0),
{'considered': 255, 'donors': 0, 'cold_db': False})
assert cold[0] != filtered[0]
assert cold[1] != filtered[1]
# and a cold DB is still NOT the "judged, found nothing" answer
coverage = R.verdict(_suggestion(match.NO_COVERAGE),
{'considered': 12, 'donors': 12})
assert cold[0] != coverage[0]
def test_no_coverage_is_a_finding_not_a_gap():
head, lines = R.verdict(
_suggestion(match.NO_COVERAGE, uncovered=(0, 1, 2, 3)),
{'considered': 255, 'donors': 12})
assert 'JUDGED' in head
assert 'NOT JUDGED' not in head
assert 'a finding, not a gap' in ' '.join(lines)
def test_no_donors_and_no_coverage_never_read_the_same():
a = R.verdict(_suggestion(match.NO_DONORS), {'considered': 1, 'donors': 0})
b = R.verdict(_suggestion(match.NO_COVERAGE),
{'considered': 1, 'donors': 1})
assert a[0] != b[0]
assert a[1] != b[1]
def test_partial_is_presented_as_an_answer():
head, lines = R.verdict(
_suggestion(match.PARTIAL, uncovered=(3,), needed=2, n=4),
{'considered': 255, 'donors': 40})
assert head.startswith('PARTIAL COVER')
assert '2 donor(s) account for 3 of 4' in head
assert 'an answer, not a failure' in ' '.join(lines)
def test_complete_counts_the_covers_found():
head, lines = R.verdict(
_suggestion(match.COMPLETE, needed=2, n=4, cover_count=7),
{'considered': 255, 'donors': 40})
assert head.startswith('COMPLETE COVER')
assert '7 cover(s)' in ' '.join(lines)
# ------------------------------------------------------------------- tables
def _row(i, kind=R.OPENING, donor=None, exact=False, distance=None,
approximate=False, through_unjudged=False, strip=None,
between=None, edge=None, donor_index=0):
return {'target_index': i, 'kind': kind, 'between': between, 'edge': edge,
'rect': (0.0, 1.0, 0.0, 2.0), 'strip_ft': strip,
'donor': donor, 'donor_index': donor_index, 'distance': distance,
'exact': exact, 'donor_rect': None, 'approximate': approximate,
'through_unjudged': through_unjudged}
# ------------------------------------------------------- the feature-ID column
def test_feature_id_cell_pairs_target_and_donor_ids():
"""A covered feature names both registry ids -- target and donor -- so a
reader can see the numbering the shared vocabulary assigned."""
cell = R.feature_id_cell({'target_feature_id': 7, 'donor': 'P1',
'donor_feature_id': 7})
assert 'target #7' in cell
assert 'donor #7' in cell
def test_feature_id_cell_says_when_no_donor_carries_the_shape():
"""A target descriptor no donor produced projects to None -- the
informative "nobody has this shape" signal, never blank, never an error."""
cell = R.feature_id_cell({'target_feature_id': None, 'donor': None})
assert 'not in donor vocabulary' in cell
# and it is not silently empty
assert cell.strip() != ''
def test_feature_id_cell_uncovered_target_still_shows_its_own_id():
"""A target the proposal did not cover still has a registry id if some
donor somewhere carries its shape; the cell shows it with no donor half."""
cell = R.feature_id_cell({'target_feature_id': 3, 'donor': None})
assert 'target #3' in cell
assert 'donor' not in cell
def test_feature_id_column_is_present_and_last():
"""The feature-by-feature table carries the id column, appended so the
existing column order is unchanged."""
assert R.FEATURE_COLUMNS[-1] == 'feature-ID'
rows = R.feature_rows([_row(0, donor='P1')])
assert len(rows[0]) == len(R.FEATURE_COLUMNS)
def test_every_target_feature_gets_a_row():
rows = R.feature_rows([_row(0, donor='P1', exact=True), _row(1),
_row(2, donor='P2', distance=0.2)],
_suggestion(match.PARTIAL, uncovered=(1,), n=3))
assert len(rows) == 3
def test_a_feature_nobody_has_says_so_loudly():
rows = R.feature_rows([_row(0)],
_suggestion(match.PARTIAL, uncovered=(0,), n=1))
assert rows[0][4] == 'NOBODY HAS IT'
def test_a_feature_this_set_missed_is_not_the_same_as_nobody_having_it():
rows = R.feature_rows([_row(0)], _suggestion(match.COMPLETE, n=1))
assert rows[0][4] == 'not in this set (another donor has it)'
assert 'NOBODY' not in rows[0][4]
def test_unjudged_penetration_is_noted_on_the_feature_row():
rows = R.feature_rows([_row(0, donor='P1', exact=True,
through_unjudged=True)], None)
assert rows[0][6] == 'penetration not judged'
def test_donor_rows_star_an_approximate_donor():
rows = R.donor_rows([_row(0, donor='P1', exact=True, approximate=True)])
assert rows[0][0] == 'P1*'
def test_donor_rows_group_by_donor_and_count_exacts():
rows = R.donor_rows([
_row(0, donor='P1', exact=True),
_row(1, donor='P1', distance=0.3),
_row(2, donor='P2', exact=True),
])
assert [r[0] for r in rows] == ['P1', 'P2']
# column 1 is provenance; the counts moved right when it was added
assert rows[0][R.DONOR_COLUMNS.index('features it covers')] == '2'
assert rows[0][R.DONOR_COLUMNS.index('of those, exact')] == '1'
def test_donor_rows_star_a_donor_named_approximate_by_the_pool():
rows = R.donor_rows([_row(0, donor='P1', exact=True)],
approximate_names=['P1'])
assert rows[0][0] == 'P1*'
def test_uncovered_rows_list_only_what_nobody_has():
rows = R.uncovered_rows(
[_row(0, donor='P1'), _row(1), _row(2)],
_suggestion(match.PARTIAL, uncovered=(2,), n=3))
assert len(rows) == 1
assert rows[0][0] == '2'
def test_rejection_rows_explain_every_reason_in_order_of_size():
rows = R.rejection_rows({'rejected': {'prefix': 400, 'thickness': 11,
'unjudged': 2}})
assert [r[0] for r in rows] == ['prefix', 'thickness', 'unjudged']
assert 'could not be judged' in rows[2][2]
def test_every_design_rejection_reason_is_explained_in_the_table():
"""A pool that shrank without saying why is a silent exclusion, and the
design rule is the biggest cut this filter makes. Its three reasons are
three different findings and the table must not blur them."""
rows = R.rejection_rows({'rejected': {'design': 300, 'design_unknown': 5,
'design_target_unknown': 1}})
why = dict((r[0], r[2]) for r in rows)
assert 'DIFFERENT DESIGN NUMBER' in why['design']
assert 'never assumed to match' in why['design_unknown']
assert 'TARGET' in why['design_target_unknown']
assert len(set(why.values())) == 3
def test_proposal_rows_report_size_and_exactness():
p = match.Proposal((0, 1), ('P1', 'P2'),
((0, 0, 0.0), (1, 0, 0.25)), ())
rows = R.proposal_rows(_suggestion(match.COMPLETE, proposals=(p,), n=2))
assert rows[0][1] == 'P1, P2'
assert rows[0][3] == '2 / 2'
assert rows[0][4] == '1'
# ---------------------------------------------------------------- footnotes
@pytest.mark.parametrize('rows,info', [
([_row(0, donor='P1', approximate=True)], {}),
([], {'target_approximate': True}),
([], {'approximate_in_pool': ['P1']}),
])
def test_footnote_shows_whenever_a_star_could_appear(rows, info):
assert R.needs_footnote(rows, info) is True
def test_footnote_is_withheld_when_nothing_is_approximated():
assert R.needs_footnote([_row(0, donor='P1')], {}) is False
def test_footnote_text_says_a_star_is_not_a_measured_exact():
assert 'never a measured exact match' in R.APPROX_FOOTNOTE
def test_read_only_line_says_it_writes_nothing():
assert 'writes nothing' in R.read_only_line()
# ------------------------------------------------- MASTER, said out loud
#
# The mark is worth nothing if the report does not say what it means. A
# reader who sees a dagger and guesses is exactly the failure this module
# exists to prevent -- and the thing most likely to be guessed WRONG here is
# that MASTER outranks a better fit. It does not, and the footnote says so.
def test_a_master_donor_is_marked_and_the_mark_is_not_the_approximate_star():
assert R.mark('P1', ['P1']) == 'P1' + R.MASTER_MARK
assert R.mark('P1', []) == 'P1'
assert R.MASTER_MARK != '*'
def test_a_donor_can_be_both_approximate_and_a_master():
both = R.mark('P1', ['P1'], approximate=True)
assert '*' in both and R.MASTER_MARK in both
def test_donor_rows_name_the_provenance_of_every_donor():
rows = R.donor_rows([_row(0, donor='P1', exact=True),
_row(1, donor='P2', exact=True)],
master_names=['P1'])
prov = R.DONOR_COLUMNS.index('provenance')
assert 'MASTER' in rows[0][prov] and 'reviewed' in rows[0][prov]
# and the un-reviewed donor is not left blank, which would read as
# "unknown" rather than as the finding it is
assert rows[1][prov] == 'reinforced only'
def test_donor_rows_take_the_master_flag_off_the_explain_row_too():
rows = R.donor_rows([dict(_row(0, donor='P1'), donor_master=True)])
assert rows[0][0] == 'P1' + R.MASTER_MARK
def test_proposal_rows_count_the_reviewed_donors():
p = match.Proposal((0, 1), ('P1', 'P2'),
((0, 0, 0.0), (1, 0, 0.0)), (), master_keys=('P2',))
rows = R.proposal_rows(_suggestion(match.COMPLETE, n=2, proposals=(p,)))
col = R.PROPOSAL_COLUMNS.index('reviewed (MASTER)')
assert rows[0][col] == '1'
assert 'P2' + R.MASTER_MARK in rows[0][1]
def test_the_footnote_says_master_is_a_tie_break_not_a_trump():
body = R.MASTER_FOOTNOTE
assert 'reviewed' in body
assert 'tie-break' in body
assert 'never outranks a donor that fits better' in body
# and it must not let anyone read MASTER as merely "reinforced"
assert 'TICKET_IS_REINFORCED' in body
def test_the_footnote_only_shows_when_a_mark_is_actually_printed():
assert R.needs_master_footnote([], {'donors': 5}) is False
assert R.needs_master_footnote([], {'master_donors': ['P1']}) is True
assert R.needs_master_footnote(
[dict(_row(0, donor='P1'), donor_master=True)], {}) is True
def test_a_pool_with_no_master_says_so_rather_than_staying_silent():
"""Absence of daggers must be readable as a fact, not as a missing feature."""
lines = R.master_note({'donors': 12, 'master_donors': []})
body = ' '.join(lines)
assert 'No donor in this pool is typed MASTER' in body
assert 'not' in body and 'reviewed' in body
def test_nothing_is_claimed_when_there_was_no_pool_at_all():
assert R.master_note({'donors': 0, 'master_donors': []}) == []
def test_the_master_note_names_them_and_repeats_the_ruling():
lines = R.master_note({'donors': 12, 'master_donors': ['P1', 'P2']})
body = ' '.join(lines)
assert 'P1' in body and 'P2' in body
assert 'never outranks a better fit' in body
assert 'fit equally well' in body
def test_an_unmapped_role_reads_as_not_run_never_as_no_masters():
"""The distinction this whole module exists to protect, one more time.
'nobody looked' and 'looked and found none' are different answers about
provenance, and the second is the one that would quietly reassure a
reader who has no reviewed donors and no idea the check is off.
"""
not_run = ' '.join(R.master_note(
{'donors': 12, 'master_donors': [], 'master_unjudged': True}))
none_found = ' '.join(R.master_note(
{'donors': 12, 'master_donors': []}))
assert 'did not run' in not_run
assert 'nobody looked' in not_run.lower()
assert 'identity_description' in not_run
assert not_run != none_found
assert 'did not run' not in none_found
# ------------------------------------------ SAME ELEVATION, said out loud
#
# The mark is worth nothing if the report does not say what it means, and the
# incident this exists for (WP425, 2026-09-02) was invisible precisely
# because nothing on the page said why WP133 beat WP234. Mirrors the MASTER
# section exactly: the mark, the column, the footnote, and the note for an
# empty pool.
def test_a_same_elevation_donor_is_marked_and_the_mark_differs_from_master():
assert R.mark('P1', same_elevation_names=['P1']) == 'P1' + R.ELEVATION_MARK
assert R.mark('P1', same_elevation_names=[]) == 'P1'
assert R.ELEVATION_MARK != R.MASTER_MARK
assert R.ELEVATION_MARK != '*'
def test_a_donor_can_carry_all_three_marks_at_once():
all_three = R.mark('P1', ['P1'], approximate=True,
same_elevation_names=['P1'])
assert '*' in all_three
assert R.MASTER_MARK in all_three
assert R.ELEVATION_MARK in all_three
def test_proposal_rows_count_the_same_elevation_donors():
p = match.Proposal((0, 1), ('P1', 'P2'),
((0, 0, 0.0), (1, 0, 0.0)), (),
same_elevation_keys=('P2',))
rows = R.proposal_rows(_suggestion(match.COMPLETE, n=2, proposals=(p,)))
col = R.PROPOSAL_COLUMNS.index('same elevation')
assert rows[0][col] == '1'
assert 'P2' + R.ELEVATION_MARK in rows[0][1]
def test_the_proposals_header_names_same_elevation_as_the_last_criterion():
"""The header sentence is a claim about ranking order, and it went stale
the moment a new criterion was added below the ones it already named."""
head = R.render(_S(), _info(), [], {'built_at': _now_stamp(),
'pieces': {}})
prose = ' '.join(_headline(head))
assert ('fewest donors first, then most exact, then most reviewed, '
'then same elevation') in prose
def test_the_elevation_footnote_says_it_is_a_tie_break_not_a_trump():
body = R.ELEVATION_FOOTNOTE
assert 'building elevation' in body
assert 'last' in body.lower()
assert 'never outranks a donor that fits better' in body
def test_the_elevation_footnote_only_shows_when_a_mark_is_actually_printed():
assert R.needs_elevation_footnote({'donors': 5}) is False
assert R.needs_elevation_footnote(
{'same_elevation_donors': ['P1']}) is True
p = match.Proposal((0,), ('P1',), ((0, 0, 0.0),), (),
same_elevation_keys=('P1',))
assert R.needs_elevation_footnote({}, _suggestion(
match.COMPLETE, n=1, proposals=(p,))) is True
_BAND = {'axis': 'X', 'min': 10.0, 'max': 10.5}
_BAND_SIGNAL = {'group': None, 'band': _BAND}
_GROUP_SIGNAL = {'group': 'E3.16', 'band': _BAND}
_NO_SIGNAL = {'group': None, 'band': None}
def test_band_label_formats_axis_and_inches():
assert R.band_label(_BAND) == 'X @ 120.00 in to 126.00 in'
assert R.band_label(None) is None
assert R.band_label({'axis': 'X'}) is None # missing min/max
assert R.band_label('not a dict') is None # never raises
def test_elevation_signal_label_prefers_the_group_when_present():
"""The group (the ACCELERATOR) is more legible to an engineer than a
coordinate band, so it wins when both happen to be on the record --
neither is privileged in correctness, only in what prints."""
assert R.elevation_signal_label(_GROUP_SIGNAL) == 'sheet E3.16'
def test_elevation_signal_label_falls_back_to_the_band():
assert (R.elevation_signal_label(_BAND_SIGNAL) ==
'X @ 120.00 in to 126.00 in')
def test_elevation_signal_label_is_none_when_neither_source_answered():
assert R.elevation_signal_label(_NO_SIGNAL) is None
assert R.elevation_signal_label(None) is None
assert R.elevation_signal_label({}) is None
def test_elevation_source_label_names_which_source_answered():
assert R.elevation_source_label(core.ELEVATION_BY_GROUP) == 'same sheet'
assert R.elevation_source_label(core.ELEVATION_BY_BAND) == 'same geometry'
assert R.elevation_source_label(None) is None
assert R.elevation_source_label('nonsense') is None
def test_an_undetermined_target_elevation_reads_as_could_not_judge():
"""Nobody looked, not nobody matches -- the same distinction
`master_note` already draws for the reviewed-template signal. Neither
source -- the group nor the geometric floor -- answered."""
lines = R.elevation_note({'target': 'T1', 'donors': 12,
'target_elevation': _NO_SIGNAL,
'same_elevation_donors': []})
body = ' '.join(lines)
assert 'could not be determined' in body
assert 'nobody looked' in body.lower()
def test_an_absent_target_elevation_key_also_reads_as_could_not_judge():
"""A caller that never set the key at all (or set it to None) must read
the same as the explicit two-None-fields shape -- never raise."""
lines = R.elevation_note({'target': 'T1', 'donors': 12,
'same_elevation_donors': []})
assert 'could not be determined' in ' '.join(lines)
def test_a_pool_with_no_same_elevation_donor_says_so_rather_than_staying_silent():
lines = R.elevation_note({'target': 'T1', 'donors': 12,
'target_elevation': _BAND_SIGNAL,
'same_elevation_donors': []})
body = ' '.join(lines)
assert 'No donor in this pool shares' in body
assert 'X @ 120.00 in to 126.00 in' in body
def test_nothing_is_claimed_about_elevation_when_there_was_no_pool_at_all():
assert R.elevation_note({'target': 'T1', 'donors': 0,
'target_elevation': _BAND_SIGNAL,
'same_elevation_donors': []}) == []
def test_the_elevation_note_names_them_and_repeats_the_ruling():
lines = R.elevation_note({
'target': 'T1', 'donors': 12,
'target_elevation': _BAND_SIGNAL,
'same_elevation_donors': ['P1', 'P2'],
'same_elevation_sources': {'P1': core.ELEVATION_BY_GROUP,
'P2': core.ELEVATION_BY_BAND}})
body = ' '.join(lines)
assert 'P1' in body and 'P2' in body
assert 'X @ 120.00 in to 126.00 in' in body
assert 'never outranks a donor that fits better' in body
def test_the_elevation_note_says_which_source_answered_each_donor():
lines = R.elevation_note({
'target': 'T1', 'donors': 12,
'target_elevation': _GROUP_SIGNAL,
'same_elevation_donors': ['P1', 'P2'],
'same_elevation_sources': {'P1': core.ELEVATION_BY_GROUP,
'P2': core.ELEVATION_BY_BAND}})
body = ' '.join(lines)
assert 'P1 (same sheet)' in body
assert 'P2 (same geometry)' in body
assert 'sheet E3.16' in body
# ------------------------------------------------------- the declared scope
def test_scope_lines_say_which_pool_the_answer_came_from():
"""A pool bounded by a declared scope and a pool bounded by nothing
print the same shaped page, so the page has to say which it had."""
lines = R.scope_lines({'scope': {
'declared': True, 'label': 'piece marks beginning PNL',
'declaration': ['scope declared by somebody'],
'line': 'NOT JUDGED, OUT OF SCOPE: 3 indexed donor(s) ...',
'target_in_scope': True, 'target_annotation': None}})
assert any('NOT JUDGED, OUT OF SCOPE' in ln for ln in lines)
assert any('scope declared by somebody' in ln for ln in lines)
def test_scope_lines_flag_a_target_outside_the_scope():
"""Nothing the user selected is refused -- it is answered, with the
warning that the knowledge behind it was never validated for it."""
lines = R.scope_lines({'scope': {
'declared': True, 'label': 'piece marks beginning PNL',
'declaration': [], 'line': 'x',
'target_in_scope': False,
'target_annotation': 'JUDGED OUTSIDE THE DECLARED SCOPE ...'}})
assert any('JUDGED OUTSIDE THE DECLARED SCOPE' in ln for ln in lines)
def test_scope_lines_are_empty_only_when_there_is_no_scope_information():
assert R.scope_lines({}) == []
def test_the_prefix_rejection_reads_as_a_scope_decision():
"""It used to read 'not a WP wall panel' -- one job's division of labour,
in a shareable repository, in the user-visible wording."""
why = dict((row[0], row[2]) for row in
R.rejection_rows({'rejected': {'prefix': 2}}))
assert 'declared scope' in why['prefix']
# ------------------------------------------------------ the donor cap, in words
#
# The report is where the two kinds of "not covered" are easiest to collapse
# into one apology, and they must not be: a feature the cap left out has a
# donor waiting; a feature nobody has must be detailed from scratch.
class _FakeSuggestion(object):
"""Just the fields the report reads. The matcher is tested elsewhere."""
def __init__(self, status, uncovered=(), capped_out=(), cap=4,
needed=4, features=8, proposals=(), cover_count=1):
self.status = status
self.uncovered = tuple(uncovered)
self.capped_out = tuple(capped_out)
self.donor_cap = cap
self.donors_needed = needed
self.target_feature_count = features
self.proposals = tuple(proposals)
self.cover_count = cover_count
self.donor_count = 9
def test_a_capped_answer_says_somebody_has_the_missing_features():
head, lines = R.verdict(
_FakeSuggestion(match.CAPPED, capped_out=(4, 5, 6, 7)), {})
assert head.startswith('CAPPED')
body = ' '.join(lines)
assert 'is** covered by somebody' in body or 'covered by somebody' in body
assert 'at most 4' in body
def test_a_capped_answer_is_not_worded_as_nobody_has_it():
"""The distinction the whole feature turns on."""
capped = ' '.join(R.verdict(
_FakeSuggestion(match.CAPPED, capped_out=(4,)), {})[1])
partial = ' '.join(R.verdict(
_FakeSuggestion(match.PARTIAL, uncovered=(4,)), {})[1])
assert 'no indexed donor at all' in partial
assert 'no indexed donor at all' not in capped
def test_a_partial_answer_also_reports_what_the_cap_left_out():
"""Both can be true at once, and both get said."""
head, lines = R.verdict(
_FakeSuggestion(match.PARTIAL, uncovered=(8,), capped_out=(4, 5),
features=9), {})
assert head.startswith('PARTIAL')
body = ' '.join(lines)
assert 'no indexed donor at all' in body
assert 'covered by somebody' in body
# 9 features, 1 nobody has, 2 the cap dropped -> 6 actually covered
assert 'cover 6 of the 9' in body
def test_capped_rows_list_only_what_the_cap_dropped():
rows = [_row(0, donor='P1'), _row(1), _row(2), _row(3)]
got = R.capped_rows(rows, _FakeSuggestion(match.CAPPED,
uncovered=(3,),
capped_out=(1, 2)))
assert [r[0] for r in got] == ['1', '2']
def test_cap_note_is_silent_when_the_cap_did_not_bite():
assert R.cap_note(_FakeSuggestion(match.COMPLETE)) == []
assert R.cap_note(None) == []
said = R.cap_note(_FakeSuggestion(match.CAPPED, capped_out=(1,)))
assert said and 'at most 4 donors' in said[0]
def test_a_feature_the_cap_dropped_does_not_read_as_nobody_has_it():
"""On the feature-by-feature table the two look identical -- both simply
uncovered -- so the words have to carry the difference."""
rows = [_row(0), _row(1)]
got = R.feature_rows(rows, _FakeSuggestion(match.PARTIAL,
uncovered=(0,),
capped_out=(1,)))
assert got[0][4] == 'NOBODY HAS IT'
assert got[1][4] == 'LEFT OUT BY THE 4-DONOR CAP'
# ------------------------------------------------------------------- offline
#
# An offline answer is a strictly weaker claim than a live one and the page
# has to say so in the same breath as the answer, not in a footnote. Three
# things are held to account here: that the banner is present and unmissable,
# that the build stamp travels with it, and that the staleness note offline
# names EVERYTHING it cannot see rather than only the geometry edit the live
# note names.
def test_the_offline_banner_says_snapshot_and_says_not_the_model():
line = R.offline_banner({'built_at': '2026-08-30 09:00:00'})
assert 'OFFLINE' in line
assert 'snapshot' in line
assert 'not the model' in line
assert '2026-08-30 09:00:00' in line
def test_the_offline_banner_admits_an_index_that_was_never_built():
assert 'never' in R.offline_banner({})
def test_index_line_offline_says_the_model_was_never_opened():
line = R.index_line({'built_at': 'x', 'pieces': {}}, None, False, False,
offline=True)
assert 'never opened' in line
assert 'nothing needed rebuilding' not in line
def test_index_line_counts_donors_apart_from_targets():
"""A piece indexed only so it can be a target is not a donor, and calling
it one overstates the pool that was actually searched."""
cache = {'built_at': 'x', 'pieces': {
'P1': {'reinforced': 1, 'on_hold': 0},
'T1': {'reinforced': 0, 'on_hold': 0},
'H1': {'reinforced': 1, 'on_hold': 1},
}}
line = R.index_line(cache, None, False, False)
assert '**1** indexed donor(s)' in line
assert '**2** piece(s) measured as possible targets' in line
def test_staleness_offline_names_everything_it_cannot_see():
note = R.staleness_note(False, offline=True)
assert 'opening moved or resized' in note
assert 'newly reinforced' in note # caught live, blind offline
assert 'added or deleted' in note
assert 'shift-click' not in note.lower() # meaningless at a command line
assert 'refresh' in note.lower()
def test_staleness_offline_is_not_withdrawn_by_a_full_rebuild_flag():
"""A rebuild happened in some earlier session, on some earlier model
state. It rules out nothing about the file being read now."""
assert R.staleness_note(True, offline=True) == \
R.staleness_note(False, offline=True)
def test_not_in_the_index_is_not_not_in_the_model():
head, _lines, judged = R.target_block({'target': 'T1',
'target_status': 'not_in_index'})
assert judged is False
assert 'not in the index' in head
assert 'does not exist' in head # explicitly denied, not implied
other, _l, _j = R.target_block({'target': 'T1',
'target_status': 'not_in_model'})
assert head != other
# --------------------------------------------------- the design refusal
#
# Owner, 2026-09-01: "选择母版的目标,必须得是跟自己的design number一样的panel。
# ... 给我俩WP1.0的母版,压根用不了。" What this section holds to account is that
# the page REFUSES -- names the design, the counts and the way out -- and never
# prints a donor of another design, however it is labelled.
def _design(**kw):
base = {'status': 'none_match', 'refused': True, 'enforced': True,
'ran': True, 'target': 'WP2.0', 'target_key': 'WP2',
'index_status': 'recorded', 'candidates': 412, 'considered': 690,
'same_design': [], 'unreadable': [],
'designs_seen': {'WP1': 300, 'WP3': 110, '?': 2}}
base.update(kw)
return base
def test_no_refusal_when_the_design_rule_is_content():
assert R.design_refusal({'design': _design(status='ok', refused=False)}) \
is None
assert R.design_refusal({}) is None
def test_the_refusal_names_the_design_the_counts_and_the_way_out():
head, lines = R.design_refusal({'target': 'WP204',
'design': _design()})
assert 'WP2' in head and 'WP204' in head
body = ' '.join(lines)
assert 'WP1 (300)' in body and 'WP3 (110)' in body
assert 'unreadable (2)' in body # never counted as a design
assert '412' in body and '690' in body
assert 'by hand' in body # the way out
def test_the_refusal_says_the_rule_is_a_filter_not_a_preference():
_head, lines = R.design_refusal({'target': 'WP204', 'design': _design()})
body = ' '.join(lines)
assert 'filter' in body
assert 'not offer a donor of another design' in body
def test_the_refusal_states_the_packet_suffix_rule():
"""A reader has to be able to tell "no WP2 donor" from "your WP2.A donor
was thrown away for its suffix". The nomenclature ruling is on the page."""
_head, lines = R.design_refusal({'target': 'WP204', 'design': _design()})
body = ' '.join(lines)
assert 'WP2.0' in body and 'WP2.A' in body
def test_an_unrecorded_index_and_an_unread_one_read_differently():
"""Two different fixes -- rebuild the index versus map the role -- so two
different sentences. Both say the snapshot has to be re-run."""
a = R.design_refusal({'target': 'WP204',
'design': _design(status='index_not_recorded',
index_status='not_recorded')})
b = R.design_refusal({'target': 'WP204',
'design': _design(status='index_unread',
index_status='unread')})
assert a[0] != b[0]
assert 'predates' in a[0]
assert 'Re-run the snapshot' in ' '.join(a[1])
assert 'Re-run the snapshot' in ' '.join(b[1])
assert 'panel.design_number' in ' '.join(b[1])
# And neither may read as "these all match".
for got in (a, b):
assert 'not' in ' '.join(got[1]) and 'match' in ' '.join(got[1])
def test_a_target_with_no_design_number_gets_its_own_refusal():
head, lines = R.design_refusal({
'target': 'WP204',
'design': _design(status='target_unknown', target=None,
target_key=None)})
assert 'WP204' in head
assert 'empty' in ' '.join(lines)
assert 'design_number' in ' '.join(lines)
def test_designs_seen_never_trails_off_into_nothing():
assert R.designs_seen_text({}) == 'none'
assert R.designs_seen_text({'WP1': 1, 'WP2': 9}) == 'WP2 (9), WP1 (1)'
def test_the_design_refusal_reaches_the_target_block_as_not_judged():
head, lines, judged = R.target_block(
{'target': 'WP204', 'target_status': 'ok',
'target_features': [{}], 'design': _design()})
assert judged is False
assert 'WP2' in head
assert lines # the counts and the way out
def test_a_target_that_could_not_be_measured_outranks_the_design_refusal():
"""Two findings at once. The geometry one is the more fundamental and is
what the reader needs first; the design rule never even ran on a piece
nobody could measure."""
head, _lines, judged = R.target_block(
{'target': 'WP204', 'target_status': 'unjudged',
'design': _design()})
assert judged is False
assert 'could not be measured' in head
# ------------------------------------------------------------- the whole page
def _info(**kw):
base = {'target': 'T1', 'target_status': 'ok', 'target_features': [{}],
'considered': 3, 'donors': 1, 'rejected': {}, 'rejected_names': {},
'master_donors': [], 'approximate_in_pool': [],
'features_by_donor': {}, 'audited': True}
base.update(kw)
return base
def _blocks(sections):
"""Every md block of every section, folded or not -- these tests are about
what the report SAYS, and `foldreport` is where folding is tested."""
out = []
for section in sections:
out.extend(b[1] for b in section.blocks if b[0] == 'md')
return out
def _headline(sections):
return [b[1] for b in sections[0].blocks if b[0] == 'md']
def _section(sections, key):
for section in sections:
if section.key == key:
return section
return None
def test_render_opens_with_the_offline_banner_and_the_index_line():
out = R.render(None, _info(target_status='not_in_index'), [],
{'built_at': 'x', 'pieces': {}}, offline=True)
md = _headline(out)
assert md[0].startswith('# ')
assert 'OFFLINE' in md[1]
assert any('Index:' in line for line in md)
def test_render_never_prints_the_offline_banner_when_it_is_live():
out = R.render(None, _info(target_status='not_in_index'), [],
{'built_at': 'x', 'pieces': {}})
assert not any('OFFLINE' in line for line in _blocks(out))
def test_the_whole_page_refuses_and_offers_no_donor_of_another_design():
"""End to end: a WP2 target, a pool of WP1s. The page must say so, must
keep every paragraph of the refusal, and must not print a proposal."""
out = R.render(None, _info(target='WP204', design=_design(),
rejected={'design': 412},
rejected_names={'design': ['WP101']}),
[], {'built_at': 'x', 'pieces': {}})
md = ' '.join(_blocks(out))
assert 'NOT JUDGED' in md
assert 'No donor with design number WP2' in md
assert 'by hand' in md # the way out survived the render
assert 'Proposals' not in md
# The index stamp and the staleness note still print, because they are
# what tells a reader whether to believe a refusal.
assert any('Index:' in line for line in _headline(out))
assert _section(out, 'staleness') is not None
def test_a_could_not_judge_page_still_carries_the_staleness_note():
"""The one page most likely to be read as 'nothing to see here'. It used
to print a stripped-down 'NOT JUDGED' and exit, losing the index stamp and
the staleness note -- which are what tell a reader whether to believe the
refusal."""
out = R.render(None, _info(target_status='not_in_index'), [],
{'pieces': {}}, offline=True)
assert any('checked against the model' in line for line in _blocks(out))
assert _section(out, 'staleness').problem # and it is OPEN
def test_render_puts_the_featureless_donor_table_on_the_headline():
"""The owner's real complaint was silence, so this table belongs on the
part of the page that is never folded -- the headline, same as an
ordinary proposal."""
search = _search(eligible=[_donor_row('P2')])
out = R.render(None, _info(target_status='no_features',
shape_search=search),
[], {'built_at': 'x', 'pieces': {}})
assert 'MEASURED -- NO OPENINGS' in ' '.join(_headline(out))
tables = [b for b in out[0].blocks if b[0] == 'table']
assert tables and tables[0][2][0][0] == 'P2'
def test_render_with_no_shape_search_keeps_the_old_not_judged_heading():
out = R.render(None, _info(target_status='no_features'), [],
{'built_at': 'x', 'pieces': {}})
assert 'NOT JUDGED' in ' '.join(_headline(out))
assert not any(b[0] == 'table' for b in out[0].blocks)
# ---------------------------------------------- what folds and what opens
#
# The owner's rule, 2026-08-30: everything below the answer starts folded,
# and a section opens itself only when it has a problem in it. The contract
# that buys is "if nothing below the headline is open, nothing needs me",
# so what these tests hold to account is which sections claim a problem.
class _P(object):
donors = ('P1',)
masters = ()
same_elevation = ()
covered_count = 1
exact_count = 1
total_distance = 0.0
def donor_for(self, _i):
return None
class _S(object):
status = match.COMPLETE
proposals = (_P(),)
best = _P()
uncovered = ()
capped_out = ()
donor_cap = 4
donors_needed = 1
cover_count = 1
target_feature_count = 1
def summary(self):
return 'one donor covers it'
def test_the_answer_is_the_headline_and_is_never_folded():
out = R.render(_S(), _info(), [], {'pieces': {}})
assert out[0].headline is True
assert out[0].is_open is True
heads = ' '.join(_headline(out))
assert 'Target' in heads and 'Proposals' in heads
def test_render_emits_tables_as_tables_not_as_text():
"""A terminal has to be able to align them, so they stay structured."""
out = R.render(_S(), _info(), [], {'pieces': {}}, offline=True)
tables = [b for b in out[0].blocks if b[0] == 'table']
assert tables
assert tables[0][1] == R.PROPOSAL_COLUMNS
assert tables[0][2][0][1] == 'P1'
def test_the_routine_sections_are_folded_by_default():
"""`howto` is the standing grain note and the read-only line: exactly the
'information I do not care about' the rule is aimed at."""
out = R.render(_S(), _info(), [], {'built_at': _now_stamp(),
'pieces': {}})
assert _section(out, 'howto').is_open is False
assert _section(out, 'staleness').is_open is False
def test_a_fresh_index_folds_the_staleness_note_and_an_old_one_opens_it():
fresh = R.render(_S(), _info(), [], {'built_at': _now_stamp(),
'pieces': {}})
assert _section(fresh, 'staleness').is_open is False
old = R.render(_S(), _info(), [], {'built_at': '2020-01-01 00:00:00',
'pieces': {}})
assert _section(old, 'staleness').problem
assert 'day(s) old' in _section(old, 'staleness').problem
def test_offline_always_opens_the_staleness_section():
out = R.render(_S(), _info(), [], {'built_at': _now_stamp(),
'pieces': {}}, offline=True)
assert 'nothing was checked against the model' in _section(out, 'staleness').problem
def test_a_check_that_did_not_run_opens_its_section():
out = R.render(_S(), _info(master_unjudged=True), [], {'pieces': {}})
assert 'DID NOT RUN' in _section(out, 'provenance').problem
def test_a_check_that_ran_and_found_nothing_stays_folded():
out = R.render(_S(), _info(donors=3), [], {'built_at': _now_stamp(),
'pieces': {}})
prov = _section(out, 'provenance')
assert prov is not None and prov.is_open is False
def test_a_target_outside_the_declared_scope_opens_the_pool_section():
info = _info(scope={'declared': True, 'label': 'marks beginning PNL',
'line': 'x', 'declaration': [],
'target_in_scope': False,
'target_annotation': 'judged anyway'})
out = R.render(_S(), info, [], {'pieces': {}})
assert 'OUTSIDE the declared scope' in _section(out, 'pool').problem
def test_features_nobody_has_open_themselves():
class _Partial(_S):
status = match.PARTIAL
uncovered = (0,)
rows = [{'target_index': 0, 'kind': 'opening', 'donor': None,
'rect': (0.0, 1.0, 0.0, 1.0), 'strip_ft': None}]
out = R.render(_Partial(), _info(), rows, {'pieces': {}})
assert 'still need somebody' in _section(out, 'gaps').problem
def test_a_folded_section_still_says_what_is_inside_it():
"""Folded is not gone: a header with no summary tells the reader nothing
about whether to open it."""
out = R.render(_S(), _info(), [], {'built_at': _now_stamp(),
'pieces': {}})
for section in out[1:]:
assert section.title
if not section.is_open:
assert section.summary, section.key
def _now_stamp():
import time
return time.strftime('%Y-%m-%d %H:%M:%S')
# ------------------------------------------------------ demo-safe: no CJK
#
# Owner, 2026-09-01: no Chinese anywhere in a report or a UI surface, even
# when quoting him -- he is demoing this to colleagues before the weekend.
# The owner's own verbatim rulings live on in code COMMENTS (provenance),
# never in a string a render can put on screen. This is the durable guard:
# render both surfaces this module builds and fail if a CJK character ever
# reaches them again.
_CJK_RE = re.compile(u'[一-鿿]')
def test_the_rendered_report_carries_no_chinese_text_or_html():
"""Both the design-refusal path and the ordinary proposal path, through
both `foldreport` renderers -- text (the .txt log) and HTML (the panel).
Neither may ever show the owner's rulings in the language he gave them
in; the Chinese stays in the module's `#` comments only."""
refusal_out = R.render(None, _info(target='WP204', design=_design(),
rejected={'design': 412},
rejected_names={'design': ['WP101']}),
[], {'built_at': 'x', 'pieces': {}})
proposal_out = R.render(_S(), _info(), [],
{'built_at': _now_stamp(), 'pieces': {}})
for sections in (refusal_out, proposal_out):
text_out = fold.text(sections)
html_out = fold.html(sections)
assert not _CJK_RE.search(text_out), text_out
assert not _CJK_RE.search(html_out), html_out