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
353 lines
16 KiB
Gherkin
353 lines
16 KiB
Gherkin
@phase2 @uko @ontology
|
|
Feature: UKO Ontology Loader
|
|
As a CleverAgents developer
|
|
I want to parse and validate the UKO ontology from TTL files
|
|
So that the system can reason about code artifacts and their relationships
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Prefix parsing
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_prefix
|
|
Scenario: Parse prefix line correctly
|
|
Given a TTL string:
|
|
"""
|
|
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
|
|
@prefix uko-code: <https://cleveragents.ai/ontology/uko/code#> .
|
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
|
|
uko: a owl:Ontology ;
|
|
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
|
|
rdfs:label "Test" ;
|
|
rdfs:comment "Test ontology" .
|
|
"""
|
|
When I parse the TTL string
|
|
Then the prefix "uko" should map to "https://cleveragents.ai/ontology/uko#"
|
|
And the prefix "uko-code" should map to "https://cleveragents.ai/ontology/uko/code#"
|
|
And the prefix "rdf" should map to "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layer 0 — Universal Foundation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_layer0
|
|
Scenario: Parse Layer 0 nodes from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then I should find a node with label "InformationUnit"
|
|
And I should find a node with label "Container"
|
|
And I should find a node with label "Atom"
|
|
And I should find a node with label "Annotation"
|
|
And I should find a node with label "Boundary"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layer 1 — General Software
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_layer1
|
|
Scenario: Parse Layer 1 nodes from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 1
|
|
Then I should find a node with label "Module"
|
|
And I should find a node with label "Callable"
|
|
And I should find a node with label "TypeDefinition"
|
|
And I should find a node with label "TestCase"
|
|
And I should find a node with label "Import"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layer 2 — Object-Oriented Paradigm
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_layer2
|
|
Scenario: Parse Layer 2 nodes from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 2
|
|
Then I should find a node with label "Class"
|
|
And I should find a node with label "Interface"
|
|
And I should find a node with label "Method"
|
|
And I should find a node with label "Attribute"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layer 0 properties (relationships)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_layer0_props
|
|
Scenario: Parse Layer 0 relationship properties from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then I should find a node with label "contains"
|
|
And I should find a node with label "references"
|
|
And I should find a node with label "dependsOn"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Version metadata
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_version
|
|
Scenario: Version metadata extracted correctly
|
|
Given the UKO ontology is loaded from the TTL file
|
|
Then the ontology version should be "0.1.0"
|
|
And the ontology label should be "Unified Knowledge Ontology"
|
|
And the ontology comment should be "CleverAgents knowledge representation layers 0-3"
|
|
And the version IRI should be "https://cleveragents.ai/ontology/uko/0.1.0"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Validation errors
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_validation @error_handling
|
|
Scenario: Parser skips nodes without rdf_type
|
|
Given a TTL string with a node missing rdf_type:
|
|
"""
|
|
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
|
|
|
|
uko: a owl:Ontology ;
|
|
owl:versionIRI <https://cleveragents.ai/ontology/uko/0.1.0> ;
|
|
rdfs:label "Test" ;
|
|
rdfs:comment "Test" .
|
|
|
|
uko:Broken rdfs:label "Broken" .
|
|
"""
|
|
When I parse the TTL string expecting no nodes
|
|
Then no nodes should be present in the ontology
|
|
|
|
@uko_validation @error_handling
|
|
Scenario: Validate rejects ontology with typeless node
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I inject a node without rdf_type into the ontology
|
|
And I validate the modified ontology
|
|
Then validation errors should include "missing rdf:type"
|
|
|
|
@uko_validation @error_handling
|
|
Scenario: Validate rejects undefined prefix
|
|
Given a UKO ontology with an undefined prefix node
|
|
When I validate the ontology
|
|
Then the validation errors should mention "undefined prefix"
|
|
|
|
@uko_validation
|
|
Scenario: Validate accepts valid ontology
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I validate the ontology
|
|
Then there should be no validation errors
|
|
|
|
@uko_validation @error_handling
|
|
Scenario: Validate rejects non-existent parent URI
|
|
Given a UKO ontology with a node referencing a non-existent parent
|
|
When I validate the ontology
|
|
Then the validation errors should mention "non-existent parent"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Inheritance resolution
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_inheritance
|
|
Scenario: Resolve inheritance DAG for uko-oo:Class (multi-parent)
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I resolve inheritance for "https://cleveragents.ai/ontology/uko/oo#Class"
|
|
Then the inheritance chain should have at least 5 nodes
|
|
And the first node in the chain should have label "Class"
|
|
And the last node in the chain should have label "InformationUnit"
|
|
|
|
@uko_inheritance
|
|
Scenario: Resolve inheritance chain for Container (Layer 0)
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I resolve inheritance for "https://cleveragents.ai/ontology/uko#Container"
|
|
Then the inheritance chain should have at least 2 nodes
|
|
And the first node in the chain should have label "Container"
|
|
|
|
@uko_inheritance @multi_parent
|
|
Scenario: uko-oo:Class has dual rdfs:subClassOf parents
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 2
|
|
Then the node with label "Class" should have parent "https://cleveragents.ai/ontology/uko/code#TypeDefinition"
|
|
And the node with label "Class" should have parent "https://cleveragents.ai/ontology/uko#Container"
|
|
|
|
@uko_inheritance @multi_parent
|
|
Scenario: uko-oo:Interface has dual rdfs:subClassOf parents
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 2
|
|
Then the node with label "Interface" should have parent "https://cleveragents.ai/ontology/uko/code#TypeDefinition"
|
|
And the node with label "Interface" should have parent "https://cleveragents.ai/ontology/uko#Boundary"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layer query
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_layer_query
|
|
Scenario: Get all nodes at specific layer
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then there should be at least 18 nodes
|
|
|
|
@uko_layer
|
|
Scenario Outline: Get correct node count for layer <layer>
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer <layer>
|
|
Then the node count should be <count>
|
|
|
|
Examples:
|
|
| layer | count |
|
|
| 0 | 18 |
|
|
| 1 | 67 |
|
|
| 2 | 14 |
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# rdfs:domain and rdfs:range URI resolution
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_domain_range
|
|
Scenario: rdfs:domain values are resolved to full URIs
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then the node with label "contains" should have property "rdfs:domain" resolved to a full URI
|
|
And the node with label "contains" should have property "rdfs:range" resolved to a full URI
|
|
|
|
@uko_domain_range
|
|
Scenario: rdfs:subPropertyOf values are resolved to full URIs
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 2
|
|
Then the node with label "inheritsFrom" should have property "rdfs:subPropertyOf" resolved to a full URI
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Integration: load actual file
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_integration
|
|
Scenario: Load the actual uko.ttl file successfully
|
|
Given the UKO ontology is loaded from the TTL file
|
|
Then the ontology should have prefixes defined
|
|
And the ontology should have nodes defined
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Version registry
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_version
|
|
Scenario: Version registry contains 0.1.0
|
|
Given the UKO ontology is loaded from the TTL file
|
|
Then "0.1.0" should be in the supported versions
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layer 0 content, provenance, and temporal properties
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_layer0_props
|
|
Scenario: Parse Layer 0 content properties from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then I should find a node with label "hasRendering"
|
|
And I should find a node with label "renderingDepth"
|
|
And I should find a node with label "hasFullContent"
|
|
|
|
@uko_layer0_props
|
|
Scenario: Parse Layer 0 provenance properties from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then I should find a node with label "sourceResource"
|
|
And I should find a node with label "sourcePath"
|
|
And I should find a node with label "sourceRange"
|
|
|
|
@uko_layer0_props
|
|
Scenario: Parse Layer 0 temporal properties from TTL
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then I should find a node with label "validFrom"
|
|
And I should find a node with label "validUntil"
|
|
And I should find a node with label "isCurrent"
|
|
And I should find a node with label "isRevisionOf"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# rdfs:domain / rdfs:range correctness for content, provenance, temporal props
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_domain_range
|
|
Scenario: Content properties have correct rdfs:domain and rdfs:range
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then the node with label "hasRendering" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "hasRendering" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#string"
|
|
And the node with label "renderingDepth" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "renderingDepth" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
|
|
And the node with label "hasFullContent" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "hasFullContent" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#string"
|
|
|
|
@uko_domain_range
|
|
Scenario: Provenance properties have correct rdfs:domain and rdfs:range
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then the node with label "sourceResource" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "sourceResource" should not have property "rdfs:range"
|
|
And the node with label "sourcePath" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "sourcePath" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#string"
|
|
And the node with label "sourceRange" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "sourceRange" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#string"
|
|
|
|
@uko_domain_range
|
|
Scenario: Temporal properties have correct rdfs:domain and rdfs:range
|
|
Given the UKO ontology is loaded from the TTL file
|
|
When I get nodes at layer 0
|
|
Then the node with label "validFrom" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "validFrom" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#dateTime"
|
|
And the node with label "validUntil" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "validUntil" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#dateTime"
|
|
And the node with label "isCurrent" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "isCurrent" should have property "rdfs:range" equal to "http://www.w3.org/2001/XMLSchema#boolean"
|
|
And the node with label "isRevisionOf" should have property "rdfs:domain" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
And the node with label "isRevisionOf" should have property "rdfs:range" equal to "https://cleveragents.ai/ontology/uko#InformationUnit"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Unsupported version rejection
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_validation @error_handling
|
|
Scenario: Loader rejects unsupported ontology version
|
|
Given a TTL string:
|
|
"""
|
|
@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/99.0.0> ;
|
|
rdfs:label "Test" ;
|
|
rdfs:comment "Test" .
|
|
"""
|
|
When I attempt to parse the TTL string expecting a validation error
|
|
Then a validation error should mention "Unsupported version"
|
|
|
|
@uko_validation @error_handling
|
|
Scenario: Loader rejects version IRI with non-semver last segment
|
|
Given a TTL string:
|
|
"""
|
|
@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> ;
|
|
rdfs:label "Test" ;
|
|
rdfs:comment "Test" .
|
|
"""
|
|
When I attempt to parse the TTL string expecting a validation error
|
|
Then a validation error should mention "Unsupported version"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Duplicate-key handling in properties tuple
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_properties
|
|
Scenario: Duplicate keys in properties tuple preserve last value when cast to dict
|
|
Given a UKO node with duplicate property keys
|
|
When I convert the node properties to a dict
|
|
Then the dict should contain only the last value for the duplicated key
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Cycle detection
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@uko_inheritance @error_handling
|
|
Scenario: Cycle detection in inheritance
|
|
Given a UKO ontology with a cycle in inheritance
|
|
When I attempt to resolve inheritance for the cyclic node
|
|
Then a cycle detection error should be raised
|