chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from enum import Enum
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from semantic_kernel.exceptions.kernel_exceptions import KernelException
|
||||
from semantic_kernel.functions.kernel_function_metadata import KernelFunctionMetadata
|
||||
from semantic_kernel.processes.kernel_process.kernel_process_edge import KernelProcessEdge
|
||||
from semantic_kernel.processes.kernel_process.kernel_process_function_target import KernelProcessFunctionTarget
|
||||
from semantic_kernel.processes.kernel_process.kernel_process_step import KernelProcessStep
|
||||
from semantic_kernel.processes.kernel_process.kernel_process_step_info import KernelProcessStepInfo
|
||||
from semantic_kernel.processes.process_step_builder import ProcessStepBuilder
|
||||
from semantic_kernel.processes.process_step_edge_builder import ProcessStepEdgeBuilder
|
||||
|
||||
|
||||
class TestFunctionEnum(Enum):
|
||||
MY_FUNCTION = "my_function"
|
||||
|
||||
|
||||
class MockKernelProcessStep(KernelProcessStep):
|
||||
"""A mock class to use as a step type."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def test_initialization():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_type = MockKernelProcessStep
|
||||
initial_state = MagicMock()
|
||||
|
||||
# Act
|
||||
step_builder = ProcessStepBuilder(name=name, type=step_type, initial_state=initial_state)
|
||||
|
||||
# Assert
|
||||
assert step_builder.name == name
|
||||
assert step_builder.function_type == step_type
|
||||
assert step_builder.initial_state == initial_state
|
||||
assert step_builder.id is not None
|
||||
assert step_builder.event_namespace.startswith(name)
|
||||
|
||||
|
||||
def test_initialization_without_type():
|
||||
# Arrange
|
||||
name = "test_step_no_type"
|
||||
|
||||
# Act
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
|
||||
# Assert
|
||||
assert step_builder.name == name
|
||||
assert step_builder.function_type is None
|
||||
assert step_builder.initial_state is None
|
||||
assert step_builder.id is not None
|
||||
assert step_builder.event_namespace.startswith(name)
|
||||
|
||||
|
||||
def test_on_input_event():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
event_id = "event_input"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
|
||||
# Act
|
||||
edge_builder = step_builder.on_input_event(event_id=event_id)
|
||||
|
||||
# Assert
|
||||
assert isinstance(edge_builder, ProcessStepEdgeBuilder)
|
||||
assert edge_builder.source == step_builder
|
||||
assert edge_builder.event_id == event_id
|
||||
|
||||
|
||||
def test_on_event():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
event_id = "event_action"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
|
||||
# Act
|
||||
edge_builder = step_builder.on_event(event_id=event_id)
|
||||
|
||||
# Assert
|
||||
assert isinstance(edge_builder, ProcessStepEdgeBuilder)
|
||||
assert edge_builder.source == step_builder
|
||||
assert edge_builder.event_id == f"{step_builder.event_namespace}.{event_id}"
|
||||
|
||||
|
||||
def test_resolve_function_target_with_single_function():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
step_builder.functions_dict = {"process_data": MagicMock(spec=KernelFunctionMetadata)}
|
||||
|
||||
# Act
|
||||
target = step_builder.resolve_function_target(function_name=None, parameter_name="input_param")
|
||||
|
||||
# Assert
|
||||
assert target.function_name == "process_data"
|
||||
assert target.parameter_name == "input_param"
|
||||
|
||||
|
||||
def test_resolve_function_target_with_multiple_functions():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
step_builder.functions_dict = {
|
||||
"func_1": MagicMock(spec=KernelFunctionMetadata),
|
||||
"func_2": MagicMock(spec=KernelFunctionMetadata),
|
||||
}
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(
|
||||
KernelException, match="The target step has more than one function, so a function name must be provided."
|
||||
):
|
||||
step_builder.resolve_function_target(function_name=None, parameter_name="input_param")
|
||||
|
||||
|
||||
def test_get_scoped_event_id():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
event_id = "my_event"
|
||||
|
||||
# Act
|
||||
scoped_event_id = step_builder.get_scoped_event_id(event_id)
|
||||
|
||||
# Assert
|
||||
assert scoped_event_id == f"{step_builder.event_namespace}.{event_id}"
|
||||
|
||||
|
||||
def test_build_step():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name, type=MockKernelProcessStep)
|
||||
|
||||
edge = MagicMock(spec=KernelProcessEdge)
|
||||
built_edge = KernelProcessEdge(
|
||||
source_step_id="source_step_id",
|
||||
output_target=MagicMock(spec=KernelProcessFunctionTarget),
|
||||
)
|
||||
edge.build = MagicMock(return_value=built_edge)
|
||||
|
||||
step_builder.edges = {"event_1": [edge]}
|
||||
|
||||
# Act
|
||||
step_info = step_builder.build_step()
|
||||
|
||||
# Assert
|
||||
assert isinstance(step_info, KernelProcessStepInfo)
|
||||
assert step_info.state.name == step_builder.name
|
||||
assert step_info.state.id == step_builder.id
|
||||
assert step_info.output_edges == {"event_1": [built_edge]}
|
||||
|
||||
|
||||
def test_link_to():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
edge_builder = MagicMock(spec=ProcessStepEdgeBuilder)
|
||||
event_id = "event_1"
|
||||
|
||||
# Act
|
||||
step_builder.link_to(event_id, edge_builder)
|
||||
|
||||
# Assert
|
||||
assert step_builder.edges[event_id] == [edge_builder]
|
||||
|
||||
|
||||
def test_link_to_multiple_edges():
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
edge_builder_1 = MagicMock(spec=ProcessStepEdgeBuilder)
|
||||
edge_builder_2 = MagicMock(spec=ProcessStepEdgeBuilder)
|
||||
event_id = "event_2"
|
||||
|
||||
# Act
|
||||
step_builder.link_to(event_id, edge_builder_1)
|
||||
step_builder.link_to(event_id, edge_builder_2)
|
||||
|
||||
# Assert
|
||||
assert step_builder.edges[event_id] == [edge_builder_1, edge_builder_2]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"function_name, expected_function_name",
|
||||
[
|
||||
("my_function", "my_function"),
|
||||
(TestFunctionEnum.MY_FUNCTION, TestFunctionEnum.MY_FUNCTION.value),
|
||||
],
|
||||
)
|
||||
def test_on_function_result(function_name, expected_function_name):
|
||||
# Arrange
|
||||
name = "test_step"
|
||||
step_builder = ProcessStepBuilder(name=name)
|
||||
|
||||
# Act
|
||||
edge_builder = step_builder.on_function_result(function_name=function_name)
|
||||
|
||||
# Assert
|
||||
assert isinstance(edge_builder, ProcessStepEdgeBuilder)
|
||||
assert edge_builder.source == step_builder
|
||||
assert edge_builder.event_id == f"{step_builder.event_namespace}.{expected_function_name}.OnResult"
|
||||
Reference in New Issue
Block a user