Files
ai-exchange/tests/unit/test_training_case_generator_proto.py
T

85 lines
3.6 KiB
Python

import contextlib
import io
import json
import tempfile
import unittest
from pathlib import Path
from scripts import run_training_case_generator
from src.services.training import generate_public_training_case_drafts
FIXTURE = Path("tests/fixtures/training_case_generator_seed_v1.json")
class TrainingCaseGeneratorProtoTests(unittest.TestCase):
def test_generate_public_training_case_drafts_returns_public_case_package(self) -> None:
payload = json.loads(FIXTURE.read_text(encoding="utf-8"))
generated = generate_public_training_case_drafts(payload)
self.assertEqual(generated["version"], 1)
self.assertEqual(generated["metadata"]["generated"], 2)
self.assertTrue(generated["metadata"]["read_only"])
self.assertEqual([item["scenario"]["source_event_type"] for item in generated["items"]], ["fvg_zone", "sweep_event"])
first = generated["items"][0]
self.assertEqual(
set(first),
{"external_id", "title", "scenario", "skill_tags", "difficulty", "answer", "rubric", "tasks", "status", "metadata", "quality"},
)
self.assertEqual(first["answer"], {})
self.assertIn("quality", first)
self.assertIn(first["quality"]["rank"], {"high", "medium", "low"})
serialized = json.dumps(generated, sort_keys=True)
self.assertNotIn("answer_key", serialized)
def test_generator_keeps_output_public_and_deterministic(self) -> None:
payload = json.loads(FIXTURE.read_text(encoding="utf-8"))
first = generate_public_training_case_drafts(payload)
second = generate_public_training_case_drafts(payload)
self.assertEqual(first, second)
self.assertNotIn("answer_key", json.dumps(first, sort_keys=True))
self.assertEqual(first["items"][0]["quality"]["signals"][0], first["items"][0]["quality"]["signals"][0])
def test_script_writes_public_draft_package_and_reports_summary(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
output_path = Path(tmpdir) / "generated_training_case_drafts.json"
stdout = io.StringIO()
with contextlib.redirect_stdout(stdout):
exit_code = run_training_case_generator.main(["--input", str(FIXTURE), "--output", str(output_path)])
summary = json.loads(stdout.getvalue())
generated = json.loads(output_path.read_text(encoding="utf-8"))
self.assertEqual(exit_code, 0)
self.assertTrue(summary["passed"])
self.assertEqual(summary["generated"], 2)
self.assertEqual(summary["event_types"], ["fvg_zone", "sweep_event"])
self.assertEqual(generated["metadata"]["generator_mode"], "prototype_public_draft")
self.assertEqual(len(generated["items"]), 2)
self.assertNotIn("answer_key", json.dumps(generated, sort_keys=True))
def test_script_reports_public_error_for_invalid_seed_package(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
input_path = Path(tmpdir) / "invalid_seed.json"
input_path.write_text(json.dumps({"version": 1, "items": [{"source_event_type": "unknown"}]}), encoding="utf-8")
stdout = io.StringIO()
with contextlib.redirect_stdout(stdout):
exit_code = run_training_case_generator.main(["--input", str(input_path)])
payload = json.loads(stdout.getvalue())
self.assertEqual(exit_code, 2)
self.assertFalse(payload["passed"])
self.assertEqual(payload["error"], "invalid_json_field:source_event_type")
if __name__ == "__main__":
unittest.main()