recce-nightly 0.62.0.20250417__py3-none-any.whl → 1.30.0.20251221__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of recce-nightly might be problematic. Click here for more details.
- recce/VERSION +1 -1
- recce/__init__.py +27 -22
- recce/adapter/base.py +11 -14
- recce/adapter/dbt_adapter/__init__.py +845 -461
- recce/adapter/dbt_adapter/dbt_version.py +3 -0
- recce/adapter/sqlmesh_adapter.py +24 -35
- recce/apis/check_api.py +59 -42
- recce/apis/check_events_api.py +353 -0
- recce/apis/check_func.py +41 -35
- recce/apis/run_api.py +25 -19
- recce/apis/run_func.py +64 -25
- recce/artifact.py +119 -51
- recce/cli.py +1301 -324
- recce/config.py +43 -34
- recce/connect_to_cloud.py +138 -0
- recce/core.py +55 -47
- recce/data/404/index.html +2 -0
- recce/data/404.html +2 -1
- recce/data/__next.@lineage.!KHNsb3Qp.__PAGE__.txt +7 -0
- recce/data/__next.@lineage.!KHNsb3Qp.txt +4 -0
- recce/data/__next.__PAGE__.txt +6 -0
- recce/data/__next._full.txt +32 -0
- recce/data/__next._head.txt +8 -0
- recce/data/__next._index.txt +14 -0
- recce/data/__next._tree.txt +8 -0
- recce/data/_next/static/chunks/025a7e3e3f9f40ae.js +1 -0
- recce/data/_next/static/chunks/0ce56d67ef5779ca.js +4 -0
- recce/data/_next/static/chunks/1a6a78780155dac7.js +48 -0
- recce/data/_next/static/chunks/1de8485918b9182a.css +2 -0
- recce/data/_next/static/chunks/1e4b1b50d1e34993.js +1 -0
- recce/data/_next/static/chunks/206d5d181e4c738e.js +1 -0
- recce/data/_next/static/chunks/2c357efc34c5b859.js +25 -0
- recce/data/_next/static/chunks/2e9d95d2d48c479c.js +1 -0
- recce/data/_next/static/chunks/2f016dc4a3edad2e.js +2 -0
- recce/data/_next/static/chunks/313251962d698f7c.js +1 -0
- recce/data/_next/static/chunks/3a9f021f38eb5574.css +1 -0
- recce/data/_next/static/chunks/40079da8d2b8f651.js +1 -0
- recce/data/_next/static/chunks/4599182bffb64661.js +38 -0
- recce/data/_next/static/chunks/4e62f6e184173580.js +1 -0
- recce/data/_next/static/chunks/5c4dfb0d09eaa401.js +1 -0
- recce/data/_next/static/chunks/69e4f06ccfdfc3ac.js +1 -0
- recce/data/_next/static/chunks/6b206cb4707d6bee.js +1 -0
- recce/data/_next/static/chunks/6d8557f062aa4386.css +1 -0
- recce/data/_next/static/chunks/7fbe3650bd83b6b5.js +1 -0
- recce/data/_next/static/chunks/83fa823a825674f6.js +1 -0
- recce/data/_next/static/chunks/848a6c9b5f55f7ed.js +1 -0
- recce/data/_next/static/chunks/859462b0858aef88.css +2 -0
- recce/data/_next/static/chunks/923964f18c87d0f1.css +1 -0
- recce/data/_next/static/chunks/939390f911895d7c.js +48 -0
- recce/data/_next/static/chunks/99a9817237a07f43.js +1 -0
- recce/data/_next/static/chunks/9fed8b4b2b924054.js +5 -0
- recce/data/_next/static/chunks/b6949f6c5892110c.js +1 -0
- recce/data/_next/static/chunks/b851a1d3f8149828.js +1 -0
- recce/data/_next/static/chunks/c734f9ad957de0b4.js +1 -0
- recce/data/_next/static/chunks/cdde321b0ec75717.js +2 -0
- recce/data/_next/static/chunks/d0f91117d77ff844.css +1 -0
- recce/data/_next/static/chunks/d6c8667911c2500f.js +1 -0
- recce/data/_next/static/chunks/da8dab68c02752cf.js +74 -0
- recce/data/_next/static/chunks/dc074049c9d12d97.js +109 -0
- recce/data/_next/static/chunks/ee7f1a8227342421.js +1 -0
- recce/data/_next/static/chunks/fa2f4e56c2fccc73.js +1 -0
- recce/data/_next/static/chunks/turbopack-1fad664f62979b93.js +3 -0
- recce/data/_next/static/media/favicon.a8d38d84.ico +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.d80d830d.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.f9d58125.woff +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.076c2a93.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.a4fa76b5.woff +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.cde454cc.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.d5761935.woff +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.40ec0659.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.b671449b.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.9f7b8541.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.f9eb854e.woff2 +0 -0
- recce/data/_next/static/nX-Uz0AH6Tc6hIQUFGqaB/_buildManifest.js +11 -0
- recce/data/_next/static/nX-Uz0AH6Tc6hIQUFGqaB/_clientMiddlewareManifest.json +1 -0
- recce/data/_not-found/__next._full.txt +24 -0
- recce/data/_not-found/__next._head.txt +8 -0
- recce/data/_not-found/__next._index.txt +13 -0
- recce/data/_not-found/__next._not-found.__PAGE__.txt +5 -0
- recce/data/_not-found/__next._not-found.txt +4 -0
- recce/data/_not-found/__next._tree.txt +6 -0
- recce/data/_not-found/index.html +2 -0
- recce/data/_not-found/index.txt +24 -0
- recce/data/auth_callback.html +68 -0
- recce/data/checks/__next.@lineage.__DEFAULT__.txt +7 -0
- recce/data/checks/__next._full.txt +39 -0
- recce/data/checks/__next._head.txt +8 -0
- recce/data/checks/__next._index.txt +14 -0
- recce/data/checks/__next._tree.txt +8 -0
- recce/data/checks/__next.checks.__PAGE__.txt +10 -0
- recce/data/checks/__next.checks.txt +4 -0
- recce/data/checks/index.html +2 -0
- recce/data/checks/index.txt +39 -0
- recce/data/imgs/reload-image.svg +4 -0
- recce/data/index.html +2 -27
- recce/data/index.txt +32 -7
- recce/data/lineage/__next.@lineage.__DEFAULT__.txt +7 -0
- recce/data/lineage/__next._full.txt +39 -0
- recce/data/lineage/__next._head.txt +8 -0
- recce/data/lineage/__next._index.txt +14 -0
- recce/data/lineage/__next._tree.txt +8 -0
- recce/data/lineage/__next.lineage.__PAGE__.txt +10 -0
- recce/data/lineage/__next.lineage.txt +4 -0
- recce/data/lineage/index.html +2 -0
- recce/data/lineage/index.txt +39 -0
- recce/data/query/__next.@lineage.__DEFAULT__.txt +7 -0
- recce/data/query/__next._full.txt +37 -0
- recce/data/query/__next._head.txt +8 -0
- recce/data/query/__next._index.txt +14 -0
- recce/data/query/__next._tree.txt +8 -0
- recce/data/query/__next.query.__PAGE__.txt +9 -0
- recce/data/query/__next.query.txt +4 -0
- recce/data/query/index.html +2 -0
- recce/data/query/index.txt +37 -0
- recce/diff.py +6 -12
- recce/event/CONFIG.bak +1 -0
- recce/event/__init__.py +86 -74
- recce/event/collector.py +33 -22
- recce/event/track.py +49 -27
- recce/exceptions.py +1 -1
- recce/git.py +7 -7
- recce/github.py +57 -53
- recce/mcp_server.py +725 -0
- recce/models/__init__.py +4 -1
- recce/models/check.py +438 -21
- recce/models/run.py +1 -0
- recce/models/types.py +134 -28
- recce/pull_request.py +27 -25
- recce/run.py +179 -122
- recce/server.py +394 -104
- recce/state/__init__.py +31 -0
- recce/state/cloud.py +644 -0
- recce/state/const.py +26 -0
- recce/state/local.py +56 -0
- recce/state/state.py +119 -0
- recce/state/state_loader.py +174 -0
- recce/summary.py +196 -149
- recce/tasks/__init__.py +19 -3
- recce/tasks/core.py +11 -13
- recce/tasks/dataframe.py +82 -18
- recce/tasks/histogram.py +69 -34
- recce/tasks/lineage.py +2 -2
- recce/tasks/profile.py +152 -86
- recce/tasks/query.py +180 -89
- recce/tasks/rowcount.py +37 -31
- recce/tasks/schema.py +18 -15
- recce/tasks/top_k.py +35 -35
- recce/tasks/utils.py +147 -0
- recce/tasks/valuediff.py +247 -155
- recce/util/__init__.py +3 -0
- recce/util/api_token.py +80 -0
- recce/util/breaking.py +105 -100
- recce/util/cll.py +274 -219
- recce/util/cloud/__init__.py +15 -0
- recce/util/cloud/base.py +115 -0
- recce/util/cloud/check_events.py +190 -0
- recce/util/cloud/checks.py +242 -0
- recce/util/io.py +22 -17
- recce/util/lineage.py +65 -16
- recce/util/logger.py +1 -1
- recce/util/onboarding_state.py +45 -0
- recce/util/perf_tracking.py +85 -0
- recce/util/recce_cloud.py +347 -72
- recce/util/singleton.py +4 -4
- recce/util/startup_perf.py +121 -0
- recce/yaml/__init__.py +7 -10
- recce_nightly-1.30.0.20251221.dist-info/METADATA +195 -0
- recce_nightly-1.30.0.20251221.dist-info/RECORD +183 -0
- {recce_nightly-0.62.0.20250417.dist-info → recce_nightly-1.30.0.20251221.dist-info}/WHEEL +1 -2
- recce/data/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js +0 -1
- recce/data/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js +0 -1
- recce/data/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js +0 -1
- recce/data/_next/static/chunks/3998a672-eaad84bdd88cc73e.js +0 -1
- recce/data/_next/static/chunks/450c323b-1bb5db526e54435a.js +0 -1
- recce/data/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js +0 -1
- recce/data/_next/static/chunks/500-e51c92a025a51234.js +0 -65
- recce/data/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js +0 -1
- recce/data/_next/static/chunks/700-3b65fc3666820d00.js +0 -2
- recce/data/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js +0 -1
- recce/data/_next/static/chunks/7f27ae6c-413f6b869a04183a.js +0 -1
- recce/data/_next/static/chunks/9746af58-d74bef4d03eea6ab.js +0 -1
- recce/data/_next/static/chunks/a30376cd-7d806e1602f2dc3a.js +0 -1
- recce/data/_next/static/chunks/app/_not-found/page-8a886fa0855c3105.js +0 -1
- recce/data/_next/static/chunks/app/layout-9102e22cb73f74d6.js +0 -1
- recce/data/_next/static/chunks/app/page-9adc25782272ed2e.js +0 -1
- recce/data/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js +0 -1
- recce/data/_next/static/chunks/c132bf7d-8102037f9ccf372a.js +0 -1
- recce/data/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js +0 -1
- recce/data/_next/static/chunks/cd9f8d63-cf0d5a7b0f7a92e8.js +0 -54
- recce/data/_next/static/chunks/ce84277d-f42c2c58049cea2d.js +0 -1
- recce/data/_next/static/chunks/e24bf851-0f8cbc99656833e7.js +0 -1
- recce/data/_next/static/chunks/fee69bc6-f17d36c080742e74.js +0 -1
- recce/data/_next/static/chunks/framework-ded83d71b51ce901.js +0 -1
- recce/data/_next/static/chunks/main-a0859f1f36d0aa6c.js +0 -1
- recce/data/_next/static/chunks/main-app-0225a2255968e566.js +0 -1
- recce/data/_next/static/chunks/pages/_app-d5672bf3d8b6371b.js +0 -1
- recce/data/_next/static/chunks/pages/_error-ed75be3f25588548.js +0 -1
- recce/data/_next/static/chunks/webpack-567d72f0bc0820d5.js +0 -1
- recce/data/_next/static/css/c9ecb46a4b21c126.css +0 -14
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.94a63aea.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.6f8fa298.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.97e20d5e.woff +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.aff52ab0.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.5f21869b.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2 +0 -0
- recce/data/_next/static/qiyFlux77VkhxiceAJe_F/_buildManifest.js +0 -1
- recce/state.py +0 -753
- recce_nightly-0.62.0.20250417.dist-info/METADATA +0 -311
- recce_nightly-0.62.0.20250417.dist-info/RECORD +0 -139
- recce_nightly-0.62.0.20250417.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- tests/adapter/__init__.py +0 -0
- tests/adapter/dbt_adapter/__init__.py +0 -0
- tests/adapter/dbt_adapter/conftest.py +0 -13
- tests/adapter/dbt_adapter/dbt_test_helper.py +0 -283
- tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -40
- tests/adapter/dbt_adapter/test_dbt_cll.py +0 -102
- tests/adapter/dbt_adapter/test_selector.py +0 -177
- tests/tasks/__init__.py +0 -0
- tests/tasks/conftest.py +0 -4
- tests/tasks/test_histogram.py +0 -137
- tests/tasks/test_lineage.py +0 -42
- tests/tasks/test_preset_checks.py +0 -50
- tests/tasks/test_profile.py +0 -73
- tests/tasks/test_query.py +0 -151
- tests/tasks/test_row_count.py +0 -116
- tests/tasks/test_schema.py +0 -99
- tests/tasks/test_top_k.py +0 -73
- tests/tasks/test_valuediff.py +0 -74
- tests/test_cli.py +0 -122
- tests/test_config.py +0 -45
- tests/test_core.py +0 -27
- tests/test_dbt.py +0 -36
- tests/test_pull_request.py +0 -130
- tests/test_server.py +0 -98
- tests/test_state.py +0 -123
- tests/test_summary.py +0 -57
- /recce/data/_next/static/chunks/{polyfills-42372ed130431b0a.js → a6dad97d9634a72d.js} +0 -0
- /recce/data/_next/static/{qiyFlux77VkhxiceAJe_F → nX-Uz0AH6Tc6hIQUFGqaB}/_ssgManifest.js +0 -0
- {recce_nightly-0.62.0.20250417.dist-info → recce_nightly-1.30.0.20251221.dist-info}/entry_points.txt +0 -0
- {recce_nightly-0.62.0.20250417.dist-info → recce_nightly-1.30.0.20251221.dist-info}/licenses/LICENSE +0 -0
tests/tasks/test_histogram.py
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from recce.tasks.histogram import HistogramDiffTask, HistogramDiffCheckValidator, _is_histogram_supported
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test_histogram(dbt_test_helper):
|
|
7
|
-
csv_data = """
|
|
8
|
-
customer_id,name,age
|
|
9
|
-
1,Alice,30
|
|
10
|
-
2,Bob,25
|
|
11
|
-
3,Charlie,35
|
|
12
|
-
4,Dolly,50
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
dbt_test_helper.create_model("customers", csv_data, csv_data)
|
|
16
|
-
|
|
17
|
-
params = {
|
|
18
|
-
"model": "customers",
|
|
19
|
-
"column_name": "age",
|
|
20
|
-
"column_type": "int"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
task = HistogramDiffTask(params)
|
|
24
|
-
run_result = task.execute()
|
|
25
|
-
|
|
26
|
-
# {
|
|
27
|
-
# 'base': {'counts': [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 'total': 4},
|
|
28
|
-
# 'current': {'counts': [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 'total': 4},
|
|
29
|
-
# 'min': 25, 'max': 50,
|
|
30
|
-
# 'bin_edges': [25, 26, ..., 51],
|
|
31
|
-
# 'labels': ['25-26', ..., '51-52']
|
|
32
|
-
# }
|
|
33
|
-
assert run_result['current']['counts'][0] == 1
|
|
34
|
-
assert run_result['current']['counts'][-1] == 1
|
|
35
|
-
assert run_result['current']['total'] == 4
|
|
36
|
-
assert run_result['min'] == 25
|
|
37
|
-
assert run_result['max'] == 50
|
|
38
|
-
assert run_result['bin_edges'][0] == 25
|
|
39
|
-
assert run_result['bin_edges'][-1] == 51
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def test_histogram_emtpy(dbt_test_helper):
|
|
43
|
-
csv_data = """
|
|
44
|
-
customer_id,name,age
|
|
45
|
-
1,Alice,30
|
|
46
|
-
2,Bob,25
|
|
47
|
-
3,Charlie,35
|
|
48
|
-
4,Dolly,50
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
csv_data_zero = """
|
|
52
|
-
customer_id,name,age
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
dbt_test_helper.create_model("customers", csv_data_zero, csv_data_zero)
|
|
56
|
-
dbt_test_helper.create_model("customers2", csv_data, csv_data_zero)
|
|
57
|
-
dbt_test_helper.create_model("customers3", csv_data_zero, csv_data)
|
|
58
|
-
|
|
59
|
-
params = {
|
|
60
|
-
"model": "customers",
|
|
61
|
-
"column_name": "age",
|
|
62
|
-
"column_type": "int"
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
task = HistogramDiffTask(params)
|
|
66
|
-
run_result = task.execute()
|
|
67
|
-
|
|
68
|
-
assert len(run_result['current']['counts']) == 0
|
|
69
|
-
assert run_result['current']['total'] == 0
|
|
70
|
-
assert run_result['min'] is None
|
|
71
|
-
assert run_result['max'] is None
|
|
72
|
-
assert len(run_result['bin_edges']) == 0
|
|
73
|
-
|
|
74
|
-
params = {
|
|
75
|
-
"model": "customers2",
|
|
76
|
-
"column_name": "age",
|
|
77
|
-
"column_type": "int"
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
task = HistogramDiffTask(params)
|
|
81
|
-
run_result = task.execute()
|
|
82
|
-
assert run_result['base']['counts'][0] == 1
|
|
83
|
-
assert run_result['base']['counts'][-1] == 1
|
|
84
|
-
assert run_result['base']['total'] == 4
|
|
85
|
-
assert run_result['current']['counts'][0] == 0
|
|
86
|
-
assert run_result['current']['counts'][-1] == 0
|
|
87
|
-
assert run_result['current']['total'] == 0
|
|
88
|
-
assert run_result['min'] == 25
|
|
89
|
-
assert run_result['max'] == 50
|
|
90
|
-
assert run_result['bin_edges'][0] == 25
|
|
91
|
-
assert run_result['bin_edges'][-1] == 51
|
|
92
|
-
|
|
93
|
-
params = {
|
|
94
|
-
"model": "customers3",
|
|
95
|
-
"column_name": "age",
|
|
96
|
-
"column_type": "int"
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
task = HistogramDiffTask(params)
|
|
100
|
-
run_result = task.execute()
|
|
101
|
-
assert run_result['base']['counts'][0] == 0
|
|
102
|
-
assert run_result['base']['counts'][-1] == 0
|
|
103
|
-
assert run_result['base']['total'] == 0
|
|
104
|
-
assert run_result['current']['counts'][0] == 1
|
|
105
|
-
assert run_result['current']['counts'][-1] == 1
|
|
106
|
-
assert run_result['current']['total'] == 4
|
|
107
|
-
assert run_result['min'] == 25
|
|
108
|
-
assert run_result['max'] == 50
|
|
109
|
-
assert run_result['bin_edges'][0] == 25
|
|
110
|
-
assert run_result['bin_edges'][-1] == 51
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def test_validator():
|
|
114
|
-
def validate(params: dict = {}, view_options: dict = {}):
|
|
115
|
-
HistogramDiffCheckValidator().validate({
|
|
116
|
-
'name': 'test',
|
|
117
|
-
'type': 'histogram_diff',
|
|
118
|
-
'params': params,
|
|
119
|
-
'view_options': view_options,
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
validate({
|
|
123
|
-
"model": "customers",
|
|
124
|
-
"column_name": "age",
|
|
125
|
-
"column_type": "int",
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
with pytest.raises(ValueError):
|
|
129
|
-
validate({})
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def test_is_column_type_supported_by_histogram():
|
|
133
|
-
assert _is_histogram_supported("varchar") is False
|
|
134
|
-
assert _is_histogram_supported("varchar(16)") is False
|
|
135
|
-
assert _is_histogram_supported("varchar(256)") is False
|
|
136
|
-
assert _is_histogram_supported("bool") is False
|
|
137
|
-
assert _is_histogram_supported("int") is True
|
tests/tasks/test_lineage.py
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_validator():
|
|
5
|
-
from recce.tasks.lineage import LineageDiffCheckValidator
|
|
6
|
-
validator = LineageDiffCheckValidator()
|
|
7
|
-
|
|
8
|
-
def validate(params: dict):
|
|
9
|
-
validator.validate({
|
|
10
|
-
'name': 'test',
|
|
11
|
-
'type': 'schema_diff',
|
|
12
|
-
'params': params,
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
# Select all models
|
|
16
|
-
validate({})
|
|
17
|
-
|
|
18
|
-
# Select by selector
|
|
19
|
-
validate({
|
|
20
|
-
'select': 'customers',
|
|
21
|
-
'exclude': 'customers',
|
|
22
|
-
'packages': ['jaffle_shop'],
|
|
23
|
-
'view_mode': 'all',
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
# packages should be an array
|
|
27
|
-
with pytest.raises(ValueError):
|
|
28
|
-
validate({
|
|
29
|
-
'packages': 'jaffle_shop',
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
# view_mode should be 'all' or 'changed_models'
|
|
33
|
-
validate({
|
|
34
|
-
'view_mode': None,
|
|
35
|
-
})
|
|
36
|
-
validate({
|
|
37
|
-
'view_mode': 'all',
|
|
38
|
-
})
|
|
39
|
-
with pytest.raises(ValueError):
|
|
40
|
-
validate({
|
|
41
|
-
'view_mode': 'abc',
|
|
42
|
-
})
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_default_validator():
|
|
5
|
-
from recce.tasks.core import CheckValidator
|
|
6
|
-
|
|
7
|
-
CheckValidator().validate({
|
|
8
|
-
"name": "test",
|
|
9
|
-
"type": "row_count_diff",
|
|
10
|
-
"params": {},
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
with pytest.raises(ValueError):
|
|
14
|
-
CheckValidator().validate({
|
|
15
|
-
"type": "row_count_diff",
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def test_query_diff_validator():
|
|
20
|
-
from recce.tasks.query import QueryDiffCheckValidator
|
|
21
|
-
QueryDiffCheckValidator().validate({
|
|
22
|
-
"name": "test",
|
|
23
|
-
"type": "query_diff",
|
|
24
|
-
"params": {
|
|
25
|
-
"sql_template": "select * from {{ model }}"
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
with pytest.raises(ValueError):
|
|
29
|
-
QueryDiffCheckValidator().validate({
|
|
30
|
-
"name": "test",
|
|
31
|
-
"type": "query_diff",
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def test_lineage_diff_validator():
|
|
36
|
-
from recce.tasks.lineage import LineageDiffCheckValidator
|
|
37
|
-
LineageDiffCheckValidator().validate({
|
|
38
|
-
"name": "test",
|
|
39
|
-
"type": "lineage_diff",
|
|
40
|
-
"params": {},
|
|
41
|
-
})
|
|
42
|
-
LineageDiffCheckValidator().validate({
|
|
43
|
-
"name": "test",
|
|
44
|
-
"type": "lineage_diff",
|
|
45
|
-
"view_options": {},
|
|
46
|
-
})
|
|
47
|
-
with pytest.raises(ValueError):
|
|
48
|
-
LineageDiffCheckValidator().validate({
|
|
49
|
-
"type": "lineage_diff",
|
|
50
|
-
})
|
tests/tasks/test_profile.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from recce.tasks import ProfileDiffTask, ProfileTask
|
|
4
|
-
|
|
5
|
-
csv_data_curr = """
|
|
6
|
-
customer_id,name,age
|
|
7
|
-
1,Alice,30
|
|
8
|
-
2,Bob,25
|
|
9
|
-
3,Charlie,35
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
csv_data_base = """
|
|
13
|
-
customer_id,name,age
|
|
14
|
-
1,Alice,35
|
|
15
|
-
2,Bob,25
|
|
16
|
-
3,Charlie,35
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def test_profile(dbt_test_helper):
|
|
21
|
-
dbt_test_helper.create_model("customers", None, csv_data_curr)
|
|
22
|
-
params = dict(model='customers')
|
|
23
|
-
task = ProfileTask(params)
|
|
24
|
-
run_result = task.execute()
|
|
25
|
-
|
|
26
|
-
assert len(run_result.current.data) == 3
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def test_profile_with_selected_columns(dbt_test_helper):
|
|
30
|
-
dbt_test_helper.create_model("customers", None, csv_data_curr)
|
|
31
|
-
params = dict(model='customers', columns=['name', 'age'])
|
|
32
|
-
task = ProfileTask(params)
|
|
33
|
-
run_result = task.execute()
|
|
34
|
-
assert len(run_result.current.data) == 2
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_profile_diff(dbt_test_helper):
|
|
38
|
-
dbt_test_helper.create_model("customers", csv_data_base, csv_data_curr)
|
|
39
|
-
params = dict(model='customers')
|
|
40
|
-
task = ProfileDiffTask(params)
|
|
41
|
-
run_result = task.execute()
|
|
42
|
-
|
|
43
|
-
assert len(run_result.current.data) == 3
|
|
44
|
-
assert len(run_result.base.data) == 3
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def test_profile_diff_with_selected_columns(dbt_test_helper):
|
|
48
|
-
dbt_test_helper.create_model("customers", csv_data_base, csv_data_curr)
|
|
49
|
-
params = dict(model='customers', columns=['name', 'age'])
|
|
50
|
-
task = ProfileDiffTask(params)
|
|
51
|
-
run_result = task.execute()
|
|
52
|
-
assert len(run_result.current.data) == 2
|
|
53
|
-
assert len(run_result.base.data) == 2
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def test_validator():
|
|
57
|
-
from recce.tasks.profile import ProfileCheckValidator
|
|
58
|
-
|
|
59
|
-
def validate(params: dict = {}, view_options: dict = {}):
|
|
60
|
-
ProfileCheckValidator().validate({
|
|
61
|
-
'name': 'test',
|
|
62
|
-
'type': 'profile_diff',
|
|
63
|
-
'params': params,
|
|
64
|
-
'view_options': view_options,
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
validate({
|
|
68
|
-
'model': 'customers',
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
with pytest.raises(ValueError):
|
|
72
|
-
validate({
|
|
73
|
-
})
|
tests/tasks/test_query.py
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from recce.tasks import QueryDiffTask, QueryTask
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test_query_diff_in_client(dbt_test_helper):
|
|
7
|
-
csv_data_curr = """
|
|
8
|
-
customer_id,name,age
|
|
9
|
-
1,Alice,30
|
|
10
|
-
2,Bob,25
|
|
11
|
-
3,Charlie,35
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
csv_data_base = """
|
|
15
|
-
customer_id,name,age
|
|
16
|
-
1,Alice,35
|
|
17
|
-
2,Bob,25
|
|
18
|
-
3,Charlie,35
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
dbt_test_helper.create_model("customers", csv_data_base, csv_data_curr)
|
|
22
|
-
params = dict(sql_template=f'select * from {{{{ ref("customers") }}}}')
|
|
23
|
-
task = QueryTask(params)
|
|
24
|
-
run_result = task.execute()
|
|
25
|
-
assert len(run_result.current.data) == 3
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def test_query_diff_in_client(dbt_test_helper):
|
|
29
|
-
csv_data_curr = """
|
|
30
|
-
customer_id,name,age
|
|
31
|
-
1,Alice,30
|
|
32
|
-
2,Bob,25
|
|
33
|
-
3,Charlie,35
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
csv_data_base = """
|
|
37
|
-
customer_id,name,age
|
|
38
|
-
1,Alice,35
|
|
39
|
-
2,Bob,25
|
|
40
|
-
3,Charlie,35
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
dbt_test_helper.create_model("customers", csv_data_base, csv_data_curr)
|
|
44
|
-
params = dict(sql_template=f'select * from {{{{ ref("customers") }}}}')
|
|
45
|
-
task = QueryDiffTask(params)
|
|
46
|
-
run_result = task.execute()
|
|
47
|
-
assert len(run_result.base.data) == 3
|
|
48
|
-
assert len(run_result.current.data) == 3
|
|
49
|
-
|
|
50
|
-
params = dict(
|
|
51
|
-
base_sql_template=f'select * from {{{{ ref("customers") }}}} where customer_id <= 2',
|
|
52
|
-
sql_template=f'select * from {{{{ ref("customers") }}}}',
|
|
53
|
-
)
|
|
54
|
-
task = QueryDiffTask(params)
|
|
55
|
-
run_result = task.execute()
|
|
56
|
-
assert len(run_result.base.data) == 2
|
|
57
|
-
assert len(run_result.current.data) == 3
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def test_query_diff_in_warehouse(dbt_test_helper):
|
|
61
|
-
csv_data_curr = """
|
|
62
|
-
customer_id,name,age
|
|
63
|
-
1,Alice,30
|
|
64
|
-
2,Bob,25
|
|
65
|
-
3,Charlie,35
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
csv_data_base = """
|
|
69
|
-
customer_id,name,age
|
|
70
|
-
1,Alice,35
|
|
71
|
-
2,Bob,25
|
|
72
|
-
3,Charlie,35
|
|
73
|
-
"""
|
|
74
|
-
|
|
75
|
-
dbt_test_helper.create_model("customers", csv_data_base, csv_data_curr)
|
|
76
|
-
params = dict(sql_template=f'select * from {{{{ ref("customers") }}}}', primary_keys=['customer_id'])
|
|
77
|
-
task = QueryDiffTask(params)
|
|
78
|
-
run_result = task.execute()
|
|
79
|
-
assert len(run_result.diff.data) == 2
|
|
80
|
-
|
|
81
|
-
params = dict(
|
|
82
|
-
base_sql_template=f'select * from {{{{ ref("customers") }}}} where customer_id == 1',
|
|
83
|
-
sql_template=f'select * from {{{{ ref("customers") }}}}',
|
|
84
|
-
primary_keys=['customer_id'],
|
|
85
|
-
)
|
|
86
|
-
task = QueryDiffTask(params)
|
|
87
|
-
run_result = task.execute()
|
|
88
|
-
assert len(run_result.diff.data) == 4
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def test_validator():
|
|
92
|
-
from recce.tasks.query import QueryCheckValidator, QueryDiffCheckValidator
|
|
93
|
-
|
|
94
|
-
def validate(params: dict = {}, view_options: dict = {}):
|
|
95
|
-
QueryCheckValidator().validate({
|
|
96
|
-
'name': 'test',
|
|
97
|
-
'type': 'query',
|
|
98
|
-
'params': params,
|
|
99
|
-
'view_options': view_options,
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
def validate_diff(params: dict = {}, view_options: dict = {}):
|
|
103
|
-
QueryDiffCheckValidator().validate({
|
|
104
|
-
'name': 'test',
|
|
105
|
-
'type': 'query_diff',
|
|
106
|
-
'params': params,
|
|
107
|
-
'view_options': view_options,
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
# query
|
|
111
|
-
validate({
|
|
112
|
-
'sql_template': 'select * from abc'
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
# diff in client
|
|
116
|
-
validate_diff({
|
|
117
|
-
'sql_template': 'select * from abc'
|
|
118
|
-
})
|
|
119
|
-
validate_diff({
|
|
120
|
-
'sql_template': 'select * from abc',
|
|
121
|
-
'base_sql_template': 'select * from abc',
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
# diff in warehouse
|
|
125
|
-
validate_diff({
|
|
126
|
-
'primary_keys': ['customer_id'],
|
|
127
|
-
'sql_template': 'select * from abc',
|
|
128
|
-
})
|
|
129
|
-
validate_diff({
|
|
130
|
-
'sql_template': 'select * from abc',
|
|
131
|
-
'base_sql_template': 'select * from abc',
|
|
132
|
-
'primary_keys': ['customer_id']
|
|
133
|
-
})
|
|
134
|
-
validate_diff({
|
|
135
|
-
'sql_template': 'select * from abc',
|
|
136
|
-
'base_sql_template': 'select * from abc',
|
|
137
|
-
'primary_keys': ['customer_id']
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
# invalid
|
|
141
|
-
with pytest.raises(ValueError):
|
|
142
|
-
validate()
|
|
143
|
-
|
|
144
|
-
with pytest.raises(ValueError):
|
|
145
|
-
validate_diff()
|
|
146
|
-
|
|
147
|
-
with pytest.raises(ValueError):
|
|
148
|
-
validate_diff({'sql_template': 123, 'primary_keys': 'xyz'})
|
|
149
|
-
|
|
150
|
-
with pytest.raises(ValueError):
|
|
151
|
-
validate_diff({'sql_template': 's', 'primary_keys': 'xyz'})
|
tests/tasks/test_row_count.py
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from recce.tasks import RowCountDiffTask
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test_row_count(dbt_test_helper):
|
|
7
|
-
csv_data_curr = """
|
|
8
|
-
customer_id,name,age
|
|
9
|
-
1,Alice,30
|
|
10
|
-
2,Bob,25
|
|
11
|
-
3,Charlie,35
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
csv_data_base = """
|
|
15
|
-
customer_id,name,age
|
|
16
|
-
1,Alice,35
|
|
17
|
-
2,Bob,25
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
dbt_test_helper.create_model("customers", csv_data_base, csv_data_curr, unique_id='model.customers')
|
|
21
|
-
task = RowCountDiffTask(dict(node_names=['customers']))
|
|
22
|
-
run_result = task.execute()
|
|
23
|
-
assert run_result['customers']['base'] == 2
|
|
24
|
-
assert run_result['customers']['curr'] == 3
|
|
25
|
-
|
|
26
|
-
task = RowCountDiffTask(dict(node_names=['customers_']))
|
|
27
|
-
run_result = task.execute()
|
|
28
|
-
assert run_result['customers_']['base'] is None
|
|
29
|
-
assert run_result['customers_']['curr'] is None
|
|
30
|
-
|
|
31
|
-
task = RowCountDiffTask(dict(node_ids=['model.customers']))
|
|
32
|
-
run_result = task.execute()
|
|
33
|
-
assert run_result['customers']['base'] == 2
|
|
34
|
-
assert run_result['customers']['curr'] == 3
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_row_count_with_selector(dbt_test_helper):
|
|
38
|
-
csv_data_1 = """
|
|
39
|
-
customer_id,name,age
|
|
40
|
-
1,Alice,30
|
|
41
|
-
2,Bob,25
|
|
42
|
-
3,Charlie,35
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
csv_data_2 = """
|
|
46
|
-
customer_id,name,age
|
|
47
|
-
1,Alice,35
|
|
48
|
-
2,Bob,25
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
dbt_test_helper.create_model("model_1", csv_data_1, csv_data_2, depends_on=[])
|
|
52
|
-
dbt_test_helper.create_model("model_2", csv_data_1, csv_data_1, depends_on=['model_1'],
|
|
53
|
-
package_name='other_package')
|
|
54
|
-
task = RowCountDiffTask(dict(select='model_1'))
|
|
55
|
-
run_result = task.execute()
|
|
56
|
-
assert len(run_result) == 1
|
|
57
|
-
|
|
58
|
-
task = RowCountDiffTask(dict(select='model_1+'))
|
|
59
|
-
run_result = task.execute()
|
|
60
|
-
assert len(run_result) == 2
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def test_validator():
|
|
64
|
-
from recce.tasks.rowcount import RowCountDiffCheckValidator
|
|
65
|
-
|
|
66
|
-
validator = RowCountDiffCheckValidator()
|
|
67
|
-
|
|
68
|
-
def validate(params: dict):
|
|
69
|
-
validator.validate({
|
|
70
|
-
'name': 'test',
|
|
71
|
-
'type': 'row_count_diff',
|
|
72
|
-
'params': params,
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
# Select all modesl
|
|
76
|
-
validate({})
|
|
77
|
-
|
|
78
|
-
# Select by node name
|
|
79
|
-
validate({
|
|
80
|
-
'node_names': ['abc'],
|
|
81
|
-
})
|
|
82
|
-
with pytest.raises(ValueError):
|
|
83
|
-
validate({
|
|
84
|
-
'node_names': 'abc',
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
# Select by node id
|
|
88
|
-
validate({
|
|
89
|
-
'node_ids': ['model.abc'],
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
# Select by selector
|
|
93
|
-
validate({
|
|
94
|
-
'select': 'customers',
|
|
95
|
-
'exclude': 'customers',
|
|
96
|
-
'packages': ['jaffle_shop'],
|
|
97
|
-
'view_mode': 'all',
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
# packages should be an array
|
|
101
|
-
with pytest.raises(ValueError):
|
|
102
|
-
validate({
|
|
103
|
-
'packages': 'jaffle_shop',
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
# view_mode should be 'all' or 'changed_models'
|
|
107
|
-
validate({
|
|
108
|
-
'view_mode': None,
|
|
109
|
-
})
|
|
110
|
-
validate({
|
|
111
|
-
'view_mode': 'all',
|
|
112
|
-
})
|
|
113
|
-
with pytest.raises(ValueError):
|
|
114
|
-
validate({
|
|
115
|
-
'view_mode': 'abc',
|
|
116
|
-
})
|
tests/tasks/test_schema.py
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from unittest import TestCase
|
|
3
|
-
from unittest.mock import MagicMock
|
|
4
|
-
|
|
5
|
-
import pytest
|
|
6
|
-
|
|
7
|
-
from recce.adapter.dbt_adapter import load_manifest, load_catalog, DbtAdapter
|
|
8
|
-
from recce.core import RecceContext, set_default_context
|
|
9
|
-
from recce.run import schema_diff_should_be_approved
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_validator():
|
|
13
|
-
from recce.tasks.schema import SchemaDiffCheckValidator
|
|
14
|
-
validator = SchemaDiffCheckValidator()
|
|
15
|
-
|
|
16
|
-
def validate(params: dict):
|
|
17
|
-
validator.validate({
|
|
18
|
-
'name': 'test',
|
|
19
|
-
'type': 'schema_diff',
|
|
20
|
-
'params': params,
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
# Select all models
|
|
24
|
-
validate({})
|
|
25
|
-
|
|
26
|
-
# Select by node name
|
|
27
|
-
validate({
|
|
28
|
-
'node_id': 'abc',
|
|
29
|
-
})
|
|
30
|
-
validate({
|
|
31
|
-
'node_id': ['abc'],
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
# Select by selector
|
|
35
|
-
validate({
|
|
36
|
-
'select': 'customers',
|
|
37
|
-
'exclude': 'customers',
|
|
38
|
-
'packages': ['jaffle_shop'],
|
|
39
|
-
'view_mode': 'all',
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
# packages should be an array
|
|
43
|
-
with pytest.raises(ValueError):
|
|
44
|
-
validate({
|
|
45
|
-
'packages': 'jaffle_shop',
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
# view_mode should be 'all' or 'changed_models'
|
|
49
|
-
validate({
|
|
50
|
-
'view_mode': None,
|
|
51
|
-
})
|
|
52
|
-
validate({
|
|
53
|
-
'view_mode': 'all',
|
|
54
|
-
})
|
|
55
|
-
with pytest.raises(ValueError):
|
|
56
|
-
validate({
|
|
57
|
-
'view_mode': 'abc',
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
test_root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class TestSchemaDiffAutoApprove(TestCase):
|
|
65
|
-
|
|
66
|
-
def setUp(self):
|
|
67
|
-
self.default_context = MagicMock(spec=RecceContext)
|
|
68
|
-
manifest = load_manifest(path=os.path.join(test_root_path, 'manifest.json'))
|
|
69
|
-
catalog = load_catalog(path=os.path.join(test_root_path, 'catalog.json'))
|
|
70
|
-
dbt_adapter = DbtAdapter(curr_manifest=manifest, curr_catalog=catalog)
|
|
71
|
-
self.default_context.adapter = dbt_adapter
|
|
72
|
-
|
|
73
|
-
dbt_adapter.adapter = MagicMock()
|
|
74
|
-
dbt_adapter.adapter.type.return_value = None
|
|
75
|
-
|
|
76
|
-
dbt_adapter.select_nodes = MagicMock()
|
|
77
|
-
# Base and Current will be the same
|
|
78
|
-
self.default_context.get_lineage.return_value = dbt_adapter.get_lineage()
|
|
79
|
-
set_default_context(self.default_context)
|
|
80
|
-
|
|
81
|
-
def test_schema_diff_should_be_approved(self):
|
|
82
|
-
# Node_id is string
|
|
83
|
-
is_approved = schema_diff_should_be_approved({
|
|
84
|
-
'node_id': 'model.jaffle_shop.customers',
|
|
85
|
-
})
|
|
86
|
-
assert is_approved is True
|
|
87
|
-
|
|
88
|
-
# Node_id is list
|
|
89
|
-
is_approved = schema_diff_should_be_approved({
|
|
90
|
-
'node_id': ['model.jaffle_shop.customers'],
|
|
91
|
-
})
|
|
92
|
-
assert is_approved is True
|
|
93
|
-
|
|
94
|
-
# Select all models
|
|
95
|
-
self.default_context.adapter.select_nodes.return_value = ['model.jaffle_shop.customers']
|
|
96
|
-
is_approved = schema_diff_should_be_approved({
|
|
97
|
-
'select': 'customers',
|
|
98
|
-
})
|
|
99
|
-
assert is_approved is True
|