44import itertools
55import pathlib
66import typing as t
7- from collections .abc import Iterator
87
98import ruamel
109
11- from sqlmesh .core import constants as c
1210from sqlmesh .utils import unique
1311from sqlmesh .utils .pydantic import PydanticModel
14- from sqlmesh .utils .yaml import load as yaml_load
15-
16- if t .TYPE_CHECKING :
17- from sqlmesh .core .config .loader import C
1812
1913
2014class ModelTestMetadata (PydanticModel ):
@@ -30,61 +24,6 @@ def __hash__(self) -> int:
3024 return self .fully_qualified_test_name .__hash__ ()
3125
3226
33- def load_model_test_file (
34- path : pathlib .Path ,
35- config : C ,
36- get_variables : t .Callable [[t .Optional [C ], t .Optional [str ]], t .Dict [str , str ]],
37- ) -> dict [str , ModelTestMetadata ]:
38- """Load a single model test file.
39-
40- Args:
41- path: The path to the test file
42-
43- returns:
44- A list of ModelTestMetadata named tuples.
45- """
46- model_test_metadata = {}
47- contents = yaml_load (path , config = config , get_variables = get_variables )
48-
49- for test_name , value in contents .items ():
50- model_test_metadata [test_name ] = ModelTestMetadata (
51- path = path , test_name = test_name , body = value
52- )
53- return model_test_metadata
54-
55-
56- def discover_model_tests (
57- path : pathlib .Path ,
58- config : C ,
59- get_variables : t .Callable [[t .Optional [C ], t .Optional [str ]], t .Dict [str , str ]],
60- ) -> Iterator [ModelTestMetadata ]:
61- """Discover model tests.
62-
63- Model tests are defined in YAML files and contain the inputs and outputs used to test model queries.
64-
65- Args:
66- path: A path to search for tests.
67- ignore_patterns: An optional list of patterns to ignore.
68-
69- Returns:
70- A list of ModelTestMetadata named tuples.
71- """
72- search_path = pathlib .Path (path )
73-
74- for yaml_file in itertools .chain (
75- search_path .glob ("**/test*.yaml" ),
76- search_path .glob ("**/test*.yml" ),
77- ):
78- for ignore_pattern in config .ignore_patterns or []:
79- if yaml_file .match (ignore_pattern ):
80- break
81- else :
82- for model_test_metadata in load_model_test_file (
83- yaml_file , config = config , get_variables = get_variables
84- ).values ():
85- yield model_test_metadata
86-
87-
8827def filter_tests_by_patterns (
8928 tests : list [ModelTestMetadata ], patterns : list [str ]
9029) -> list [ModelTestMetadata ]:
@@ -103,47 +42,3 @@ def filter_tests_by_patterns(
10342 if ("*" in pattern and fnmatch .fnmatchcase (test .fully_qualified_test_name , pattern ))
10443 or pattern in test .fully_qualified_test_name
10544 )
106-
107-
108- def load_model_tests (
109- configs : t .Dict [pathlib .Path , C ],
110- get_variables : t .Callable [[t .Optional [C ], t .Optional [str ]], t .Dict [str , str ]],
111- tests : t .Optional [t .List [str ]] = None ,
112- patterns : list [str ] | None = None ,
113- ) -> list [ModelTestMetadata ]:
114- """Load model tests into a list of ModelTestMetadata which will be propagated to the test runner.
115-
116- Args:
117- tests: A list of tests to load; If not specified, all tests are loaded
118- patterns: A list of patterns that'll be used to filter tests by file name.
119- configs: A dictionary of configs to use when loading all the tests.
120- """
121- test_meta = []
122-
123- if tests :
124- for test in tests :
125- filename , test_name = test .split ("::" , maxsplit = 1 ) if "::" in test else (test , "" )
126-
127- test_file = load_model_test_file (
128- pathlib .Path (filename ),
129- config = next (iter (configs .values ())),
130- get_variables = get_variables ,
131- )
132- if test_name :
133- test_meta .append (test_file [test_name ])
134- else :
135- test_meta .extend (test_file .values ())
136- else :
137- for path , config in configs .items ():
138- test_meta .extend (
139- discover_model_tests (
140- pathlib .Path (path / c .TESTS ),
141- config = config ,
142- get_variables = get_variables ,
143- )
144- )
145-
146- if patterns :
147- test_meta = filter_tests_by_patterns (test_meta , patterns )
148-
149- return test_meta
0 commit comments