← Files Software & AI CopilotARCHIVED FILE
tests/test_evidence_gate.py
2.71 KB · Nov 12, 2026 · 18:41 UTC
import importlib.util, json, pathlib, unittest
MODULE=pathlib.Path(__file__).resolve().parents[1]/'scripts/check_evidence.py'
spec=importlib.util.spec_from_file_location('check_evidence',MODULE)
mod=importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)
BASE={'task':'fix','changes':['src/a.py'],'checks':[{'name':'unit','status':'passed','command':'pytest -q','exit_code':0,'evidence':'3 tests passed'}],'approvals':{'required':True,'granted':True},'blockers':[]}
def clone():return json.loads(json.dumps(BASE))
class TestEvidence(unittest.TestCase):
def test_valid_report(self):self.assertTrue(mod.evaluate(clone())['ready'])
def test_non_object(self):self.assertFalse(mod.evaluate([])['ready'])
def test_missing_task(self):r=clone();r.pop('task');self.assertFalse(mod.evaluate(r)['ready'])
def test_missing_changes(self):r=clone();r['changes']=[];self.assertFalse(mod.evaluate(r)['ready'])
def test_empty_changes(self):r=clone();r['changes']=[''];self.assertFalse(mod.evaluate(r)['ready'])
def test_invalid_checks(self):r=clone();r['checks']=None;self.assertFalse(mod.evaluate(r)['ready'])
def test_pass_missing_command(self):r=clone();r['checks'][0].pop('command');self.assertFalse(mod.evaluate(r)['ready'])
def test_pass_missing_evidence(self):r=clone();r['checks'][0].pop('evidence');self.assertFalse(mod.evaluate(r)['ready'])
def test_pass_nonzero_exit(self):r=clone();r['checks'][0]['exit_code']=1;self.assertFalse(mod.evaluate(r)['ready'])
def test_not_run(self):r=clone();r['checks'][0]['status']='not_run';self.assertFalse(mod.evaluate(r)['ready'])
def test_failed(self):r=clone();r['checks'][0]['status']='failed';self.assertFalse(mod.evaluate(r)['ready'])
def test_blocked(self):r=clone();r['checks'][0]['status']='blocked';self.assertFalse(mod.evaluate(r)['ready'])
def test_invalid_status(self):r=clone();r['checks'][0]['status']='probably';self.assertFalse(mod.evaluate(r)['ready'])
def test_unapproved(self):r=clone();r['approvals']['granted']=False;self.assertFalse(mod.evaluate(r)['ready'])
def test_no_approval_required(self):r=clone();r['approvals']={'required':False,'granted':False};self.assertTrue(mod.evaluate(r)['ready'])
def test_approval_requirement_unknown(self):r=clone();r['approvals']={'required':'no'};self.assertFalse(mod.evaluate(r)['ready'])
def test_no_approval_field(self):r=clone();r['approvals']={};self.assertFalse(mod.evaluate(r)['ready'])
def test_blockers(self):r=clone();r['blockers']=['unresolved'];self.assertFalse(mod.evaluate(r)['ready'])
def test_invalid_blockers(self):r=clone();r['blockers']='unknown';self.assertFalse(mod.evaluate(r)['ready'])
def test_invalid_check_item(self):r=clone();r['checks']=['green'];self.assertFalse(mod.evaluate(r)['ready'])
if __name__=='__main__':unittest.main()
SHA-256: 36cca7df04ec1968d4dd3ad2584c7e0c28fb9225b682235f6c4d88a6eba427c3