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
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.
214 lines
10 KiB
Gherkin
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) |