From 99d27b0da186ff6fe76a30f908e93ea3f68e0313 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Wed, 17 Jul 2024 15:57:21 -0700 Subject: [PATCH] Write tests for metric_time filters in YAML definitions --- .../metrics.yaml | 34 ++++++++ .../query/test_metric_time_granularity.py | 58 ++++++++++++++ ...h_defined_metric_time_filter__result_0.txt | 76 ++++++++++++++++++ ..._time_filter_on_input_metric__result_0.txt | 80 +++++++++++++++++++ ...h_defined_metric_time_filter__result_0.txt | 76 ++++++++++++++++++ 5 files changed, 324 insertions(+) create mode 100644 metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter__result_0.txt create mode 100644 metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter_on_input_metric__result_0.txt create mode 100644 metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_simple_metric_with_defined_metric_time_filter__result_0.txt diff --git a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/metrics.yaml b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/metrics.yaml index 9c3ebbc576..01fa224f3b 100644 --- a/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/metrics.yaml +++ b/metricflow-semantics/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/metrics.yaml @@ -120,3 +120,37 @@ metric: metrics: - name: simple_metric_with_time_granularity - name: monthly_metric_0 +--- +metric: + name: simple_metric_with_time_granularity_and_metric_time_filter + description: Simple metric with time granularity and metric_time filter + type: simple + type_params: + measure: monthly_measure_1 + time_granularity: quarter + filter: | + {{ TimeDimension('metric_time') }} > '2020-01-01' +--- +metric: + name: derived_metric_with_time_granularity_and_outer_metric_time_filter + description: Derived metric with time granularity + type: derived + time_granularity: year + type_params: + expr: simple_metric_with_time_granularity * 2 + metrics: + - name: simple_metric_with_time_granularity + filter: | + {{ TimeDimension('metric_time') }} > '2020-01-01' +--- +metric: + name: derived_metric_with_time_granularity_and_inner_metric_time_filter + description: Derived metric with time granularity + type: derived + time_granularity: year + type_params: + expr: simple_metric_with_time_granularity_and_metric_time_filter * 2 + metrics: + - name: simple_metric_with_time_granularity_and_metric_time_filter + filter: | + {{ TimeDimension('metric_time') }} = '2020-01-01' diff --git a/metricflow-semantics/tests_metricflow_semantics/query/test_metric_time_granularity.py b/metricflow-semantics/tests_metricflow_semantics/query/test_metric_time_granularity.py index a634b635ea..e1ab2577e3 100644 --- a/metricflow-semantics/tests_metricflow_semantics/query/test_metric_time_granularity.py +++ b/metricflow-semantics/tests_metricflow_semantics/query/test_metric_time_granularity.py @@ -114,3 +114,61 @@ def test_non_metric_time_ignores_default_granularity( # noqa: D103 obj_id="result_0", obj=query_spec, ) + + +def test_simple_metric_with_defined_metric_time_filter( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + ambiguous_resolution_query_parser: MetricFlowQueryParser, +) -> None: + """Tests that a simple metric's metric_time filter defined in its YAML uses metric's default granularity.""" + query_spec = ambiguous_resolution_query_parser.parse_and_validate_query( + metric_names=["simple_metric_with_time_granularity_and_metric_time_filter"] + ).query_spec + + assert_object_snapshot_equal( + request=request, + mf_test_configuration=mf_test_configuration, + obj_id="result_0", + obj=query_spec, + ) + + +def test_derived_metric_with_defined_metric_time_filter( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + ambiguous_resolution_query_parser: MetricFlowQueryParser, +) -> None: + """Tests that a derived metric's metric_time filter defined in its YAML uses outer metric's default granularity.""" + query_spec = ambiguous_resolution_query_parser.parse_and_validate_query( + metric_names=["derived_metric_with_time_granularity_and_outer_metric_time_filter"] + ).query_spec + + assert_object_snapshot_equal( + request=request, + mf_test_configuration=mf_test_configuration, + obj_id="result_0", + obj=query_spec, + ) + + +def test_derived_metric_with_defined_metric_time_filter_on_input_metric( + request: FixtureRequest, + mf_test_configuration: MetricFlowTestConfiguration, + ambiguous_resolution_query_parser: MetricFlowQueryParser, +) -> None: + """Tests a derived metric with a metric_time filter on its input metric. + + Should use the outer metric's default granularity. + Should always use the default granularity for the object where the filter is defined. + """ + query_spec = ambiguous_resolution_query_parser.parse_and_validate_query( + metric_names=["derived_metric_with_time_granularity_and_inner_metric_time_filter"] + ).query_spec + assert 0, "this don't werk" + assert_object_snapshot_equal( + request=request, + mf_test_configuration=mf_test_configuration, + obj_id="result_0", + obj=query_spec, + ) diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter__result_0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter__result_0.txt new file mode 100644 index 0000000000..0d7c697397 --- /dev/null +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter__result_0.txt @@ -0,0 +1,76 @@ +MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name='derived_metric_with_time_granularity_and_outer_metric_time_filter'),), + filter_intersection=PydanticWhereFilterIntersection(), + filter_spec_resolution_lookup=FilterSpecResolutionLookUp( + spec_resolutions=( + FilterSpecResolution( + lookup_key=ResolvedSpecLookUpKey( + filter_location=WhereFilterLocation( + metric_references=( + MetricReference( + element_name='derived_metric_with_time_granularity_and_outer_metric_time_filter', + ), + ), + ), + call_parameter_set=TimeDimensionCallParameterSet( + time_dimension_reference=TimeDimensionReference( + element_name='metric_time', + ), + ), + ), + where_filter_intersection=PydanticWhereFilterIntersection( + where_filters=[ + PydanticWhereFilter( + where_sql_template="{{ TimeDimension('metric_time') }} > '2020-01-01'\n", + ), + ], + ), + resolved_linkable_element_set=LinkableElementSet( + path_key_to_linkable_dimensions={ + ElementPathKey( + element_name='metric_time', + element_type=TIME_DIMENSION, + time_granularity=YEAR, + ): ( + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='monthly_measures_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', + ), + ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=YEAR, + ), + ), + }, + ), + spec_pattern=TimeDimensionPattern( + parameter_set=EntityLinkPatternParameterSet( + fields_to_compare=( + DATE_PART, + ELEMENT_NAME, + ENTITY_LINKS, + ), + element_name='metric_time', + ), + ), + filter_location_path=MetricFlowQueryResolutionPath( + resolution_path_nodes=( + QueryGroupByItemResolutionNode(node_id=qr_1), + MetricGroupByItemResolutionNode(node_id=mtr_1), + ), + ), + object_builder_str="TimeDimension('metric_time')", + ), + ), + ), + min_max_only=False, +) diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter_on_input_metric__result_0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter_on_input_metric__result_0.txt new file mode 100644 index 0000000000..ef462b6c37 --- /dev/null +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_derived_metric_with_defined_metric_time_filter_on_input_metric__result_0.txt @@ -0,0 +1,80 @@ +MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name='derived_metric_with_time_granularity_and_inner_metric_time_filter'),), + filter_intersection=PydanticWhereFilterIntersection(), + filter_spec_resolution_lookup=FilterSpecResolutionLookUp( + spec_resolutions=( + FilterSpecResolution( + lookup_key=ResolvedSpecLookUpKey( + filter_location=WhereFilterLocation( + metric_references=( + MetricReference( + element_name='simple_metric_with_time_granularity_and_metric_time_filter', + ), + ), + ), + call_parameter_set=TimeDimensionCallParameterSet( + time_dimension_reference=TimeDimensionReference( + element_name='metric_time', + ), + ), + ), + where_filter_intersection=PydanticWhereFilterIntersection( + where_filters=[ + PydanticWhereFilter( + where_sql_template="{{ TimeDimension('metric_time') }} > '2020-01-01'\n", + ), + PydanticWhereFilter( + where_sql_template="{{ TimeDimension('metric_time') }} = '2020-01-01'", + ), + ], + ), + resolved_linkable_element_set=LinkableElementSet( + path_key_to_linkable_dimensions={ + ElementPathKey( + element_name='metric_time', + element_type=TIME_DIMENSION, + time_granularity=QUARTER, + ): ( + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='monthly_measures_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', + ), + ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=QUARTER, + ), + ), + }, + ), + spec_pattern=TimeDimensionPattern( + parameter_set=EntityLinkPatternParameterSet( + fields_to_compare=( + DATE_PART, + ELEMENT_NAME, + ENTITY_LINKS, + ), + element_name='metric_time', + ), + ), + filter_location_path=MetricFlowQueryResolutionPath( + resolution_path_nodes=( + QueryGroupByItemResolutionNode(node_id=qr_1), + MetricGroupByItemResolutionNode(node_id=mtr_1), + MetricGroupByItemResolutionNode(node_id=mtr_0), + ), + ), + object_builder_str="TimeDimension('metric_time')", + ), + ), + ), + min_max_only=False, +) diff --git a/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_simple_metric_with_defined_metric_time_filter__result_0.txt b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_simple_metric_with_defined_metric_time_filter__result_0.txt new file mode 100644 index 0000000000..5c127c3435 --- /dev/null +++ b/metricflow-semantics/tests_metricflow_semantics/snapshots/test_metric_time_granularity.py/MetricFlowQuerySpec/test_simple_metric_with_defined_metric_time_filter__result_0.txt @@ -0,0 +1,76 @@ +MetricFlowQuerySpec( + metric_specs=(MetricSpec(element_name='simple_metric_with_time_granularity_and_metric_time_filter'),), + filter_intersection=PydanticWhereFilterIntersection(), + filter_spec_resolution_lookup=FilterSpecResolutionLookUp( + spec_resolutions=( + FilterSpecResolution( + lookup_key=ResolvedSpecLookUpKey( + filter_location=WhereFilterLocation( + metric_references=( + MetricReference( + element_name='simple_metric_with_time_granularity_and_metric_time_filter', + ), + ), + ), + call_parameter_set=TimeDimensionCallParameterSet( + time_dimension_reference=TimeDimensionReference( + element_name='metric_time', + ), + ), + ), + where_filter_intersection=PydanticWhereFilterIntersection( + where_filters=[ + PydanticWhereFilter( + where_sql_template="{{ TimeDimension('metric_time') }} > '2020-01-01'\n", + ), + ], + ), + resolved_linkable_element_set=LinkableElementSet( + path_key_to_linkable_dimensions={ + ElementPathKey( + element_name='metric_time', + element_type=TIME_DIMENSION, + time_granularity=QUARTER, + ): ( + LinkableDimension( + defined_in_semantic_model=SemanticModelReference( + semantic_model_name='monthly_measures_source', + ), + element_name='metric_time', + dimension_type=TIME, + join_path=SemanticModelJoinPath( + left_semantic_model_reference=SemanticModelReference( + semantic_model_name='monthly_measures_source', + ), + ), + properties=frozenset( + 'DERIVED_TIME_GRANULARITY', + 'METRIC_TIME', + ), + time_granularity=QUARTER, + ), + ), + }, + ), + spec_pattern=TimeDimensionPattern( + parameter_set=EntityLinkPatternParameterSet( + fields_to_compare=( + DATE_PART, + ELEMENT_NAME, + ENTITY_LINKS, + ), + element_name='metric_time', + ), + ), + filter_location_path=MetricFlowQueryResolutionPath( + resolution_path_nodes=( + QueryGroupByItemResolutionNode(node_id=qr_1), + MetricGroupByItemResolutionNode(node_id=mtr_0), + ), + ), + object_builder_str="TimeDimension('metric_time')", + ), + ), + ), + min_max_only=False, +)