1+ from collections import Counter
12from pathlib import Path
23
34import pytest
@@ -24,13 +25,26 @@ def test_cases_loaded():
2425MIN_INDIVIDUAL_SCORE = 10.0
2526
2627
28+ def _count_fragments_per_file (context : dict ) -> dict [str , int ]:
29+ counts : Counter [str ] = Counter ()
30+ for frag in context .get ("fragments" , []):
31+ path = frag .get ("path" , "" )
32+ if path :
33+ counts [path ] += 1
34+ return dict (counts )
35+
36+
2737@pytest .mark .parametrize ("case" , ALL_CASES , ids = lambda c : c .id )
2838def test_diff_yaml (yaml_test_runner : YamlTestRunner , case : YamlTestCase , record_property , request ):
2939 if case .xfail :
3040 request .node .add_marker (pytest .mark .xfail (reason = case .xfail , strict = True ))
3141 context = yaml_test_runner .run_test_case (case )
3242 breakdown = yaml_test_runner .score_test_case (context , case )
3343
44+ fragments = context .get ("fragments" , [])
45+ frag_count = len (fragments )
46+ unique_files = len ({f .get ("path" , "" ) for f in fragments if f .get ("path" )})
47+
3448 record_property ("score" , breakdown .score )
3549 record_property ("recall" , round (breakdown .recall * 100 , 1 ))
3650 record_property ("noise_rate" , round (breakdown .noise_rate * 100 , 1 ))
@@ -39,12 +53,41 @@ def test_diff_yaml(yaml_test_runner: YamlTestRunner, case: YamlTestCase, record_
3953 record_property ("enrichment" , round (breakdown .enrichment * 100 ))
4054 record_property ("diff_tokens" , breakdown .diff_tokens )
4155 record_property ("context_tokens" , breakdown .context_tokens )
56+ record_property ("fragment_count" , frag_count )
57+ record_property ("unique_files" , unique_files )
4258
4359 effective_min = case .min_score if case .min_score is not None else MIN_INDIVIDUAL_SCORE
4460 assert breakdown .score >= effective_min , f"[{ case .id } ] score { breakdown .score :.1f} % below minimum { effective_min } %"
4561 if case .must_include_files :
4662 assert breakdown .diff_covered , f"[{ case .id } ] diff lines not covered by context"
4763
64+ if case .max_fragments_per_file is not None :
65+ per_file = _count_fragments_per_file (context )
66+ for path , count in per_file .items ():
67+ assert (
68+ count <= case .max_fragments_per_file
69+ ), f"[{ case .id } ] { path } has { count } fragments, exceeds max_fragments_per_file={ case .max_fragments_per_file } "
70+
71+ if case .max_enrichment is not None :
72+ assert (
73+ breakdown .enrichment <= case .max_enrichment
74+ ), f"[{ case .id } ] enrichment { breakdown .enrichment :.1f} x exceeds max_enrichment={ case .max_enrichment } "
75+
76+ if case .min_recall is not None :
77+ assert (
78+ breakdown .recall >= case .min_recall
79+ ), f"[{ case .id } ] recall { breakdown .recall :.1%} below min_recall={ case .min_recall :.0%} "
80+
81+ if case .max_noise_rate is not None :
82+ assert (
83+ breakdown .noise_rate <= case .max_noise_rate
84+ ), f"[{ case .id } ] noise_rate { breakdown .noise_rate :.1%} exceeds max_noise_rate={ case .max_noise_rate :.0%} "
85+
86+ if case .max_context_tokens is not None :
87+ assert (
88+ breakdown .context_tokens <= case .max_context_tokens
89+ ), f"[{ case .id } ] { breakdown .context_tokens } context tokens exceeds max_context_tokens={ case .max_context_tokens } "
90+
4891
4992@pytest .mark .parametrize (
5093 "case" ,
0 commit comments