@@ -325,7 +325,8 @@ def test_ambiguities_is_a_legal_field_name() -> None:
325325
326326def _run_main (tmp_path : Path , monkeypatch : pytest .MonkeyPatch , ledger_body : str ,
327327 baseline_facade : dict , baseline : str = "1.4.0" ,
328- baseline_v2 : dict | None = None ) -> tuple [int , str ]:
328+ baseline_v2 : dict | None = None ,
329+ floor : int | None = 1 ) -> tuple [int , str ]:
329330 """Drive main() end to end with a faked baseline worker.
330331
331332 No uv, no network. The helper exists because every unit test above
@@ -351,6 +352,11 @@ def _fake(v: str, w: bool, n: list[str]) -> tuple[dict, list[dict]]:
351352 return ({"__version__" : v ,
352353 "__file__" : "/wheel/nameparser/__init__.py" }, [row ])
353354
355+ # The fixture corpus needs a floor like any other. `floor=None`
356+ # leaves it unregistered, for the test that pins what happens when
357+ # a corpus arrives without one.
358+ if floor is not None :
359+ monkeypatch .setitem (compare ._CORPUS_FLOORS , corpus .name , floor )
354360 monkeypatch .setattr (compare , "HERE" , tmp_path )
355361 monkeypatch .setattr (compare , "_run_worker" , _fake )
356362 monkeypatch .setattr (sys , "argv" , ["compare.py" , "--baseline" , baseline ,
@@ -636,3 +642,55 @@ def test_main_asks_for_the_facade_alone_below_2_0(
636642 _run_main (tmp_path , monkeypatch ,
637643 '[[change]]\n issue = "x"\n name_regex = "ZZZ"\n ' , _SAME_FACADE )
638644 assert _WORKER_CALL ["want_v2" ] is False
645+
646+
647+ def test_every_shipped_corpus_has_a_floor_and_clears_it () -> None :
648+ """Two bindings, so neither half can rot alone: every corpus file
649+ on disk must have a floor, and must be at or above it.
650+
651+ The floor exists because the empty-file guard only catches a corpus
652+ that lost EVERY name. One truncated to a handful passes that guard,
653+ and the run exits 0 having compared a fraction of what its summary
654+ line reports -- the harness's own stated nightmare, reached by a
655+ file that is merely short rather than absent.
656+ """
657+ import json
658+ corpora = sorted (_TOOLS .glob ("corpus*.jsonl" ))
659+ assert corpora , "no corpora found; this test would pass vacuously"
660+ for path in corpora :
661+ names = [json .loads (line ) for line
662+ in path .read_text (encoding = "utf-8" ).splitlines ()
663+ if line .strip ()]
664+ floor = compare ._CORPUS_FLOORS .get (path .name )
665+ assert floor is not None , (
666+ f"{ path .name } has no _CORPUS_FLOORS entry; add one a little "
667+ f"under its { len (names )} names" )
668+ assert len (names ) >= floor , (
669+ f"{ path .name } holds { len (names )} , below its floor { floor } " )
670+
671+
672+ def test_a_floor_names_a_corpus_that_exists () -> None :
673+ """The other direction: a floor for a file nobody ships is a guard
674+ that can never fire, and reads as coverage that is not there."""
675+ on_disk = {p .name for p in _TOOLS .glob ("corpus*.jsonl" )}
676+ assert set (compare ._CORPUS_FLOORS ) <= on_disk
677+
678+
679+ def test_main_aborts_on_a_truncated_corpus (
680+ tmp_path : Path , monkeypatch : pytest .MonkeyPatch ) -> None :
681+ """A corpus below its floor must stop the run, not shrink it."""
682+ with pytest .raises (SystemExit , match = "below its floor" ):
683+ _run_main (tmp_path , monkeypatch ,
684+ '[[change]]\n issue = "x"\n name_regex = "ZZZ"\n ' ,
685+ _SAME_FACADE , floor = 50 )
686+
687+
688+ def test_main_aborts_on_a_corpus_with_no_floor (
689+ tmp_path : Path , monkeypatch : pytest .MonkeyPatch ) -> None :
690+ """Adding a corpus without a floor must be a decision, not a
691+ silent default -- the same force-a-decision shape the Script
692+ tables use."""
693+ with pytest .raises (SystemExit , match = "no entry in _CORPUS_FLOORS" ):
694+ _run_main (tmp_path , monkeypatch ,
695+ '[[change]]\n issue = "x"\n name_regex = "ZZZ"\n ' ,
696+ _SAME_FACADE , floor = None )
0 commit comments