f2f7aa5dc9
Implement multiple Stage A/B/E/SEC milestones for the v3 lifecycle system: - Stage A5.3+A5.4: Add LifecycleActionModel and LifecyclePlanModel SQLAlchemy models with to_domain()/from_domain() conversion methods - Stage A5.6: Implement ActionRepository with full CRUD, namespace/state queries, referential integrity checks, and retry decorator - Stage E1: Add subplan domain models (ExecutionMode, SubplanMergeStrategy, SubplanConfig, SubplanStatus, SubplanAttempt, SubplanFailureHandler) with computed properties on Plan (is_subplan, is_root_plan, depth, has_subplans) - Stage A6: Add AutomationLevel enum (MANUAL, REVIEW_BEFORE_APPLY, FULL_AUTOMATION), settings integration, PlanLifecycleService auto-progression, pause/resume, and CLI commands (--automation-level, set-automation-level) - Stage SEC1: Remove eval()/exec() from stream_router.py, replace with named operation and transform registries; code blocks and unregistered transforms now raise StreamRoutingError - Add langchain-anthropic dependency - Update BDD tests for security changes and relax ADR directory requirement
88 lines
3.9 KiB
Gherkin
88 lines
3.9 KiB
Gherkin
Feature: Stream Router uncovered branches
|
|
As a developer
|
|
I want targeted Behave coverage for uncovered stream_router paths
|
|
So that critical branches are exercised
|
|
|
|
Background:
|
|
Given the CleverAgents reactive system is available
|
|
|
|
Scenario: Copying stream message without metadata override deep copies entries
|
|
Given I have a base stream message with context metadata
|
|
When I copy the message without metadata override
|
|
Then the metadata should be deep-copied except context
|
|
|
|
Scenario: Map operator without params should raise routing error
|
|
When I build a map operator without required params
|
|
Then I should get a stream routing error about missing map params
|
|
|
|
Scenario: Buffer operator without count should raise routing error
|
|
When I build a buffer operator without count
|
|
Then I should get a stream routing error about buffer count
|
|
|
|
Scenario: Window operator without count should raise routing error
|
|
When I build a window operator without count
|
|
Then I should get a stream routing error about window count
|
|
|
|
Scenario: Condition check for missing field returns false
|
|
When I evaluate a field condition against a message without that field
|
|
Then the condition result should be false
|
|
|
|
Scenario: Accumulator append initializes list and appends items
|
|
When I apply the append accumulator with list initialization
|
|
Then the accumulator should return a list with the item
|
|
|
|
Scenario: Sending message to unknown stream raises routing error
|
|
When I send a message to an unknown stream
|
|
Then I should get a stream routing error about missing stream
|
|
|
|
Scenario: Splitting from unknown source raises routing error
|
|
When I split a stream from an unknown source
|
|
Then I should get a stream routing error about missing source
|
|
|
|
Scenario: Creating stream using string name initializes config
|
|
When I create a stream from the string name "string_stream"
|
|
Then the stream should exist in the router
|
|
|
|
Scenario: Duplicate stream creation raises routing error
|
|
Given I have already created a stream named "dup_stream"
|
|
When I try to create the stream "dup_stream" again
|
|
Then I should get a stream routing error about duplicate stream
|
|
|
|
Scenario: Map operator with function param uses fallback
|
|
When I map a message using function param "noop_function"
|
|
Then the mapped result should equal the original message
|
|
|
|
Scenario: Transform operator with unregistered fn raises error
|
|
When I build a transform operator with an invalid function string
|
|
Then I should get a stream routing error about unregistered transform fn
|
|
|
|
Scenario: Filter operator without condition raises routing error
|
|
When I build a filter operator without condition
|
|
Then I should get a stream routing error about missing filter condition
|
|
|
|
Scenario: Switch operator applies default operators pipeline
|
|
When I run a switch operator with default operators against a message
|
|
Then the switch operator should output the transformed value
|
|
|
|
Scenario: Switch operator routes to default stream subject
|
|
When I run a switch operator that targets a default stream subject
|
|
Then the default stream should emit its initial value
|
|
|
|
Scenario: Apply replace transform updates dictionary field
|
|
When I apply a replace transform to a dictionary message
|
|
Then the dictionary field should be updated
|
|
|
|
Scenario: Sum accumulator initializes and sums numeric messages
|
|
When I apply the sum accumulator to numeric messages
|
|
Then the accumulator should produce the summed value
|
|
|
|
Scenario: Merge streams creates target when missing
|
|
Given I have two source streams named "merge_a" and "merge_b"
|
|
When I merge the streams into a new target "merge_output"
|
|
Then the merged target stream should exist
|
|
|
|
Scenario: Dispose cleans up subscriptions and stream disposables
|
|
Given I have a stream router with disposable streams and subscriptions
|
|
When I dispose the stream router
|
|
Then the stream router internals should be cleared
|