Tests / Test (push) Skipped
Tests / OCR (tesseract fixture) (push) Skipped
Tests / Release (semver) (push) Skipped
temporal_freshness then authority_pairing; unresolved keeps (not confirmed). bin/facts/audit contradict. Gitea #29.
105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
import os
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
from contradict import ( # noqa: E402
|
|
RULE_AUTHORITY,
|
|
RULE_SINGLE,
|
|
RULE_TEMPORAL,
|
|
RULE_TWO_SOURCE,
|
|
RULE_UNRESOLVED,
|
|
adjudicate,
|
|
check_fact_row,
|
|
parse_source_field,
|
|
)
|
|
|
|
|
|
def src(i, kind, stale=False):
|
|
return {"id": i, "kind": kind, "stale": stale}
|
|
|
|
|
|
class TestContradict(unittest.TestCase):
|
|
def test_two_vs_two_stays_hypothesis(self):
|
|
r = adjudicate({
|
|
"text": "svc listens on 443",
|
|
"yes": [src("docker-ps", "runtime"), src("compose", "config")],
|
|
"no": [src("docker-old", "runtime"), src("compose-old", "config")],
|
|
})
|
|
self.assertFalse(r["confirmed"])
|
|
self.assertEqual(r["rule"], RULE_UNRESOLVED)
|
|
self.assertEqual(r["winner"], "")
|
|
|
|
def test_temporal_freshness(self):
|
|
r = adjudicate({
|
|
"text": "svc listens on 443",
|
|
"yes": [src("docker-ps", "runtime"), src("compose", "config")],
|
|
"no": [src("old-readme", "narrative", True), src("old-wiki", "narrative", True)],
|
|
})
|
|
self.assertTrue(r["confirmed"])
|
|
self.assertEqual(r["rule"], RULE_TEMPORAL)
|
|
self.assertEqual(r["winner"], "yes")
|
|
|
|
def test_authority_pairing(self):
|
|
r = adjudicate({
|
|
"text": "svc listens on 443",
|
|
"yes": [src("docker-ps", "runtime"), src("compose", "config")],
|
|
"no": [src("readme", "narrative"), src("wiki", "narrative")],
|
|
})
|
|
self.assertTrue(r["confirmed"])
|
|
self.assertEqual(r["rule"], RULE_AUTHORITY)
|
|
self.assertEqual(r["winner"], "yes")
|
|
|
|
def test_two_source_and_single(self):
|
|
two = adjudicate({
|
|
"text": "arc-1 runs Matrix",
|
|
"yes": [src("compose", "config"), src("docker-ps", "runtime")],
|
|
})
|
|
self.assertTrue(two["confirmed"])
|
|
self.assertEqual(two["rule"], RULE_TWO_SOURCE)
|
|
one = adjudicate({"text": "maybe", "yes": [src("readme", "narrative")]})
|
|
self.assertFalse(one["confirmed"])
|
|
self.assertEqual(one["rule"], RULE_SINGLE)
|
|
|
|
def test_parse_source_field(self):
|
|
yes, no = parse_source_field("docker ps x compose.yml vs old.md x wiki.md")
|
|
self.assertIn(" x ", yes)
|
|
self.assertIn(" x ", no)
|
|
|
|
def test_check_fact_row_allows_hypothesis_vs(self):
|
|
p = check_fact_row(
|
|
"L1", "a.md x b.md vs c.md x d.md", "var/", "audit", "hypothesis",
|
|
)
|
|
self.assertEqual(p, [])
|
|
p = check_fact_row("L2", "a.md x b.md", "var/", "audit", "confirmed")
|
|
self.assertEqual(p, [])
|
|
p = check_fact_row("L3", "a.md x b.md vs c.md x d.md", "var/", "audit", "confirmed")
|
|
self.assertTrue(any("vs-contradiction" in x for x in p))
|
|
p = check_fact_row("L4", "only-one.md", "var/", "audit", "hypothesis")
|
|
self.assertTrue(any("a x b vs" in x for x in p))
|
|
|
|
def test_audit_contradict_cli_unresolved(self):
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
root = Path(__file__).resolve().parents[2]
|
|
payload = json.dumps({
|
|
"text": "svc 443",
|
|
"yes": [src("a", "runtime"), src("b", "config")],
|
|
"no": [src("c", "runtime"), src("d", "config")],
|
|
})
|
|
proc = subprocess.run(
|
|
[sys.executable, str(root / "bin" / "facts" / "audit"), "contradict", "--json"],
|
|
input=payload, capture_output=True, text=True, check=False,
|
|
)
|
|
self.assertEqual(proc.returncode, 0, proc.stderr)
|
|
out = json.loads(proc.stdout)
|
|
self.assertTrue(out["ok"])
|
|
self.assertEqual(out["contradictions"][0]["rule"], RULE_UNRESOLVED)
|
|
self.assertFalse(out["contradictions"][0]["confirmed"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|