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
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
310 lines
13 KiB
Gherkin
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"
|