from __future__ import annotations import copy import unittest from claridoc.models import Brief, DocumentType, Outline, ValidationError from claridoc.structures import create_outline, reconcile_outline from tests.helpers import brief_dict, make_sources class StructureTests(unittest.TestCase): def test_every_document_type_has_unique_required_intents(self) -> None: for document_type in DocumentType: brief = Brief.from_dict(brief_dict(document_type.value)) outline = create_outline(brief, make_sources()) intents = [section.intent for section in outline.sections] self.assertEqual(len(intents), len(set(intents)), document_type.value) self.assertGreaterEqual(len(intents), 7, document_type.value) def test_readme_outline_preserves_reader_onboarding_order(self) -> None: brief = Brief.from_dict(brief_dict("readme")) outline = create_outline(brief, make_sources()) self.assertEqual( [section.intent for section in outline.sections], [ "problem_value", "principles", "workflow", "installation", "quickstart", "configuration", "verification", "limits_next", ], ) def test_reconcile_preserves_contract_order(self) -> None: brief = Brief.from_dict(brief_dict()) sources = make_sources() base = create_outline(brief, sources) candidate = Outline.from_dict(copy.deepcopy(base.to_dict())) candidate.sections[0].title = "A sharper promise" merged = reconcile_outline(base, candidate, sources) self.assertEqual(merged.sections[0].title, "A sharper promise") self.assertEqual([s.intent for s in merged.sections], [s.intent for s in base.sections]) def test_reconcile_rejects_removed_required_intent(self) -> None: brief = Brief.from_dict(brief_dict()) sources = make_sources() base = create_outline(brief, sources) data = base.to_dict() data["sections"] = data["sections"][1:] with self.assertRaises(ValidationError): reconcile_outline(base, Outline.from_dict(data), sources) def test_reconcile_rejects_unknown_source(self) -> None: brief = Brief.from_dict(brief_dict()) sources = make_sources() base = create_outline(brief, sources) data = base.to_dict() data["sections"][0]["evidence_ids"] = ["S999"] with self.assertRaises(ValidationError): reconcile_outline(base, Outline.from_dict(data), sources) if __name__ == "__main__": unittest.main()