diff --git a/examples/data_factory/copy_blobs/test_data_factory_copy_blobs_unit.py b/examples/data_factory/copy_blobs/test_data_factory_copy_blobs_unit.py index 6b8feebf..4812556b 100644 --- a/examples/data_factory/copy_blobs/test_data_factory_copy_blobs_unit.py +++ b/examples/data_factory/copy_blobs/test_data_factory_copy_blobs_unit.py @@ -7,6 +7,7 @@ RunParameter, RunParameterType, ) +from data_factory_testing_framework.state._dependency_condition import DependencyCondition @pytest.fixture @@ -61,7 +62,7 @@ def test_for_each(pipeline: Pipeline) -> None: ) state.add_activity_result( activity_name="List Folders", - status="Succeeded", + status=DependencyCondition.SUCCEEDED, output={ "Response": """ diff --git a/examples/synapse/copy_blobs/test_synapse_copy_blobs_unit.py b/examples/synapse/copy_blobs/test_synapse_copy_blobs_unit.py index 4870fd8b..d734dc12 100644 --- a/examples/synapse/copy_blobs/test_synapse_copy_blobs_unit.py +++ b/examples/synapse/copy_blobs/test_synapse_copy_blobs_unit.py @@ -7,6 +7,7 @@ RunParameter, RunParameterType, ) +from data_factory_testing_framework.state._dependency_condition import DependencyCondition @pytest.fixture @@ -61,7 +62,7 @@ def test_for_each(pipeline: Pipeline) -> None: ) state.add_activity_result( activity_name="List Folders", - status="Succeeded", + status=DependencyCondition.SUCCEEDED, output={ "Response": """ diff --git a/src/data_factory_testing_framework/_pythonnet/data_factory_testing_framework_expressions_evaluator.py b/src/data_factory_testing_framework/_pythonnet/data_factory_testing_framework_expressions_evaluator.py index f592f77e..8b29dff7 100644 --- a/src/data_factory_testing_framework/_pythonnet/data_factory_testing_framework_expressions_evaluator.py +++ b/src/data_factory_testing_framework/_pythonnet/data_factory_testing_framework_expressions_evaluator.py @@ -37,16 +37,16 @@ def evaluate(expression: str, state: PipelineRunState) -> Union[str, int, float, activity_results = {} for activity in state.activity_results: - activity_result_dir = { - "outputs": { - "body": { - "output": activity.output, - "status": activity.status, - "error": activity.error, - } - } + output_body = { + k: v + for k, v in { + "error": activity.error, + "output": activity.output, + "status": activity.status.value if activity.status is not None else None, + }.items() + if v is not None } - activity_results[activity.activity_name] = activity_result_dir + activity_results[activity.activity_name] = {"outputs": {"body": output_body}} variables = {variable.name: variable.value for variable in state.variables} diff --git a/src/data_factory_testing_framework/state/_activity_result.py b/src/data_factory_testing_framework/state/_activity_result.py index 5fe96af5..e3b345d8 100644 --- a/src/data_factory_testing_framework/state/_activity_result.py +++ b/src/data_factory_testing_framework/state/_activity_result.py @@ -7,7 +7,7 @@ class ActivityResult: def __init__( self, activity_name: str, - status: Optional[DependencyCondition] = None, + status: Optional[DependencyCondition] = DependencyCondition.SUCCEEDED, output: Optional[Any] = None, # noqa: ANN401 error: Optional[Any] = None, # noqa: ANN401 ) -> None: @@ -20,7 +20,7 @@ def __init__( error: Error of the activity. (e.g. { "code": "ErrorCode", "message": "ErrorMessage" } for activity('activityName').Error) """ self.activity_name = activity_name - self.status = status if status is not None else DependencyCondition.SUCCEEDED + self.status = status self.output = output self.error = error diff --git a/tests/unit/functions/test_data_factory_testing_framework_expression_evaluator.py b/tests/unit/functions/test_data_factory_testing_framework_expression_evaluator.py index 08f59bd8..2cbd061b 100644 --- a/tests/unit/functions/test_data_factory_testing_framework_expression_evaluator.py +++ b/tests/unit/functions/test_data_factory_testing_framework_expression_evaluator.py @@ -446,6 +446,55 @@ def test_evaluate_function_names_are_case_insensitive() -> None: assert evaluated_value == "ab" +@pytest.mark.parametrize( + ["expression", "property_name"], + [ + p( + "@contains(createArray(activity('Fail').status,activity('Notebook').status),'Failed')", + "status", + id="status", + ), + p( + "@contains(createArray(activity('Fail').status,activity('Notebook').error),'Succeeded')", + "error", + id="error", + ), + p( + "@contains(createArray(activity('Fail').status,activity('Notebook').output),'Succeeded')", + "output", + id="output", + ), + ], +) +def test_evaluate_expression_with_none_activity_result_raises_exception( + expression: str, + property_name: str, +) -> None: + # Arrange + expression_runtime = ExpressionRuntime() + state = PipelineRunState( + activity_results=[ + ActivityResult( + activity_name="Fail", + status=DependencyCondition.FAILED, + output={}, + ), + ActivityResult( + activity_name="Notebook", + status=None, + output=None, + error=None, + ), + ] + ) + + # Act & Assert + with pytest.raises(ParameterNotFoundError) as exinfo: + expression_runtime.evaluate(expression, state) + + assert str(exinfo.value) == f"Parameter: '{property_name}' of type 'RunParameterType.System' not found" + + def test_evaluate_function_with_null_conditional_operator() -> None: # Arrange expression = "@pipeline().parameters.parameter.field1?.field2"