    1: import copy
    1: import json
    1: import unittest
    1: from pathlib import Path
       
    1: import jsonschema
       
       
    1: CONFIG_PATH = Path(__file__).resolve().parents[1] / "config.json"
    1: SCHEMA_PATH = Path(__file__).resolve().parents[1] / "config.schema.json"
    1: ROOT = CONFIG_PATH.parent
       
       
    1: def load_config():
           with CONFIG_PATH.open(encoding="utf-8") as f:
               return json.load(f)
       
       
    1: def load_schema():
           with SCHEMA_PATH.open(encoding="utf-8") as f:
               return json.load(f)
       
       
    2: class ConfigSchemaTest(unittest.TestCase):
    1:     def test_config_matches_schema(self):
               config = load_config()
               schema = load_schema()
               jsonschema.validate(config, schema)
       
    1:     def test_required_modules_present(self):
               modules = load_config()["modules"]
               self.assertEqual(set(modules.keys()), {"dev", "bmad", "requirements", "essentials", "advanced"})
       
    1:     def test_enabled_defaults_and_flags(self):
               modules = load_config()["modules"]
               self.assertTrue(modules["dev"]["enabled"])
               self.assertTrue(modules["essentials"]["enabled"])
               self.assertFalse(modules["bmad"]["enabled"])
               self.assertFalse(modules["requirements"]["enabled"])
               self.assertFalse(modules["advanced"]["enabled"])
       
    1:     def test_operations_have_expected_shape(self):
               config = load_config()
               for name, module in config["modules"].items():
                   self.assertTrue(module["operations"], f"{name} should declare at least one operation")
                   for op in module["operations"]:
                       self.assertIn("type", op)
                       if op["type"] in {"copy_dir", "copy_file"}:
                           self.assertTrue(op.get("source"), f"{name} operation missing source")
                           self.assertTrue(op.get("target"), f"{name} operation missing target")
                       elif op["type"] == "run_command":
                           self.assertTrue(op.get("command"), f"{name} run_command missing command")
                           if "env" in op:
                               self.assertIsInstance(op["env"], dict)
                       else:
                           self.fail(f"Unsupported operation type: {op['type']}")
       
    1:     def test_operation_sources_exist_on_disk(self):
               config = load_config()
               for module in config["modules"].values():
                   for op in module["operations"]:
                       if op["type"] in {"copy_dir", "copy_file"}:
                           path = (ROOT / op["source"]).expanduser()
                           self.assertTrue(path.exists(), f"Source path not found: {path}")
       
    1:     def test_schema_rejects_invalid_operation_type(self):
               config = load_config()
               invalid = copy.deepcopy(config)
               invalid["modules"]["dev"]["operations"][0]["type"] = "unknown_op"
               schema = load_schema()
               with self.assertRaises(jsonschema.exceptions.ValidationError):
                   jsonschema.validate(invalid, schema)
       
       
    1: if __name__ == "__main__":
    1:     unittest.main()
