168 lines
6.4 KiB
Gherkin
168 lines
6.4 KiB
Gherkin
Feature: Stream Router Coverage
|
|
As a developer
|
|
I want to exercise reactive stream router behaviors
|
|
So that stream_router.py is covered in actor-first mode
|
|
|
|
Background:
|
|
Given a reactive stream router harness
|
|
|
|
Scenario: Create replay stream with buffer size
|
|
Given I have a replay stream configuration:
|
|
"""
|
|
{"name": "replay_stream", "type": "replay", "buffer_size": 5, "operators": []}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Create hot stream with initial value
|
|
Given I have a hot stream configuration:
|
|
"""
|
|
{"name": "hot_stream", "type": "hot", "initial_value": "initial_data", "operators": []}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Stream creation with existing name should fail
|
|
Given I have a stream configuration:
|
|
"""
|
|
{"name": "existing_stream", "type": "cold", "operators": []}
|
|
"""
|
|
When I create the reactive stream
|
|
And I try to create another stream with the same name
|
|
Then I should get a stream router coverage error
|
|
|
|
Scenario: Create agent mapper with tool agent
|
|
Given I have a tool agent named "echo_agent" with echo tool
|
|
And I have a stream configuration with agent mapper:
|
|
"""
|
|
{"name": "agent_stream", "type": "cold", "operators": [{"type": "map", "params": {"agent": "echo_agent"}}]}
|
|
"""
|
|
When I create the reactive stream
|
|
And I send router message "hello" to stream "agent_stream"
|
|
Then the stream should be created successfully
|
|
|
|
|
|
Scenario: Create agent mapper with missing agent should fail
|
|
Given I have a stream configuration with missing agent:
|
|
"""
|
|
{"name": "missing_agent_stream", "type": "cold", "operators": [{"type": "map", "params": {"agent": "nonexistent_agent"}}]}
|
|
"""
|
|
When I try to create the reactive stream
|
|
Then I should get a stream router coverage error about missing agent
|
|
|
|
Scenario: Transform operator with extract_field transform
|
|
Given I have a stream configuration with extract transform:
|
|
"""
|
|
{"name": "extract_stream", "type": "cold", "operators": [{"type": "map", "params": {"transform": {"type": "extract_field", "field": "data"}}}]}
|
|
"""
|
|
When I create the reactive stream
|
|
And I send a dictionary message with field "data"
|
|
Then the field value should be extracted
|
|
|
|
Scenario: Unknown operator should fail
|
|
Given I have a stream configuration with unknown operator:
|
|
"""
|
|
{"name": "unknown_stream", "type": "cold", "operators": [{"type": "unknown_operator"}]}
|
|
"""
|
|
When I try to create the reactive stream
|
|
Then I should get a stream router coverage error about unknown operator
|
|
|
|
Scenario: LangGraph operators without bridge should fail
|
|
Given I have a stream configuration with LangGraph operator:
|
|
"""
|
|
{"name": "langgraph_stream", "type": "cold", "operators": [{"type": "graph_execute", "params": {}}]}
|
|
"""
|
|
When I try to create the reactive stream
|
|
Then I should get a stream router coverage error about LangGraph bridge
|
|
|
|
Scenario: Stream message copy_with functionality
|
|
Given I have a stream message for router testing
|
|
When I copy the message with modifications
|
|
Then the new message should have the modifications
|
|
And the original message should be unchanged
|
|
|
|
Scenario: Agent mapper with None message handling
|
|
Given I have a tool agent named "none_agent" with echo tool
|
|
And I have a stream configuration with agent mapper:
|
|
"""
|
|
{"name": "none_stream", "type": "cold", "operators": [{"type": "map", "params": {"agent": "none_agent"}}]}
|
|
"""
|
|
When I create the reactive stream
|
|
And I send router None message to stream "none_stream"
|
|
Then the agent should handle None gracefully
|
|
|
|
|
|
Scenario: Stream disposal
|
|
Given I have a stream for router testing
|
|
When I dispose of the stream router
|
|
Then the stream router should be disposed properly
|
|
|
|
Scenario: Message with timestamp
|
|
Given I have a stream for router testing
|
|
When I send a message to check timestamp
|
|
Then the message should have a timestamp
|
|
|
|
Scenario: Filter operator with equals condition
|
|
Given I have a stream configuration with equals filter:
|
|
"""
|
|
{"name": "equals_filter", "type": "cold", "operators": [{"type": "filter", "params": {"condition": {"equals": "match"}}}]}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Filter operator with field presence condition
|
|
Given I have a stream configuration with field condition:
|
|
"""
|
|
{"name": "field_filter", "type": "cold", "operators": [{"type": "filter", "params": {"condition": {"field": "test_key"}}}]}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Buffer and window operators
|
|
Given I have a stream configuration with buffer and window:
|
|
"""
|
|
{"name": "buffer_window", "type": "cold", "operators": [
|
|
{"type": "buffer", "params": {"count": 2, "timeout": 0.01}},
|
|
{"type": "window", "params": {"count": 1}}
|
|
]}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Take, skip, and merge operators
|
|
Given I have a stream configuration with take skip merge:
|
|
"""
|
|
{"name": "take_skip_merge", "type": "cold", "operators": [
|
|
{"type": "take", "params": {"count": 1}},
|
|
{"type": "skip", "params": {"count": 0}},
|
|
{"type": "merge", "params": {"streams": ["__input__"]}}
|
|
]}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Accumulate operator
|
|
Given I have a stream configuration with accumulate:
|
|
"""
|
|
{"name": "accumulate_stream", "type": "cold", "operators": [
|
|
{"type": "accumulate", "params": {"accumulator": {"op": "sum"}}}
|
|
]}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|
|
|
|
Scenario: Switch/conditional routing operator
|
|
Given I have a stream configuration with switch operator:
|
|
"""
|
|
{"name": "switch_stream", "type": "cold", "operators": [
|
|
{"type": "switch", "params": {
|
|
"cases": [
|
|
{"condition": {"equals": "yes"}, "target": "__output__"}
|
|
],
|
|
"default": "__output__"
|
|
}}
|
|
]}
|
|
"""
|
|
When I create the reactive stream
|
|
Then the stream should be created successfully
|