"""Robot Framework helper for UKO Layer 2 paradigm vocabulary tests. Subcommands: vocab-oo -- verify uko-oo: vocabulary, print ``vocab-oo-ok`` vocab-func -- verify uko-func: vocabulary, print ``vocab-func-ok`` vocab-proc -- verify uko-proc: vocabulary, print ``vocab-proc-ok`` detail-map-chain -- verify L2->L1->L0 chain, print ``detail-map-chain-ok`` ttl-validate -- validate TTL with new prefixes, print ``ttl-validate-ok`` """ from __future__ import annotations import sys import traceback from collections.abc import Callable from pathlib import Path _SRC = str(Path(__file__).resolve().parents[1] / "src") if _SRC not in sys.path: sys.path.insert(0, _SRC) from cleveragents.acms.uko.detail_level_maps import ( # noqa: E402 CODE_DETAIL_LEVEL_MAP, FUNC_DETAIL_LEVEL_MAP, OO_DETAIL_LEVEL_MAP, PROC_DETAIL_LEVEL_MAP, ) from cleveragents.acms.uko.vocabularies import ( # noqa: E402 get_func_vocabulary, get_oo_vocabulary, get_proc_vocabulary, ) from cleveragents.acms.uko.vocabulary_registry import VocabularyRegistry # noqa: E402 from cleveragents.application.services.uko_loader import UKOLoader # noqa: E402 _TTL_PATH = Path(__file__).resolve().parents[1] / "docs" / "ontology" / "uko.ttl" def _cmd_vocab_oo() -> int: """Verify uko-oo: vocabulary has expected classes and properties.""" try: vocab = get_oo_vocabulary() if len(vocab.classes) != 4: print(f"vocab-oo-fail: expected 4 classes, got {len(vocab.classes)}") return 1 if len(vocab.properties) != 2: print(f"vocab-oo-fail: expected 2 properties, got {len(vocab.properties)}") return 1 expected_classes = {"Class", "Interface", "Method", "Attribute"} actual_classes = {c.label for c in vocab.classes} if actual_classes != expected_classes: print(f"vocab-oo-fail: classes mismatch: {actual_classes}") return 1 print( f"vocab-oo-ok: {len(vocab.classes)} classes, " f"{len(vocab.properties)} properties" ) return 0 except Exception as exc: # robot helper must not crash traceback.print_exc() print(f"vocab-oo-fail: {exc}") return 1 def _cmd_vocab_func() -> int: """Verify uko-func: vocabulary has expected classes.""" try: vocab = get_func_vocabulary() if len(vocab.classes) != 3: print(f"vocab-func-fail: expected 3 classes, got {len(vocab.classes)}") return 1 expected = {"PureFunction", "TypeClass", "Monad"} actual = {c.label for c in vocab.classes} if actual != expected: print(f"vocab-func-fail: classes mismatch: {actual}") return 1 print(f"vocab-func-ok: {len(vocab.classes)} classes") return 0 except Exception as exc: # robot helper must not crash traceback.print_exc() print(f"vocab-func-fail: {exc}") return 1 def _cmd_vocab_proc() -> int: """Verify uko-proc: vocabulary has expected classes.""" try: vocab = get_proc_vocabulary() if len(vocab.classes) != 5: print(f"vocab-proc-fail: expected 5 classes, got {len(vocab.classes)}") return 1 expected = { "ProceduralFunction", "GlobalVariable", "HeaderFile", "StructDefinition", "Macro", } actual = {c.label for c in vocab.classes} if actual != expected: print(f"vocab-proc-fail: classes mismatch: {actual}") return 1 print(f"vocab-proc-ok: {len(vocab.classes)} classes") return 0 except Exception as exc: # robot helper must not crash traceback.print_exc() print(f"vocab-proc-fail: {exc}") return 1 def _cmd_detail_map_chain() -> int: """Verify DetailLevelMap inheritance chain: L2 -> L1 -> L0.""" try: # Verify OO map extends CODE map oo_map = OO_DETAIL_LEVEL_MAP if oo_map.parent is None: print("detail-map-chain-fail: OO map has no parent") return 1 if oo_map.parent.domain != "uko-code:": print(f"detail-map-chain-fail: OO parent is {oo_map.parent.domain}") return 1 # Verify OO map has CLASS_HIERARCHY at depth 3 depth = oo_map.resolve("CLASS_HIERARCHY") if depth != 3: print(f"detail-map-chain-fail: CLASS_HIERARCHY at {depth}, expected 3") return 1 # Verify OO map has VISIBILITY_ANNOTATED at depth 7 depth = oo_map.resolve("VISIBILITY_ANNOTATED") if depth != 7: print(f"detail-map-chain-fail: VISIBILITY_ANNOTATED at {depth}, expected 7") return 1 # Verify FULL_SOURCE shifted to 11 depth = oo_map.resolve("FULL_SOURCE") if depth != 11: print(f"detail-map-chain-fail: FULL_SOURCE at {depth}, expected 11") return 1 # Verify func and proc maps have correct parent func_map = FUNC_DETAIL_LEVEL_MAP proc_map = PROC_DETAIL_LEVEL_MAP if func_map.parent is None or func_map.parent.domain != "uko-code:": print("detail-map-chain-fail: FUNC map parent incorrect") return 1 if proc_map.parent is None or proc_map.parent.domain != "uko-code:": print("detail-map-chain-fail: PROC map parent incorrect") return 1 # Verify CODE map has no parent code_map = CODE_DETAIL_LEVEL_MAP if code_map.parent is not None: print("detail-map-chain-fail: CODE map should have no parent") return 1 print( f"detail-map-chain-ok: OO={len(oo_map.levels)} levels, " f"FUNC={len(func_map.levels)}, PROC={len(proc_map.levels)}, " f"CODE={len(code_map.levels)}" ) return 0 except Exception as exc: # robot helper must not crash traceback.print_exc() print(f"detail-map-chain-fail: {exc}") return 1 def _cmd_ttl_validate() -> int: """Load and validate the updated TTL file with new prefixes.""" try: loader = UKOLoader() ontology = loader.load(_TTL_PATH) prefixes = {p.prefix for p in ontology.prefixes} if "uko-func" not in prefixes: print("ttl-validate-fail: uko-func prefix missing") return 1 if "uko-proc" not in prefixes: print("ttl-validate-fail: uko-proc prefix missing") return 1 # Check layer 2 node count layer2 = [n for n in ontology.nodes if n.layer == 2] if len(layer2) < 12: print(f"ttl-validate-fail: expected >= 12 L2 nodes, got {len(layer2)}") return 1 # Verify registry can be populated registry = VocabularyRegistry( vocabularies=( get_oo_vocabulary(), get_func_vocabulary(), get_proc_vocabulary(), ) ) if len(registry) != 3: print(f"ttl-validate-fail: registry has {len(registry)} vocabs") return 1 print( f"ttl-validate-ok: {len(ontology.nodes)} nodes, " f"{len(layer2)} layer-2, {len(registry)} vocabs" ) return 0 except Exception as exc: # robot helper must not crash traceback.print_exc() print(f"ttl-validate-fail: {exc}") return 1 _COMMANDS: dict[str, Callable[[], int]] = { "vocab-oo": _cmd_vocab_oo, "vocab-func": _cmd_vocab_func, "vocab-proc": _cmd_vocab_proc, "detail-map-chain": _cmd_detail_map_chain, "ttl-validate": _cmd_ttl_validate, } def main() -> int: """Entry point called by Robot Framework ``Run Process``.""" if len(sys.argv) < 2: print( "Usage: helper_uko_layer2_paradigm.py " "" ) return 1 command = sys.argv[1] handler = _COMMANDS.get(command) if handler is None: print(f"Unknown command: {command}") return 1 return handler() if __name__ == "__main__": sys.exit(main())