diff --git a/tests/unit/test_contracts_graph_parsed.py b/tests/unit/test_contracts_graph_parsed.py index 498ec5480e1..36f4e96eacf 100644 --- a/tests/unit/test_contracts_graph_parsed.py +++ b/tests/unit/test_contracts_graph_parsed.py @@ -34,6 +34,7 @@ HookNode, Owner, TestMetadata, + SemanticModel, ) from dbt.contracts.graph.unparsed import ( ExposureType, @@ -2354,3 +2355,111 @@ def basic_parsed_metric_object(): meta={}, tags=[], ) + + +# SEMANTIC MODELS + + +@pytest.fixture +def full_parsed_semantic_model_dict(): + return { + # From BaseNode + "name": "full_parsed_semantic_model", + "resource_type": str(NodeType.SemanticModel), + "package_name": "semantic_models", + "path": "a_path", + "original_file_path": "where/it/lived", + "unique_id": "project_name.semantic_models.full_parsed_semantic_model", + # From GraphNode + "fqn": ["project_name", "semantic_models", "full_parsed_semantic_model"], + # From SemanticModel + "model": 'ref("model_name")', + "node_relation": { + "alias": "model_name", + "schema_name": "schema_name", + "database": "database_name", + "relation_name": "database_name.schema_name.model_name", + }, + "description": "a description of what this semantic model represents", + "defaults": {"agg_time_dimension": "a_time_dimension_name"}, + "entities": [ + { + "name": "foreign_entity", + "type": "foreign", + "description": "id of foreign semantic model", + "role": "what is this", + "expr": "foreign_id", + } + ], + "measures": [ + { + "name": "measuring_stuff", + "agg": "count", + "description": "a count of stuff", + "create_metric": True, + "expr": "1", + "agg_params": { + "percentile": 0.5, + "use_discrete_percentile": False, + "use_approximate_percentile": False, + }, + "non_additive_dimension": { + "name": "dimension_name", + "window_choice": "sum", + "window_groupings": ["some", "groupings"], + }, + "agg_time_dimension": "non_default_time_dimension", + } + ], + "dimensions": [ + { + "name": "my_dimension", + "type": "categorical", + "description": "a dimension that denotes a category", + "is_partition": False, + "type_params": { + "time_granularity": "day", + "validity_params": { + "is_start": False, + "is_end": False, + }, + }, + "expr": "column_name", + "metadata": { + "repo_file_path": "where/it/lives/file.yml", + "file_slice": { + "filename": "file.yml", + "content": "raw dimension yaml", + "start_line_number": 25, + "end_line_number": 30, + }, + }, + } + ], + "metadata": { + "repo_file_path": "where/it/lived/file.yml", + "file_slice": { + "filename": "file.yml", + "content": "raw_yaml_object...", + "start_line_number": 15, + "end_line_number": 30, + }, + }, + "depends_on": {"macros": [], "nodes": []}, + "refs": [], + "created_at": 1, + "config": {"enabled": False, "group": "my_group"}, + "unrendered_config": {}, + "primary_entity": "for_some_reason_i_set_this", + "group": "my_group", + } + + +def test_full_parsed_semantic_model(full_parsed_semantic_model_dict): + # check that the object loaded from the dict is symmetric with the original dict + loaded_object = SemanticModel.from_dict(full_parsed_semantic_model_dict) + assert_symmetric(loaded_object, full_parsed_semantic_model_dict, SemanticModel) + assert_from_dict(loaded_object, full_parsed_semantic_model_dict, SemanticModel) + + # check that the loaded_object can be dumped and loaded without error + pickle.loads(pickle.dumps(loaded_object))