|
1 | 1 | import pickle |
| 2 | +from abc import abstractmethod |
2 | 3 | from datetime import timedelta |
| 4 | +from typing import Any, Dict |
3 | 5 |
|
4 | 6 | import pytest |
| 7 | +from typing_extensions import override |
5 | 8 |
|
6 | 9 | from dbt.artifacts.resources import ( |
7 | 10 | ExposureType, |
|
23 | 26 | UnparsedMetric, |
24 | 27 | UnparsedMetricInputMeasure, |
25 | 28 | UnparsedMetricTypeParams, |
| 29 | + UnparsedMetricV2, |
26 | 30 | UnparsedModelUpdate, |
27 | 31 | UnparsedNode, |
28 | 32 | UnparsedNodeUpdate, |
@@ -883,9 +887,57 @@ def test_bad_tags(self): |
883 | 887 | self.assert_fails_validation(tst) |
884 | 888 |
|
885 | 889 |
|
886 | | -class TestUnparsedMetric(ContractTestCase): |
| 890 | +class BaseTestUnparsedMetric: |
| 891 | + |
| 892 | + @abstractmethod |
| 893 | + def get_ok_dict(self) -> Dict[str, Any]: |
| 894 | + raise NotImplementedError() |
| 895 | + |
| 896 | + def test_bad_tags(self): |
| 897 | + tst = self.get_ok_dict() |
| 898 | + tst["tags"] = [123] |
| 899 | + self.assert_fails_validation(tst) |
| 900 | + |
| 901 | + def test_bad_metric_name_with_spaces(self): |
| 902 | + tst = self.get_ok_dict() |
| 903 | + tst["name"] = "metric name with spaces" |
| 904 | + self.assert_fails_validation(tst) |
| 905 | + |
| 906 | + def test_bad_metric_name_too_long(self): |
| 907 | + tst = self.get_ok_dict() |
| 908 | + tst["name"] = "a" * 251 |
| 909 | + self.assert_fails_validation(tst) |
| 910 | + |
| 911 | + def test_bad_metric_name_does_not_start_with_letter(self): |
| 912 | + tst = self.get_ok_dict() |
| 913 | + tst["name"] = "123metric" |
| 914 | + self.assert_fails_validation(tst) |
| 915 | + |
| 916 | + tst["name"] = "_metric" |
| 917 | + self.assert_fails_validation(tst) |
| 918 | + |
| 919 | + def test_bad_metric_name_contains_special_characters(self): |
| 920 | + tst = self.get_ok_dict() |
| 921 | + tst["name"] = "metric!name" |
| 922 | + self.assert_fails_validation(tst) |
| 923 | + |
| 924 | + tst["name"] = "metric@name" |
| 925 | + self.assert_fails_validation(tst) |
| 926 | + |
| 927 | + tst["name"] = "metric#name" |
| 928 | + self.assert_fails_validation(tst) |
| 929 | + |
| 930 | + tst["name"] = "metric$name" |
| 931 | + self.assert_fails_validation(tst) |
| 932 | + |
| 933 | + tst["name"] = "metric-name" |
| 934 | + self.assert_fails_validation(tst) |
| 935 | + |
| 936 | + |
| 937 | +class TestUnparsedMetric(BaseTestUnparsedMetric, ContractTestCase): |
887 | 938 | ContractType = UnparsedMetric |
888 | 939 |
|
| 940 | + @override |
889 | 941 | def get_ok_dict(self): |
890 | 942 | return { |
891 | 943 | "name": "new_customers", |
@@ -928,45 +980,42 @@ def test_bad_metric_no_type_params(self): |
928 | 980 | del tst["type_params"] |
929 | 981 | self.assert_fails_validation(tst) |
930 | 982 |
|
931 | | - def test_bad_tags(self): |
932 | | - tst = self.get_ok_dict() |
933 | | - tst["tags"] = [123] |
934 | | - self.assert_fails_validation(tst) |
935 | | - |
936 | | - def test_bad_metric_name_with_spaces(self): |
937 | | - tst = self.get_ok_dict() |
938 | | - tst["name"] = "metric name with spaces" |
939 | | - self.assert_fails_validation(tst) |
940 | | - |
941 | | - def test_bad_metric_name_too_long(self): |
942 | | - tst = self.get_ok_dict() |
943 | | - tst["name"] = "a" * 251 |
944 | | - self.assert_fails_validation(tst) |
945 | 983 |
|
946 | | - def test_bad_metric_name_does_not_start_with_letter(self): |
947 | | - tst = self.get_ok_dict() |
948 | | - tst["name"] = "123metric" |
949 | | - self.assert_fails_validation(tst) |
950 | | - |
951 | | - tst["name"] = "_metric" |
952 | | - self.assert_fails_validation(tst) |
953 | | - |
954 | | - def test_bad_metric_name_contains_special_characters(self): |
955 | | - tst = self.get_ok_dict() |
956 | | - tst["name"] = "metric!name" |
957 | | - self.assert_fails_validation(tst) |
958 | | - |
959 | | - tst["name"] = "metric@name" |
960 | | - self.assert_fails_validation(tst) |
961 | | - |
962 | | - tst["name"] = "metric#name" |
963 | | - self.assert_fails_validation(tst) |
| 984 | +class TestUnparsedMetricV2(BaseTestUnparsedMetric, ContractTestCase): |
| 985 | + ContractType = UnparsedMetricV2 |
964 | 986 |
|
965 | | - tst["name"] = "metric$name" |
966 | | - self.assert_fails_validation(tst) |
| 987 | + @override |
| 988 | + def get_ok_dict(self): |
| 989 | + return { |
| 990 | + "name": "new_customers", |
| 991 | + "label": "New Customers", |
| 992 | + "description": "New customers", |
| 993 | + "type": "simple", |
| 994 | + "agg": "sum", |
| 995 | + "filter": "is_new = true", |
| 996 | + "join_to_timespine": False, |
| 997 | + "config": {}, |
| 998 | + "tags": [], |
| 999 | + "meta": {"is_okr": True}, |
| 1000 | + } |
967 | 1001 |
|
968 | | - tst["name"] = "metric-name" |
969 | | - self.assert_fails_validation(tst) |
| 1002 | + def test_ok(self): |
| 1003 | + metric = self.ContractType( |
| 1004 | + name="new_customers", |
| 1005 | + label="New Customers", |
| 1006 | + description="New customers", |
| 1007 | + agg="sum", |
| 1008 | + filter="is_new = true", |
| 1009 | + join_to_timespine=False, |
| 1010 | + config={}, |
| 1011 | + tags=[], |
| 1012 | + meta={"is_okr": True}, |
| 1013 | + ) |
| 1014 | + dct = self.get_ok_dict() |
| 1015 | + # add defaults: |
| 1016 | + dct["hidden"] = False |
| 1017 | + self.assert_symmetric(metric, dct) |
| 1018 | + pickle.loads(pickle.dumps(metric)) |
970 | 1019 |
|
971 | 1020 |
|
972 | 1021 | class TestUnparsedVersion(ContractTestCase): |
|
0 commit comments