Files
cleveragents-core/features/uko_loader_coverage_boost.feature
freemo a808c395f9
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 35s
CI / security (pull_request) Successful in 50s
CI / unit_tests (pull_request) Successful in 2m46s
CI / integration_tests (pull_request) Successful in 3m16s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 5m6s
CI / lint (push) Successful in 13s
CI / quality (push) Successful in 16s
CI / build (push) Successful in 18s
CI / security (push) Successful in 32s
CI / typecheck (push) Successful in 35s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m52s
CI / integration_tests (push) Successful in 3m8s
CI / docker (push) Successful in 39s
CI / coverage (push) Successful in 5m53s
CI / benchmark-publish (push) Successful in 16m55s
CI / benchmark-regression (pull_request) Successful in 33m0s
test(coverage): add Behave BDD tests to improve unit test coverage across 53 source modules
Add 53 new .feature files and corresponding step definition files targeting
uncovered lines identified in build/coverage.xml. Fix AmbiguousStep conflicts
in 7 pre-existing step files by disambiguating step text.

New tests cover: ACP clients/facade, actor CLI/config, application container,
ACMS service/strategies, async worker, automation profile CLI, autonomy
guardrail, bridge, change model, config CLI/service, context service,
cross-plan correction, database models, decision service, decomposition
clustering/service, discovery handler, langchain chat provider, langgraph
nodes, materializers, multi-project service, plan apply/CLI/lifecycle/model/
preflight/resume/service, PostgreSQL analyzer, project CLI/context CLI,
provider registry, reactive application/route, repositories, resolver handler,
resource registry service, resume model, retry patterns, sandbox protocol,
server CLI, skill CLI/service, skills registry, subplan execution/service,
system CLI, UKO loader, UoW, and YAML template engine.

Closes #645
2026-03-09 13:01:58 -04:00

310 lines
13 KiB
Gherkin

@phase2 @uko @coverage
Feature: UKO Loader coverage boost
Exercises uncovered code paths in uko_loader.py to improve branch/line coverage.
# ---------------------------------------------------------------------------
# _detect_layer: full-IRI path (lines 87-90)
# ---------------------------------------------------------------------------
@uko_detect_layer
Scenario: _detect_layer resolves layer from full IRI namespace
Given a full IRI "https://cleveragents.ai/ontology/uko/code#Module"
When I detect the layer for that URI
Then the detected layer should be 1
@uko_detect_layer
Scenario: _detect_layer returns 0 for unknown URI
Given a full IRI "https://example.com/unknown#Thing"
When I detect the layer for that URI
Then the detected layer should be 0
@uko_detect_layer
Scenario: _detect_layer resolves layer 2 from full IRI
Given a full IRI "https://cleveragents.ai/ontology/uko/oo#Class"
When I detect the layer for that URI
Then the detected layer should be 2
@uko_detect_layer
Scenario: _detect_layer resolves layer 3 from full IRI
Given a full IRI "https://cleveragents.ai/ontology/uko/py#Decorator"
When I detect the layer for that URI
Then the detected layer should be 3
# ---------------------------------------------------------------------------
# _extract_iri: called with and without angle-bracket IRI (lines 101-102)
# ---------------------------------------------------------------------------
@uko_extract_iri
Scenario: _extract_iri extracts IRI from angle brackets
Given a value string "<https://example.com/test>"
When I extract the IRI from that value
Then the extracted IRI should be "https://example.com/test"
@uko_extract_iri
Scenario: _extract_iri returns stripped value when no angle brackets
Given a value string "plain-value"
When I extract the IRI from that value
Then the extracted IRI should be "plain-value"
# ---------------------------------------------------------------------------
# Non-resolvable property value else branch (line 181)
# ---------------------------------------------------------------------------
@uko_property_resolve
Scenario: Property with HTTP value is kept as-is during resolution
Given a TTL string with a property whose value starts with http:
"""
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
uko: a owl:Ontology ;
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
rdfs:label "Test" ;
rdfs:comment "Test" .
uko:myProp a owl:DatatypeProperty ;
rdfs:label "myProp" ;
rdfs:domain uko:InformationUnit ;
rdfs:range <http://www.w3.org/2001/XMLSchema#string> .
uko:InformationUnit a owl:Class ;
rdfs:label "InformationUnit" .
"""
When I parse the TTL coverage string
Then the parsed ontology should contain a node labeled "myProp"
And node "myProp" property "rdfs:range" should equal "http://www.w3.org/2001/XMLSchema#string"
# ---------------------------------------------------------------------------
# Validation: prefixed parent URI with undefined prefix (lines 249-254)
# ---------------------------------------------------------------------------
@uko_validation_prefixed
Scenario: Validate detects undefined prefix in prefixed parent URI
Given a UKO ontology with a prefixed parent referencing an undefined prefix
When I run validation on the ontology
Then the validation result should mention "undefined prefix"
# ---------------------------------------------------------------------------
# Validation: prefixed parent URI referencing non-existent node (lines 256-259)
# ---------------------------------------------------------------------------
@uko_validation_prefixed
Scenario: Validate detects non-existent prefixed parent URI
Given a UKO ontology with a prefixed parent referencing a non-existent node
When I run validation on the ontology
Then the validation result should mention "non-existent parent"
# ---------------------------------------------------------------------------
# resolve_inheritance: parent not in uri_map (line 310)
# ---------------------------------------------------------------------------
@uko_inheritance_coverage
Scenario: resolve_inheritance skips unknown parent URIs gracefully
Given a UKO ontology where a node has an external parent URI
When I resolve the inheritance chain for the node with external parent
Then the chain should contain the starting node only
# ---------------------------------------------------------------------------
# _detect_cycle_dfs: already-explored node (line 361)
# ---------------------------------------------------------------------------
@uko_cycle_dfs
Scenario: DFS cycle detection handles diamond inheritance without error
Given a UKO ontology with diamond inheritance shape
When I resolve the inheritance chain for the diamond leaf
Then the chain should include each ancestor at most once
# ---------------------------------------------------------------------------
# _detect_cycle_dfs: gray node popped from stack (line 363)
# ---------------------------------------------------------------------------
@uko_cycle_dfs
Scenario: DFS detects self-referencing cycle
Given a UKO ontology where a node is its own parent
When I attempt to resolve inheritance for the self-referencing node
Then a cycle error should be raised for that node
# ---------------------------------------------------------------------------
# _detect_cycle_dfs: node is None (line 370)
# ---------------------------------------------------------------------------
@uko_cycle_dfs
Scenario: DFS cycle check handles start URI not in uri_map
Given a UKO ontology with some nodes
When I resolve the inheritance chain for a URI not in the ontology
Then the chain should be empty
# ---------------------------------------------------------------------------
# _split_blocks: dot inside bare token is not a terminator (line 443)
# ---------------------------------------------------------------------------
@uko_parser
Scenario: Parser treats dots in bare tokens as non-terminators
Given a TTL string with dots in bare subject names:
"""
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
uko: a owl:Ontology ;
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
rdfs:label "Test" ;
rdfs:comment "Test" .
uko:v0.1 a owl:Class ;
rdfs:label "Dotted" .
uko:Thing a owl:Class ;
rdfs:label "Thing" .
"""
When I parse the TTL coverage string
Then the parsed ontology should contain a node labeled "Thing"
And the parsed ontology should contain a node labeled "Dotted"
# ---------------------------------------------------------------------------
# _split_blocks: unterminated statement remainder (line 451)
# ---------------------------------------------------------------------------
@uko_parser
Scenario: Parser handles TTL block without trailing period
Given a TTL string without trailing period:
"""
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
uko: a owl:Ontology ;
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
rdfs:label "Test" ;
rdfs:comment "Test" .
uko:Leftover a owl:Class ;
rdfs:label "Leftover"
"""
When I parse the TTL coverage string
Then the parsed ontology should contain a node labeled "Leftover"
# ---------------------------------------------------------------------------
# _split_blocks: single-token statement (line 457)
# ---------------------------------------------------------------------------
@uko_parser
Scenario: Parser skips single-token statements
Given a TTL string with a stray single token:
"""
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
uko: a owl:Ontology ;
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
rdfs:label "Test" ;
rdfs:comment "Test" .
uko:Lone a owl:Class ;
rdfs:label "Lone" .
stray-token .
uko:Valid a owl:Class ;
rdfs:label "Valid" .
"""
When I parse the TTL coverage string
Then the parsed ontology should contain a node labeled "Valid"
# ---------------------------------------------------------------------------
# _parse_predicates: empty and single-part pairs (lines 469, 472)
# ---------------------------------------------------------------------------
@uko_parser
Scenario: Parser handles predicates with empty and bare keyword pairs
Given a TTL string with trailing semicolons and bare keywords:
"""
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
uko: a owl:Ontology ;
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
rdfs:label "Test" ;
rdfs:comment "Test" .
uko:Node1 a owl:Class ;
rdfs:label "Node1" ; ;
"""
When I parse the TTL coverage string
Then the parsed ontology should contain a node labeled "Node1"
# ---------------------------------------------------------------------------
# _resolve_uri: angle-bracket IRI (line 517)
# ---------------------------------------------------------------------------
@uko_resolve_uri
Scenario: _resolve_uri strips angle brackets from well-formed IRI
Given a UKO loader instance
When I resolve the prefixed URI "<https://example.com/thing>" with an empty prefix map
Then the resolved URI should be "https://example.com/thing"
# ---------------------------------------------------------------------------
# _resolve_uri: prefix not in map (line 522)
# ---------------------------------------------------------------------------
@uko_resolve_uri
Scenario: _resolve_uri returns prefixed name when prefix is unknown
Given a UKO loader instance
When I resolve the prefixed URI "unknown:Foo" with an empty prefix map
Then the resolved URI should be "unknown:Foo"
# ---------------------------------------------------------------------------
# _extract_version_string: empty version IRI (line 531)
# ---------------------------------------------------------------------------
@uko_version_extract
Scenario: _extract_version_string returns empty for empty IRI
Given a UKO loader instance
When I extract version string from an empty IRI
Then the extracted version should be ""
@uko_version_extract
Scenario: _extract_version_string returns empty for non-semver segment
Given a UKO loader instance
When I extract version string from "https://example.com/ontology/latest"
Then the extracted version should be ""
# ---------------------------------------------------------------------------
# load() via Path (line 117-118) — file-based loading
# ---------------------------------------------------------------------------
@uko_load_file
Scenario: load() reads TTL from a file Path
Given a temporary TTL file with valid content
When I load the ontology from the temporary file
Then the loaded ontology should have version "0.1.0"
# ---------------------------------------------------------------------------
# Ontology declaration via rdf:type instead of 'a' (line 136)
# ---------------------------------------------------------------------------
@uko_parser
Scenario: Parser recognises ontology declaration via rdf:type
Given a TTL string using rdf:type for ontology declaration:
"""
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
uko: rdf:type owl:Ontology ;
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
rdfs:label "Alt" ;
rdfs:comment "Alt test" .
uko:Thing a owl:Class ;
rdfs:label "Thing" .
"""
When I parse the TTL coverage string
Then the parsed ontology version label should be "Alt"
And the parsed ontology should contain a node labeled "Thing"