3c014a9565
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 19s
CI / e2e_tests (pull_request) Successful in 23s
CI / typecheck (pull_request) Successful in 32s
CI / security (pull_request) Successful in 43s
CI / unit_tests (pull_request) Successful in 2m2s
CI / integration_tests (pull_request) Successful in 2m41s
CI / docker (pull_request) Successful in 49s
CI / coverage (pull_request) Successful in 5m32s
CI / benchmark-regression (pull_request) Successful in 36m2s
240 lines
8.1 KiB
Python
240 lines
8.1 KiB
Python
"""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 "
|
|
"<vocab-oo|vocab-func|vocab-proc|detail-map-chain|ttl-validate>"
|
|
)
|
|
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())
|