Files
cleveragents-core/features/domain_analyzers.feature
T
hamza.khyari 13618fb8d5
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 33s
CI / typecheck (pull_request) Successful in 47s
CI / unit_tests (pull_request) Successful in 2m35s
CI / integration_tests (pull_request) Successful in 3m13s
CI / docker (pull_request) Successful in 39s
CI / coverage (pull_request) Successful in 4m26s
CI / benchmark-regression (pull_request) Has been cancelled
fix(acms): address PR #611 review findings F1-F7
- F1/F2 [P1]: Split postgresql_analyzer.py (695→310 lines) by
  extracting regex patterns, URI builders, and parsing functions
  into _postgresql_helpers.py (440 lines).  Split
  domain_analyzers.feature (605→217 lines) into separate
  postgresql_analyzer.feature (201) and
  docker_compose_analyzer.feature (199).

- F3 [P1]: Fix _extract_body and _split_entries to track
  single-quoted SQL string literals so parentheses inside
  DEFAULT/CHECK values (e.g. 'func(x)') do not corrupt depth
  counting.  Added regression scenarios.

- F4 [P2]: Remove prohibited `# type: ignore[arg-type]` by
  adding a static protocol assertion for _DuplicatePyAnalyzer.

- F5 [P2]: Add 1 MiB size guard before yaml.safe_load in
  DockerComposeAnalyzer to mitigate billion-laughs alias
  expansion attacks.

- F6 [P2]: Fix quoted-keyword column names (e.g. "primary")
  being silently dropped by checking raw_first.startswith('"')
  before keyword filtering.  Added regression scenario.

- F7 [P2]: Out-of-scope file changes resolved by rebase onto
  master (changes already merged via other PRs).

All nox gates pass: lint (0 errors), typecheck (0 errors),
security_scan, behave (57 scenarios, 211 steps, 0 failures).
2026-03-06 20:07:03 +00:00

218 lines
8.1 KiB
Gherkin

@phase2 @acms @analyzer
Feature: Domain-Specific Analyzers
As a CleverAgents developer
I want domain-specific analyzers that produce UKO triples from resources
So that the ACMS can index code, documents, SQL, and infrastructure into the UKO knowledge graph
# ---------------------------------------------------------------------------
# AnalyzerProtocol conformance
# ---------------------------------------------------------------------------
@analyzer_protocol
Scenario: PythonAnalyzer satisfies AnalyzerProtocol
Given a PythonAnalyzer analyzer
Then the analyzer should satisfy the AnalyzerProtocol
And the current analyzer domain should be "python"
@analyzer_protocol
Scenario: MarkdownAnalyzer satisfies AnalyzerProtocol
Given a MarkdownAnalyzer analyzer
Then the analyzer should satisfy the AnalyzerProtocol
And the current analyzer domain should be "markdown"
@analyzer_protocol
Scenario: PostgreSQLAnalyzer satisfies AnalyzerProtocol
Given a PostgreSQLAnalyzer analyzer
Then the analyzer should satisfy the AnalyzerProtocol
And the current analyzer domain should be "postgresql"
@analyzer_protocol
Scenario: DockerComposeAnalyzer satisfies AnalyzerProtocol
Given a DockerComposeAnalyzer analyzer
Then the analyzer should satisfy the AnalyzerProtocol
And the current analyzer domain should be "docker-compose"
# ---------------------------------------------------------------------------
# AnalyzerRegistry
# ---------------------------------------------------------------------------
@analyzer_registry
Scenario: Register all 4 analyzers and verify count
Given a fresh analyzer registry
When I register all 4 domain analyzers
Then the registry should contain 4 analyzers
@analyzer_registry
Scenario: Lookup by extension returns correct analyzer for .py
Given a fresh analyzer registry with all domain analyzers registered
When I look up extension ".py" in the registry
Then the current analyzer domain should be "python"
@analyzer_registry
Scenario: Lookup by extension returns correct analyzer for .sql
Given a fresh analyzer registry with all domain analyzers registered
When I look up extension ".sql" in the registry
Then the current analyzer domain should be "postgresql"
@analyzer_registry
Scenario: Lookup for unknown extension returns None
Given a fresh analyzer registry with all domain analyzers registered
When I look up extension ".rs" in the registry
Then the extension lookup result should be None
@analyzer_registry
Scenario: Register duplicate extension first wins
Given a fresh analyzer registry
When I register a PythonAnalyzer
And I register a duplicate analyzer that also claims ".py"
And I look up extension ".py" in the registry
Then the current analyzer domain should be "python"
@analyzer_registry
Scenario: list_extensions returns all registered extensions
Given a fresh analyzer registry with all domain analyzers registered
Then the registry extensions should include ".py"
And the registry extensions should include ".pyi"
And the registry extensions should include ".md"
And the registry extensions should include ".markdown"
And the registry extensions should include ".sql"
And the registry extensions should include ".ddl"
And the registry extensions should include ".yml"
And the registry extensions should include ".yaml"
# ---------------------------------------------------------------------------
# PythonAnalyzer
# ---------------------------------------------------------------------------
@python_analyzer
Scenario: Analyze Python class definition
Given a PythonAnalyzer analyzer
When I analyze the Python content:
"""
class MyService:
pass
"""
Then the triples should include predicate "rdf:type" with object_uri "uko-code:Module"
And the triples should include predicate "rdf:type" with object_uri "uko-py:Class"
And the triples should include predicate "uko:contains" linking subject "module" to object "MyService"
@python_analyzer
Scenario: Analyze Python function with docstring
Given a PythonAnalyzer analyzer
When I analyze the Python content:
"""
def process_data():
'''Process incoming data.'''
pass
"""
Then the triples should include predicate "rdf:type" with object_uri "uko-py:Function"
And the triples should include predicate "uko-doc:hasDocstring"
@python_analyzer
Scenario: Analyze Python imports
Given a PythonAnalyzer analyzer
When I analyze the Python content:
"""
import os
from pathlib import Path
"""
Then the triples should include predicate "uko:references" with object_uri containing "os"
And the triples should include predicate "uko:references" with object_uri containing "pathlib"
@python_analyzer
Scenario: Analyze empty Python content raises ValueError
Given a PythonAnalyzer analyzer
Then analyzing empty content with this analyzer should raise ValueError
@python_analyzer
Scenario: Analyze invalid Python syntax returns empty list
Given a PythonAnalyzer analyzer
When I analyze the Python content:
"""
def broken(
pass
class ???
"""
Then no triples should be returned
# ---------------------------------------------------------------------------
# MarkdownAnalyzer
# ---------------------------------------------------------------------------
@markdown_analyzer
Scenario: Analyze heading hierarchy
Given a MarkdownAnalyzer analyzer
When I analyze the Markdown content:
"""
# Introduction
Some text.
## Details
More text.
"""
Then the triples should include predicate "rdf:type" with object_uri "uko-doc:Document"
And the triples should include predicate "rdf:type" with object_uri "uko-doc:Section"
And the triples should include predicate "uko-doc:headingLevel" with object_value "1"
And the triples should include predicate "uko-doc:headingLevel" with object_value "2"
@markdown_analyzer
Scenario: Analyze code block with language
Given a MarkdownAnalyzer analyzer
When I analyze the Markdown content:
"""
# Example
```python
print("hello")
```
"""
Then the triples should include predicate "rdf:type" with object_uri "uko-code:CodeBlock"
And the triples should include predicate "uko-code:language" with object_value "python"
@markdown_analyzer
Scenario: Analyze links
Given a MarkdownAnalyzer analyzer
When I analyze the Markdown content:
"""
# Resources
See [Example](https://example.com) for details.
"""
Then the triples should include predicate "uko:references" with object_value "https://example.com"
@markdown_analyzer
Scenario: Analyze empty Markdown content raises ValueError
Given a MarkdownAnalyzer analyzer
Then analyzing empty content with this analyzer should raise ValueError
@markdown_analyzer
Scenario: Analyze content with no headings still produces Document triple
Given a MarkdownAnalyzer analyzer
When I analyze the Markdown content:
"""
Just some plain text without any headings.
Another line of text.
"""
Then the triples should include predicate "rdf:type" with object_uri "uko-doc:Document"
And the triples should not include predicate "rdf:type" with object_uri "uko-doc:Section"
# ---------------------------------------------------------------------------
# Cross-analyzer
# ---------------------------------------------------------------------------
@analyzer_cross
Scenario: All analyzers use UKO URI scheme
Given a PythonAnalyzer analyzer
And a MarkdownAnalyzer analyzer
And a PostgreSQLAnalyzer analyzer
And a DockerComposeAnalyzer analyzer
When each analyzer processes its sample content
Then every triple subject_uri should start with "uko://"
@analyzer_cross
Scenario: Confidence scores default to 1.0
Given a PythonAnalyzer analyzer
When I analyze the Python content:
"""
class Example:
pass
"""
Then every triple confidence should be 1.0