hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

test_traceability.mojo (6296B)


      1 import std.os
      2 from std.collections import List
      3 from std.os.path import dirname, isfile
      4 from std.pathlib import Path, _dir_of_current_file
      5 from safe_tempdir import SafeTempDir
      6 from std.testing import TestSuite, assert_equal, assert_true
      7 from json import loads
      8 
      9 from fixture_validator import (
     10     FixtureValidationIssue,
     11     validate_requirement_traceability,
     12     validate_step_states,
     13 )
     14 
     15 
     16 def _write(path: Path, text: String) raises:
     17     _ = std.os.makedirs(dirname(path.__fspath__()), exist_ok=True)
     18     path.write_text(text)
     19     assert_true(
     20         isfile(path.__fspath__()),
     21         "expected a regular file at " + path.__fspath__(),
     22     )
     23 
     24 
     25 def _make_corpus(base: Path, mutation: String) raises:
     26     var manifest = '{"cases":[{"case_id":"T001"}]}'
     27     var steps = '{"steps":[{"id":"S001","dependencies":[]}]}'
     28     var registry = (
     29         '{"requirements":[{"id":"HYF-TEST-001",'
     30         '"verification_method":"fixture-schema and traceability checks",'
     31         '"implementation_steps":["S001"],"fixture_ids":["T001"]}]}'
     32     )
     33     if mutation == "duplicate_requirement":
     34         registry = registry.replace(
     35             "]}]}",
     36             (
     37                 ']},{"id":"HYF-TEST-001","verification_method":"x",'
     38                 '"implementation_steps":["S001"],"fixture_ids":["T001"]}]}'
     39             ),
     40         )
     41     elif mutation == "unknown_step":
     42         registry = registry.replace('["S001"]', '["S999"]')
     43     elif mutation == "dangling_fixture":
     44         registry = registry.replace('["T001"]', '["MISSING"]')
     45     elif mutation == "uncovered_requirement":
     46         registry = registry.replace(
     47             '"implementation_steps":["S001"]', '"implementation_steps":[]'
     48         )
     49     elif mutation == "missing_verification_method":
     50         registry = registry.replace(
     51             '"fixture-schema and traceability checks"', '""'
     52         )
     53     elif mutation == "dangling_dependency":
     54         steps = '{"steps":[{"id":"S001","dependencies":["S404"]}]}'
     55     elif mutation == "duplicate_step":
     56         steps = (
     57             '{"steps":[{"id":"S001","dependencies":[]},'
     58             '{"id":"S001","dependencies":[]}]}'
     59         )
     60     _write(base / "manifest.json", manifest)
     61     _write(base / "steps.json", steps)
     62     _write(base / "registry.json", registry)
     63 
     64 
     65 def _validate(base: Path) raises -> List[FixtureValidationIssue]:
     66     return validate_requirement_traceability(
     67         (base / "registry.json").__fspath__(),
     68         (base / "manifest.json").__fspath__(),
     69         (base / "steps.json").__fspath__(),
     70     )
     71 
     72 
     73 def test_requirement_traceability_accepts_registry_and_rejects_dangling() raises:
     74     var root = _dir_of_current_file()
     75     assert_equal(
     76         len(
     77             validate_requirement_traceability(
     78                 (
     79                     root / "requirements" / "hyf_v1_jev.requirements.json"
     80                 ).__fspath__(),
     81                 (
     82                     root / "fixtures" / "hyf_v1_jev" / "manifest.json"
     83                 ).__fspath__(),
     84                 (root / "requirements" / "hyf_v1_jev.steps.json").__fspath__(),
     85             )
     86         ),
     87         0,
     88     )
     89 
     90     var mutations = List[String]()
     91     mutations.append("duplicate_requirement")
     92     mutations.append("unknown_step")
     93     mutations.append("dangling_fixture")
     94     mutations.append("uncovered_requirement")
     95     mutations.append("missing_verification_method")
     96     mutations.append("dangling_dependency")
     97     mutations.append("duplicate_step")
     98     for mutation in mutations:
     99         with SafeTempDir() as temp_dir:
    100             var base = Path(temp_dir)
    101             _make_corpus(base, mutation)
    102             assert_true(
    103                 len(_validate(base)) > 0,
    104                 "traceability accepted corruption: " + mutation,
    105             )
    106 
    107 
    108 def test_step_state_contract_is_valid_and_rejects_corruption() raises:
    109     var path = (
    110         _dir_of_current_file() / "requirements" / "hyf_v1_jev.step_states.json"
    111     )
    112     assert_equal(len(validate_step_states(path.__fspath__())), 0)
    113 
    114     with SafeTempDir() as temp_dir:
    115         var base = Path(temp_dir)
    116         _write(
    117             base / "states.json",
    118             (
    119                 '{"states":["PASSED","PASSED","NOT_RUN","NOT_APPLICABLE"],'
    120                 '"passed_requires_executed_evidence":true,"rules":["x"]}'
    121             ),
    122         )
    123         assert_true(
    124             len(validate_step_states((base / "states.json").__fspath__())) > 0
    125         )
    126     with SafeTempDir() as temp_dir:
    127         var base = Path(temp_dir)
    128         _write(
    129             base / "states.json",
    130             (
    131                 '{"states":["PASSED","NOT_RUN","NOT_APPLICABLE"],'
    132                 '"passed_requires_executed_evidence":false,"rules":["x"]}'
    133             ),
    134         )
    135         assert_true(
    136             len(validate_step_states((base / "states.json").__fspath__())) > 0
    137         )
    138 
    139 
    140 def main() raises:
    141     TestSuite.discover_tests[__functions_in_module()]().run()
    142 
    143 
    144 from fixture_validator import validate_requirement_traceability as _vrt
    145 
    146 
    147 def test_requirement_and_fixture_closure_audit() raises:
    148     var root = _dir_of_current_file()
    149     var registry = loads(
    150         (root / "requirements" / "hyf_v1_jev.requirements.json").read_text()
    151     )
    152     var steps = loads(
    153         (root / "requirements" / "hyf_v1_jev.steps.json").read_text()
    154     )
    155     var step_ids = List[String]()
    156     for step in steps["steps"].array_items():
    157         step_ids.append(step["id"].string_value())
    158     assert_equal(len(step_ids), 138)
    159     var covered = 0
    160     for requirement in registry["requirements"].array_items():
    161         assert_true(len(requirement["implementation_steps"].array_items()) > 0)
    162         covered += 1
    163     assert_equal(covered, 85)
    164 
    165     var manifest = loads(
    166         (root / "fixtures" / "hyf_v1_jev" / "manifest.json").read_text()
    167     )
    168     var planned = 0
    169     for entry in manifest["cases"].array_items():
    170         var doc = loads(
    171             (
    172                 root / "fixtures" / "hyf_v1_jev" / entry["path"].string_value()
    173             ).read_text()
    174         )
    175         var found_step = False
    176         for known in step_ids:
    177             if known == entry["required_from_step"].string_value():
    178                 found_step = True
    179         assert_true(found_step)
    180         assert_equal(doc["implementation_status"].string_value(), "planned")
    181         planned += 1
    182     assert_equal(planned, 116)