Skip to content

Commit

Permalink
feat: support null-conditional operator (#147)
Browse files Browse the repository at this point in the history
  • Loading branch information
arjendev authored Dec 13, 2024
1 parent e85fc19 commit 907f356
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self) -> None:

expression_grammar = f"""
expression_start: "@" expression_evaluation
expression_evaluation: (expression_logical_bool | expression_branch | expression_call) ((("." EXPRESSION_PARAMETER_NAME) | EXPRESSION_ARRAY_INDEX)+)? EXPRESSION_WS*
expression_evaluation: (expression_logical_bool | expression_branch | expression_call) ((EXPRESSION_NULL_CONDITIONAL_OPERATOR? (expression_field_reference | EXPRESSION_ARRAY_INDEX))+)? EXPRESSION_WS*
?expression_call: expression_function_call
// used to translate to expression_pipeline_reference
| expression_datafactory_parameters_reference
Expand All @@ -55,9 +55,8 @@ def __init__(self) -> None:
expression_datafactory_parameters_reference: EXPRESSION_DATAFACTORY_REFERENCE "()"
expression_datafactory_activity_reference: "activity" "(" EXPRESSION_ACTIVITY_NAME ")"
expression_item_reference: "item" "()"
expression_pipeline_reference: "pipeline" "()" "." EXPRESSION_PIPELINE_PROPERTY
expression_pipeline_reference: "pipeline" "()" EXPRESSION_NULL_CONDITIONAL_OPERATOR? "." EXPRESSION_PIPELINE_PROPERTY
expression_field_reference: "." EXPRESSION_PARAMETER_NAME
// branch rules
expression_logical_bool: EXPRESSION_LOGICAL_BOOL "(" expression_parameter "," expression_parameter ")"
Expand All @@ -83,6 +82,7 @@ def __init__(self) -> None:
EXPRESSION_STRING: SINGLE_QUOTED_STRING
EXPRESSION_SYSTEM_VARIABLE_NAME: /[a-zA-Z0-9_]+/
EXPRESSION_VARIABLE_NAME: "'" /[^']*/ "'"
EXPRESSION_NULL_CONDITIONAL_OPERATOR: "?"
EXPRESSION_WS: WS
""" # noqa: E501

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,65 @@ def test_evaluate_function_names_are_case_insensitive() -> None:
assert evaluated_value == "ab"


def test_evaluate_function_with_null_conditional_operator() -> None:
# Arrange
expression = "@pipeline().parameters.parameter.field1?.field2"
expression_runtime = ExpressionRuntime()
state = PipelineRunState(
parameters=[
RunParameter(
RunParameterType.Pipeline,
"parameter",
{
"field1": {"field2": "value1"},
},
),
]
)

# Act
evaluated_value = expression_runtime.evaluate(expression, state)

# Assert
assert evaluated_value == "value1"


def test_evaluate_function_with_null_conditional_operator_and_null_value() -> None:
# Arrange
expression = "@pipeline().parameters.parameter?.field1?.field2"
expression_runtime = ExpressionRuntime()
state = PipelineRunState(
parameters=[
RunParameter(
RunParameterType.Pipeline,
"parameter",
{
"field1": None,
},
),
]
)

# Act
evaluated_value = expression_runtime.evaluate(expression, state)

# Assert
assert evaluated_value is None


def test_evaluate_function_with_null_conditional_operator_and_system_variable() -> None:
# Arrange
expression = "@pipeline()?.TriggeredByPipelineRunId"
expression_runtime = ExpressionRuntime()
state = PipelineRunState()

# Act
evaluated_value = expression_runtime.evaluate(expression, state)

# Assert
assert evaluated_value is None


def test_evaluate_parameter_with_complex_object_and_array_index() -> None:
# Arrange
expression = "@pipeline().parameters.parameter[0].field1.field2"
Expand Down

0 comments on commit 907f356

Please sign in to comment.