340 lines
16 KiB
Gherkin
340 lines
16 KiB
Gherkin
Feature: LangGraph Bridge Module Coverage
|
|
As a developer
|
|
I want to test all functionality in the langgraph bridge module
|
|
So that we achieve 90%+ code coverage for the bridge.py file
|
|
|
|
Background:
|
|
Given I have a clean test environment for langgraph bridge
|
|
And I have initialized the reactive system with langgraph support
|
|
|
|
Scenario: Test RxPyLangGraphBridge initialization
|
|
Given I have a stream router instance
|
|
When I create a RxPyLangGraphBridge instance
|
|
Then the bridge should be initialized correctly
|
|
And the stream router should be stored
|
|
And the graphs dictionary should be empty
|
|
And langgraph operators should be registered
|
|
|
|
Scenario: Test _register_langgraph_operators
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When the bridge registers langgraph operators
|
|
Then graph_execute operator should be registered
|
|
And state_update operator should be registered
|
|
And state_checkpoint operator should be registered
|
|
And langgraph_node operator should be registered
|
|
And conditional_route operator should be registered
|
|
|
|
Scenario: Test create_graph_from_config - basic configuration
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a basic graph configuration for bridge testing
|
|
When I create a graph from configuration using bridge
|
|
Then a LangGraph should be created successfully via bridge
|
|
And the graph should have the correct name in bridge
|
|
And the graph should be stored in the graphs dictionary in bridge
|
|
And the graph should have the specified entry point in bridge
|
|
|
|
Scenario: Test create_graph_from_config - with nodes configuration
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a graph configuration with nodes for bridge testing
|
|
When I create a graph from configuration using bridge
|
|
Then nodes should be created correctly in bridge
|
|
And node types should be set properly in bridge
|
|
And node metadata should be preserved in bridge
|
|
|
|
Scenario: Test create_graph_from_config - with edges configuration
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a graph configuration with edges for bridge testing
|
|
When I create a graph from configuration using bridge
|
|
Then edges should be created correctly in bridge
|
|
And edge conditions should be preserved in bridge
|
|
And edge metadata should be included in bridge
|
|
|
|
Scenario: Test create_graph_from_config - with checkpointing enabled
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a graph configuration with checkpointing enabled for bridge testing
|
|
When I create a graph from configuration using bridge
|
|
Then the graph should have checkpointing enabled in bridge
|
|
And the graph should have time travel enabled in bridge
|
|
|
|
Scenario: Test create_graph_from_config - with parallel execution
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a graph configuration with parallel execution for bridge testing
|
|
When I create a graph from configuration using bridge
|
|
Then the graph should have parallel execution enabled in bridge
|
|
|
|
Scenario: Test create_graph_stream - existing graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "test_graph" for bridge testing
|
|
When I create a graph stream for "test_graph" using bridge
|
|
Then a StreamConfig should be created by bridge
|
|
And the stream should have graph_execute operator in bridge
|
|
And the stream name should be "graph_test_graph" in bridge
|
|
And the stream type should be COLD in bridge
|
|
|
|
Scenario: Test create_graph_stream - non-existing graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I try to create a graph stream for non-existing graph using bridge
|
|
Then a ValueError should be raised with message containing "not found" in bridge
|
|
|
|
Scenario: Test _create_graph_executor - valid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "executor_test" for bridge testing
|
|
When I create a graph executor operator for "executor_test" using bridge
|
|
Then the operator should process stream messages in bridge
|
|
And the operator should execute the graph in bridge
|
|
And the operator should return results with metadata in bridge
|
|
|
|
Scenario: Test _create_graph_executor - invalid graph name
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I try to create a graph executor for invalid graph using bridge
|
|
Then a ValueError should be raised in bridge
|
|
|
|
Scenario: Test _create_graph_executor - string input handling
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a test graph named "string_test" for bridge testing
|
|
When I execute the graph with a string message using bridge
|
|
Then the string should be converted to messages format by bridge
|
|
And the graph should process the message correctly via bridge
|
|
|
|
Scenario: Test _create_graph_executor - dict input handling
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a test graph named "dict_test" for bridge testing
|
|
When I execute the graph with a dict message using bridge
|
|
Then the dict should be passed directly to the graph via bridge
|
|
And the graph should process the message correctly via bridge
|
|
|
|
Scenario: Test _create_state_updater - valid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a stateful graph named "state_test" for bridge testing
|
|
When I create a state updater operator using bridge
|
|
Then the operator should update graph state via bridge
|
|
And the message should include state_updated metadata in bridge
|
|
|
|
Scenario: Test _create_state_updater - update modes
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a stateful graph for bridge testing
|
|
When I create a state updater with merge mode using bridge
|
|
Then state updates should be merged correctly by bridge
|
|
|
|
Scenario: Test _create_state_updater - invalid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I try to create a state updater for invalid graph using bridge
|
|
Then a ValueError should be raised in bridge
|
|
|
|
Scenario: Test _create_state_checkpointer - valid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph with checkpointing for bridge testing
|
|
When I create a state checkpointer operator using bridge
|
|
Then the operator should checkpoint graph state via bridge
|
|
And the message should include checkpointed metadata in bridge
|
|
|
|
Scenario: Test _create_state_checkpointer - invalid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I try to create a state checkpointer for invalid graph using bridge
|
|
Then a ValueError should be raised in bridge
|
|
|
|
Scenario: Test _create_node_operator - valid node
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph with nodes for bridge testing
|
|
When I create a node operator for a valid node using bridge
|
|
Then the operator should execute the specific node via bridge
|
|
And the node execution should update graph state via bridge
|
|
And results should include node metadata in bridge
|
|
|
|
Scenario: Test _create_node_operator - invalid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I try to create a node operator for invalid graph using bridge
|
|
Then a ValueError should be raised in bridge
|
|
|
|
Scenario: Test _create_node_operator - invalid node
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "node_test" for bridge testing
|
|
When I try to create a node operator for invalid node using bridge
|
|
Then a ValueError should be raised in bridge
|
|
|
|
Scenario: Test _create_node_operator - string message handling
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph with nodes for bridge testing
|
|
When I execute a node with a string message using bridge
|
|
Then the string should be added to state messages in bridge
|
|
And the node should process the message via bridge
|
|
|
|
Scenario: Test _create_conditional_router - basic routing
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have conditional routing configuration for bridge testing
|
|
When I create a conditional router operator using bridge
|
|
Then the operator should route messages based on conditions in bridge
|
|
And messages should be grouped by route in bridge
|
|
|
|
Scenario: Test _create_conditional_router - default route
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have routing configuration with default route for bridge testing
|
|
When I route a message that matches no conditions using bridge
|
|
Then the message should go to the default route in bridge
|
|
|
|
Scenario: Test _create_conditional_router - no default route
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have routing configuration without default route for bridge testing
|
|
When I route a message that matches no conditions using bridge
|
|
Then the message should go to "__output__" in bridge
|
|
|
|
Scenario: Test _evaluate_route_condition - always condition
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a message for bridge testing
|
|
When I evaluate an "always" condition using bridge
|
|
Then the condition should return True in bridge
|
|
|
|
Scenario: Test _evaluate_route_condition - content_type condition
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a message with string content for bridge testing
|
|
When I evaluate a content_type condition for "str" using bridge
|
|
Then the condition should return True in bridge
|
|
When I evaluate a content_type condition for "dict" using bridge
|
|
Then the condition should return False in bridge
|
|
|
|
Scenario: Test _evaluate_route_condition - metadata_has condition
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a message with metadata key "test_key" for bridge testing
|
|
When I evaluate a metadata_has condition for "test_key" using bridge
|
|
Then the condition should return True in bridge
|
|
When I evaluate a metadata_has condition for "missing_key" using bridge
|
|
Then the condition should return False in bridge
|
|
|
|
Scenario: Test _evaluate_route_condition - content_contains condition
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a message with content "hello world" for bridge testing
|
|
When I evaluate a content_contains condition for "hello" using bridge
|
|
Then the condition should return True in bridge
|
|
When I evaluate a content_contains condition for "goodbye" using bridge
|
|
Then the condition should return False in bridge
|
|
|
|
Scenario: Test _evaluate_route_condition - unknown condition type
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a message for bridge testing
|
|
When I evaluate an unknown condition type using bridge
|
|
Then the condition should return False in bridge
|
|
|
|
Scenario: Test connect_stream_to_graph - valid connection
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "connect_test" for bridge testing
|
|
And I have a stream named "input_stream" for bridge testing
|
|
When I connect the stream to the graph using bridge
|
|
Then an observer should be created by bridge
|
|
And the observer should execute the graph on messages via bridge
|
|
And the subscription should be stored by bridge
|
|
|
|
Scenario: Test connect_stream_to_graph - invalid stream
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "test" for bridge testing
|
|
When I try to connect non-existing stream to graph using bridge
|
|
Then a ValueError should be raised with "Stream" and "not found" in bridge
|
|
|
|
Scenario: Test connect_stream_to_graph - invalid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a stream named "test" for bridge testing
|
|
When I try to connect stream to non-existing graph using bridge
|
|
Then a ValueError should be raised with "Graph" and "not found" in bridge
|
|
|
|
Scenario: Test connect_graph_to_stream - existing stream
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "output_test" for bridge testing
|
|
And I have a stream named "output_stream" for bridge testing
|
|
When I connect the graph to the stream using bridge
|
|
Then graph state updates should be sent to the stream via bridge
|
|
And messages should include graph metadata in bridge
|
|
|
|
Scenario: Test connect_graph_to_stream - create new stream
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph named "new_stream_test" for bridge testing
|
|
When I connect the graph to a new stream "new_output" using bridge
|
|
Then a new Subject stream should be created by bridge
|
|
And the stream should be registered in stream router by bridge
|
|
|
|
Scenario: Test connect_graph_to_stream - invalid graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I try to connect non-existing graph to stream using bridge
|
|
Then a ValueError should be raised in bridge
|
|
|
|
Scenario: Test create_hybrid_pipeline - stream stages
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a hybrid pipeline config with stream stages for bridge testing
|
|
When I create the hybrid pipeline using bridge
|
|
Then stream stages should be created correctly by bridge
|
|
And streams should have correct configurations in bridge
|
|
|
|
Scenario: Test create_hybrid_pipeline - graph stages
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a hybrid pipeline config with graph stages for bridge testing
|
|
When I create the hybrid pipeline using bridge
|
|
Then graph stages should be created correctly by bridge
|
|
And graphs should be properly configured in bridge
|
|
|
|
Scenario: Test create_hybrid_pipeline - connected stages
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a pipeline config with connected stages for bridge testing
|
|
When I create the hybrid pipeline using bridge
|
|
Then stages should be connected properly by bridge
|
|
And input_from connections should work in bridge
|
|
And output_to connections should work in bridge
|
|
|
|
Scenario: Test get_graph - existing graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created graphs named "graph1" and "graph2" for bridge testing
|
|
When I get graph "graph1" using bridge
|
|
Then the correct graph should be returned by bridge
|
|
|
|
Scenario: Test get_graph - non-existing graph
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I get non-existing graph using bridge
|
|
Then None should be returned by bridge
|
|
|
|
Scenario: Test list_graphs
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created graphs named "alpha", "beta", "gamma" for bridge testing
|
|
When I list all graphs using bridge
|
|
Then the list should contain all graph names in bridge
|
|
And the list should have 3 items in bridge
|
|
|
|
Scenario: Test _register_operator
|
|
Given I have a RxPyLangGraphBridge instance
|
|
When I register a custom operator "test_op" using bridge
|
|
Then the operator factory should be stored by bridge
|
|
And the operator should be accessible in bridge
|
|
|
|
Scenario: Test graph executor with execution history
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a graph with execution tracking
|
|
When I execute the graph through bridge
|
|
Then execution history should be included in metadata
|
|
And final state should be included in metadata
|
|
|
|
Scenario: Test state updater with dict content
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a stateful graph for bridge testing
|
|
When I update state with dict content
|
|
Then the dict should be used directly for updates
|
|
|
|
Scenario: Test state updater with non-dict content
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have created a stateful graph for bridge testing
|
|
When I update state with string content
|
|
Then the content should be wrapped in a dict with "data" key
|
|
|
|
Scenario: Test node operator result extraction - with messages
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a graph with message-returning nodes
|
|
When I execute a node that returns messages
|
|
Then the last message content should be extracted
|
|
|
|
Scenario: Test node operator result extraction - without messages
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a graph with data-returning nodes
|
|
When I execute a node that returns other data
|
|
Then the full updates dict should be returned
|
|
|
|
Scenario: Test conditional router observable operations
|
|
Given I have a RxPyLangGraphBridge instance
|
|
And I have a conditional router
|
|
When I apply the router to an observable
|
|
Then messages should be grouped by route key
|
|
And grouped messages should be flattened with keys |