Files
cleveractors-core/features/pure_graph_coverage.feature
CoreRasurae 9753b31c7e
CI / quality (push) Successful in 36s
CI / lint (push) Successful in 38s
CI / typecheck (push) Successful in 49s
CI / security (push) Successful in 51s
CI / integration_tests (push) Successful in 55s
CI / unit_tests (push) Successful in 3m35s
CI / build (push) Successful in 33s
CI / coverage (push) Successful in 3m36s
CI / status-check (push) Successful in 3s
test: add coverage gap tests improving coverage from 81.4% to 96.90%
Add 13 BDD scenarios covering previously uncovered code paths:
- SAFE_BUILTINS validation (sandbox.py: 0% → 100%)
- ConfigurationError re-raise path (config.py: 99.3% → 100%)
- CLI hello/main functions (cli.py: 72.7% → 90.9%)
- GraphState message truncation (state.py: 98.7% → 100%)
- ProgressBarManager update/context rendering (progress.py: 0% → 87.7%)
- MessageRouter regex/exact/contains routing (message_router.py: 0% → 59.4%)
- RoutingAdapter parse_routing_command (routing_adapter.py)
- DynamicRouterNode pattern-based routing (dynamic_router.py)
- EnhancedTemplateRegistry unknown template type (enhanced_registry.py: 99.2%)
- CompositeAgent null-graph error path (composite.py: 97.8% → 98.6%)

Cover routing_adapter.py (17% → 100%): all GOTO/ROUTE patterns,
create_routing_node, create_conditional_router, dynamic config conversion.

Cover dynamic_router.py (21% → 87%): execute with empty/dict/string
messages, extract_message with colon parsing, config creation, graph
extension with edge generation.

Cover message_router.py (59% → 78%): regex, exact, contains, prefix,
suffix match types, invalid regex handling, non-string message, set_state.

Exercise Node._prepare_conversation_history with invalid configs,
_runtime error paths, _execute_message_router with rules,
_execute_agent with current_message and metadata propagation,
_execute_function with dynamic_router, and _execute_conditional
with content_contains/content_not_contains/content_starts_with
and custom condition types. Improves nodes.py from 71.3% to 72.5%.

Exercise PureGraphConfig, PureLangGraph init with dict/config,
RxPyLangGraphBridge registration/connection/lookup,
ReactiveStreamRouter operator creation and condition functions,
ReactiveConfigParser config/route/graph parsing,
ToolAgent tool execution with JSON, space-separated, single,
file_read, progress_bar invocations, and
ReactiveCleverAgentsApp init/dispose/visualization.
2026-06-02 20:02:01 +01:00

214 lines
10 KiB
Gherkin

Feature: Pure Graph Configuration Analysis, Cycle Detection, and Execution
As a developer
I want pure graphs to validate configurations, analyze structure, detect cycles, and execute with edge conditions
So that graph topology validation prevents malformed workflows from entering production
Scenario: PureGraphConfig initializes with all fields
Given a fresh pure graph test context (pg_cov)
When I create a PureGraphConfig with all fields (pg_cov)
Then all PureGraphConfig fields should be set correctly (pg_cov)
Scenario: PureLangGraph init converts dict config to PureGraphConfig
Given a fresh pure graph test context (pg_cov)
When I create a PureLangGraph with a dict config (pg_cov)
Then the config should be converted to PureGraphConfig (pg_cov)
Scenario: Graph initializes message router nodes
Given a fresh pure graph test context (pg_cov)
When I create a graph with a MESSAGE_ROUTER node (pg_cov)
Then the message router node should be initialized (pg_cov)
Scenario: Graph initializes dynamic router nodes
Given a fresh pure graph test context (pg_cov)
When I create a graph with a dynamic_router node type (pg_cov)
Then the dynamic router node should be initialized (pg_cov)
Scenario: Graph analysis maps END to end in edges
Given a fresh pure graph test context (pg_cov)
When I create a graph with edges using END (pg_cov)
Then END should be mapped to end in adjacency lists (pg_cov)
Scenario: Graph finds entry nodes correctly
Given a fresh pure graph test context (pg_cov)
When I create a graph with nodes having different incoming edges (pg_cov)
Then entry nodes should be correctly identified (pg_cov)
Scenario: Graph detects cycles
Given a fresh pure graph test context (pg_cov)
When I create a graph with a cycle (pg_cov)
Then the graph should detect the cycle (pg_cov)
Scenario: Graph confirms no cycles
Given a fresh pure graph test context (pg_cov)
When I create a graph without cycles (pg_cov)
Then the graph should report no cycles (pg_cov)
Scenario: Execute raises error when already running
Given a fresh pure graph test context (pg_cov)
When I try to execute a graph that is already running (pg_cov)
Then a RuntimeError should be raised (pg_cov)
Scenario: Execute with global_context provided
Given a fresh pure graph test context (pg_cov)
When I execute a graph with global_context (pg_cov)
Then the global_context should be used as initial context (pg_cov)
Scenario: Execute with conversation_history provided
Given a fresh pure graph test context (pg_cov)
When I execute a graph with conversation_history (pg_cov)
Then the conversation_history should be included in messages (pg_cov)
Scenario: Execute with context_manager but no global_context
Given a fresh pure graph test context (pg_cov)
When I execute a graph with a context_manager providing global context (pg_cov)
Then the context_manager context should be used (pg_cov)
Scenario: Execute uses _last_context as fallback
Given a fresh pure graph test context (pg_cov)
When I execute a graph with _last_context set (pg_cov)
Then _last_context should be used as initial context (pg_cov)
Scenario: Execute persists final state to context_manager
Given a fresh pure graph test context (pg_cov)
When I execute a graph with a context_manager (pg_cov)
Then the final state should be saved to the context_manager (pg_cov)
Scenario: Execute updates global_context dict in place
Given a fresh pure graph test context (pg_cov)
When I execute a graph with a mutable global_context dict (pg_cov)
Then the global_context dict should be updated with final state (pg_cov)
Scenario: Execute with empty conversation_history
Given a fresh pure graph test context (pg_cov)
When I execute a graph with empty conversation_history entries (pg_cov)
Then empty entries should be skipped (pg_cov)
Scenario: Execute node max depth exceeded
Given a fresh pure graph test context (pg_cov)
When I execute a node beyond max recursion depth (pg_cov)
Then the current message should be returned (pg_cov)
Scenario: Execute detects cycle and stops with current message
Given a fresh pure graph test context (pg_cov)
When I execute a graph with a self-loop to the same node (pg_cov)
Then the cycle should be detected and current message returned (pg_cov)
Scenario: Cycle detection bypassed with auto_finish_active
Given a fresh pure graph test context (pg_cov)
When I execute a graph with auto_finish_active and a self-loop (pg_cov)
Then execution should continue past cycle detection (pg_cov)
Scenario: Execute detects ping-pong between router and agent
Given a fresh pure graph test context (pg_cov)
When I execute a graph with router-agent-router-agent ping-pong (pg_cov)
Then the ping-pong should be detected and current message returned (pg_cov)
Scenario: Ping-pong detection bypassed with auto_finish_active
Given a fresh pure graph test context (pg_cov)
When I execute a graph with auto_finish_active causing ping-pong pattern (pg_cov)
Then execution should continue past ping-pong detection (pg_cov)
Scenario: Execute from start node routes to entry point
Given a fresh pure graph test context (pg_cov)
When I execute from the start node (pg_cov)
Then it should route to the next node after start (pg_cov)
Scenario: Execute from end node returns message
Given a fresh pure graph test context (pg_cov)
When I execute from the end node (pg_cov)
Then the end node message should be returned as-is (pg_cov)
Scenario: Execute from node not found returns message
Given a fresh pure graph test context (pg_cov)
When I execute from a non-existent node (pg_cov)
Then the not-found node message should be returned (pg_cov)
Scenario: Execute parallel execution with multiple next nodes
Given a fresh pure graph test context (pg_cov)
When I execute a graph with parallel execution and multiple next nodes (pg_cov)
Then nodes should be executed in parallel (pg_cov)
Scenario: Execute sequential execution with multiple next nodes
Given a fresh pure graph test context (pg_cov)
When I execute a graph with sequential execution and multiple next nodes (pg_cov)
Then nodes should be executed sequentially (pg_cov)
Scenario: Execute no next nodes returns output
Given a fresh pure graph test context (pg_cov)
When I execute from a node with no outgoing edges (pg_cov)
Then the output should be returned (pg_cov)
Scenario: Get next nodes evaluates edges
Given a fresh pure graph test context (pg_cov)
When I get next nodes from a node with edges (pg_cov)
Then edges should be evaluated for valid next nodes (pg_cov)
Scenario: Edge condition content_contains with string message
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with content_contains condition and string message (pg_cov)
Then the condition should match correctly (pg_cov)
Scenario: Edge condition content_contains with dict message
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with content_contains condition and dict message (pg_cov)
Then the condition should check the content field (pg_cov)
Scenario: Edge condition context_value matches metadata
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with context_value condition (pg_cov)
Then the context value should be checked against state metadata (pg_cov)
Scenario: Edge condition context_value matches nested context
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with context_value in nested context (pg_cov)
Then the nested context value should be checked (pg_cov)
Scenario: Edge condition output_pattern matches
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with output_pattern condition (pg_cov)
Then the last_output should be checked against the pattern (pg_cov)
Scenario: Edge condition message_pattern matches
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with message_pattern condition (pg_cov)
Then the last message should be checked against the pattern (pg_cov)
Scenario: Edge condition unknown type defaults to true
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with an unknown condition type (pg_cov)
Then the edge should default to allowing traversal (pg_cov)
Scenario: Edge condition always allows traversal
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with an always condition type (pg_cov)
Then the edge should always allow traversal (pg_cov)
Scenario: Edge with no condition always allows traversal
Given a fresh pure graph test context (pg_cov)
When I evaluate an edge with no condition (pg_cov)
Then the edge should allow traversal (pg_cov)
Scenario: create_pure_langgraph with dict config and dict nodes
Given a fresh pure graph test context (pg_cov)
When I call create_pure_langgraph with a fully dict config (pg_cov)
Then a PureLangGraph should be created with correct nodes and edges (pg_cov)
Scenario: create_pure_langgraph with NodeConfig and Edge objects
Given a fresh pure graph test context (pg_cov)
When I call create_pure_langgraph with NodeConfig and Edge objects (pg_cov)
Then the objects should be used directly (pg_cov)
Scenario: create_pure_langgraph handles errors gracefully
Given a fresh pure graph test context (pg_cov)
When I call create_pure_langgraph with invalid config (pg_cov)
Then an exception should be raised (pg_cov)
Scenario: create_pure_langgraph converts dict edges to Edge objects
Given a fresh pure graph test context (pg_cov)
When I call create_pure_langgraph with dict edges (pg_cov)
Then the edges should be converted to Edge objects (pg_cov)
Scenario: process_message delegates to execute
Given a fresh pure graph test context (pg_cov)
When I call process_message on a PureLangGraph (pg_cov)
Then it should delegate to execute and return the result (pg_cov)