Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
78 lines
3.8 KiB
Python
78 lines
3.8 KiB
Python
"""Recipe preparation tests; generated contracts are never completion receipts."""
|
|
import json
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
from wbv2_local_planner import LocalPlanner
|
|
|
|
|
|
class LocalPlannerTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.temporary = tempfile.TemporaryDirectory()
|
|
self.addCleanup(self.temporary.cleanup)
|
|
self.root = Path(self.temporary.name)
|
|
self.directory = self.root / "tests/golden/WBV2/autopilot"
|
|
self.planner = LocalPlanner(self.root, self.directory)
|
|
self.context = {"task": "WBV2-P42-001", "parentSha256": "a" * 64}
|
|
self.provider = "SERVER-OPERATOR-HTTP-PROVIDER"
|
|
self.job = {"id": "SERVER-OPERATOR-SCHEMA-PALETTE", "ownedPaths": ["app.tsx"], "module": "RUNTIME"}
|
|
|
|
def prepare_base(self):
|
|
source = self.directory / "local-plans" / (self.provider + ".json")
|
|
source.parent.mkdir(parents=True)
|
|
contract = {**self.context, "job": self.provider, "result": {"checks": [{"id": "chromium-main", "argv": ["node", "test.js"], "kinds": ["chromium"]}], "cases": [{"id": "positive", "checkId": "chromium-main", "unitIds": ["operator:TEST"]}], "dependencies": ["test.js"], "changedFiles": ["test.js"]}}
|
|
source.write_text(json.dumps(contract))
|
|
target = self.root / "web/tests/e2e/server-operator-schema-palette.spec.ts"
|
|
target.parent.mkdir(parents=True)
|
|
target.write_text("// synthetic test-entrypoint fixture\n")
|
|
return source, target
|
|
|
|
def test_missing_dependency_is_not_dispatched(self):
|
|
self.prepare_base()
|
|
result = self.planner.refresh(self.context, [self.job], set())
|
|
self.assertEqual(0, result["readyCount"])
|
|
self.assertEqual([], result["created"])
|
|
|
|
def test_missing_test_is_a_specific_preparation_task(self):
|
|
_, target = self.prepare_base()
|
|
target.unlink()
|
|
self.planner.refresh(self.context, [self.job], {self.provider})
|
|
report = json.loads((self.directory / "local-task-assignments.json").read_text())
|
|
self.assertEqual("needs_test_entrypoint", report["assignments"][0]["state"])
|
|
|
|
def test_complete_recipe_is_prepared_but_not_marked_verified(self):
|
|
self.prepare_base()
|
|
result = self.planner.refresh(self.context, [self.job], {self.provider})
|
|
self.assertEqual([self.job["id"]], result["created"])
|
|
recipe = json.loads((self.directory / "local-plans" / (self.job["id"] + ".json")).read_text())
|
|
self.assertEqual("pending local behavior verification", recipe["acceptance"])
|
|
self.assertEqual("chromium-schema-palette", recipe["result"]["cases"][0]["checkId"])
|
|
self.assertIn("tests/e2e/server-operator-schema-palette.spec.ts", recipe["result"]["checks"][0]["argv"])
|
|
|
|
def test_stable_assignments_do_not_rewrite_every_poll(self):
|
|
self.prepare_base()
|
|
self.planner.refresh(self.context, [self.job], {self.provider})
|
|
report = self.directory / "local-task-assignments.json"
|
|
before = report.stat().st_mtime_ns
|
|
result = self.planner.refresh(self.context, [self.job], {self.provider})
|
|
self.assertFalse(result["changed"])
|
|
self.assertEqual(before, report.stat().st_mtime_ns)
|
|
|
|
def test_parent_mismatch_fails_without_preparing_a_recipe(self):
|
|
source, _ = self.prepare_base()
|
|
contract = json.loads(source.read_text())
|
|
contract["parentSha256"] = "b" * 64
|
|
source.write_text(json.dumps(contract))
|
|
with self.assertRaisesRegex(ValueError, "parent mismatch"):
|
|
self.planner.refresh(self.context, [self.job], {self.provider})
|
|
|
|
def test_unknown_modules_are_not_falsely_accepted(self):
|
|
result = self.planner.refresh(self.context, [{"id": "OTHER", "ownedPaths": []}], set())
|
|
self.assertEqual(1, result["blockedCount"])
|
|
self.assertEqual(0, result["readyCount"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|