recce-nightly 1.10.0.20250626__py3-none-any.whl → 1.10.0.20250629__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.
@@ -1,34 +1,75 @@
1
1
  from recce.adapter.dbt_adapter import DbtAdapter
2
2
  from recce.models.types import CllData
3
-
4
-
5
- def assert_column(result: CllData, node_name, column_name, transformation_type, depends_on):
6
- column_id = f"{node_name}_{column_name}"
3
+ from recce.util.lineage import build_column_key
4
+
5
+
6
+ def assert_parent_map(result: CllData, node_or_column_id, parents):
7
+ a_parents = result.parent_map.get(node_or_column_id) or set()
8
+
9
+ assert len(a_parents) == len(parents), "parents length mismatch"
10
+ for parent in parents:
11
+ if isinstance(parent, str):
12
+ node_id = parent
13
+ assert node_id in a_parents, f"Node {node_id} not found in parent list"
14
+ elif len(parent) == 1:
15
+ (node_id,) = parent
16
+ assert node_id in a_parents, f"Column {parent} not found in parent list"
17
+ elif len(parent) == 2:
18
+ node, column = parent
19
+ column_id = build_column_key(node, column)
20
+ assert column_id in a_parents, f"Column {column_id} not found in parent list for {node_or_column_id}"
21
+ else:
22
+ raise ValueError(f"Invalid parent format: {parent}. Expected node_id or (node_id, column_name).")
23
+
24
+
25
+ def assert_column(
26
+ result: CllData,
27
+ node_id,
28
+ column_name,
29
+ transformation_type=None,
30
+ change_status=None,
31
+ parents=None,
32
+ ):
33
+ column_id = build_column_key(node_id, column_name)
7
34
  entry = result.columns.get(column_id)
8
35
  assert entry is not None, f"Column {column_id} not found in result"
9
36
  assert (
10
37
  entry.transformation_type == transformation_type
11
38
  ), f"Column {column_name} type mismatch: expected {transformation_type}, got {entry.transformation_type}"
12
- parents = result.parent_map.get(column_id)
39
+ assert_parent_map(result, column_id, parents)
40
+ assert (
41
+ entry.change_status == change_status
42
+ ), f"Column {column_name} change status mismatch: expected {change_status}, got {entry.change_status}"
13
43
 
14
- assert len(parents) == len(depends_on), "depends_on length mismatch"
15
- for i in range(len(depends_on)):
16
- node, column = depends_on[i]
17
- parent_column_id = f"{node}_{column}"
18
44
 
19
- assert parent_column_id in parents, f"Column {parent_column_id} not found in {column_id}'s parent list"
45
+ def assert_model(
46
+ result: CllData,
47
+ node_id,
48
+ change_category=None,
49
+ parents=None,
50
+ ):
51
+ entry = result.nodes.get(node_id)
52
+ assert entry is not None, f"Node {node_id} not found in result"
53
+ assert_parent_map(result, node_id, parents)
20
54
 
55
+ assert (
56
+ entry.change_category == change_category
57
+ ), f"Node {node_id} change category mismatch: expected {change_category}, got {entry.change_category}"
21
58
 
22
- def assert_model(result: CllData, node_name, depends_on):
23
- assert result.nodes.get(node_name) is not None, f"Node {node_name} not found in result"
24
- parent_map = result.parent_map.get(node_name)
25
- assert parent_map is not None, f"Parent map {node_name} not found in result"
26
- # assert len(parent_map) == len(depends_on), "depends_on length mismatch"
27
- for i in range(len(depends_on)):
28
- node, column = depends_on[i]
29
- column_id = f"{node}_{column}"
30
59
 
31
- assert column_id in parent_map, f"Parent map {node_name} does not contain {column_id}"
60
+ def assert_cll_contain_nodes(cll_data: CllData, nodes):
61
+ assert len(nodes) == len(cll_data.nodes), "Model count mismatch"
62
+ for node in nodes:
63
+ assert node in cll_data.nodes, f"Model {node} not found in lineage"
64
+
65
+
66
+ def assert_cll_contain_columns(cll_data: CllData, columns):
67
+ assert len(columns) == len(cll_data.columns), "Column count mismatch"
68
+ for column in columns:
69
+ column_key = f"{column[0]}_{column[1]}"
70
+ assert column_key in cll_data.columns, f"Column {column} not found in lineage"
71
+ assert column[0] == cll_data.columns[column_key].table_id, f"Column {column[0]} node mismatch"
72
+ assert column[1] == cll_data.columns[column_key].name, f"Column {column[1]} name mismatch"
32
73
 
33
74
 
34
75
  def test_cll_basic(dbt_test_helper):
@@ -51,13 +92,12 @@ def test_cll_basic(dbt_test_helper):
51
92
  )
52
93
  adapter: DbtAdapter = dbt_test_helper.context.adapter
53
94
 
54
- result = adapter.get_cll("model.model2", no_filter=True)
55
- assert_model(result, "model.model2", [("model.model1", "c")])
56
- assert_column(result, "model.model2", "c", "passthrough", [("model.model1", "c")])
95
+ result = adapter.get_cll("model.model1", "c")
96
+ assert_model(result, "model.model2", parents=[("model.model1", "c")])
97
+ assert_column(result, "model.model2", "c", transformation_type="passthrough", parents=[("model.model1", "c")])
57
98
 
58
- result = adapter.get_cll("model.model3", no_filter=True)
59
- assert_model(result, "model.model3", [("model.model1", "c")])
60
- assert_column(result, "model.model3", "c", "passthrough", [("model.model1", "c")])
99
+ assert_model(result, "model.model3", parents=[("model.model1", "c")])
100
+ assert_column(result, "model.model3", "c", transformation_type="passthrough", parents=[("model.model1", "c")])
61
101
 
62
102
 
63
103
  def test_cll_table_alisa(dbt_test_helper):
@@ -75,8 +115,8 @@ def test_cll_table_alisa(dbt_test_helper):
75
115
  depends_on=["model.model1"],
76
116
  )
77
117
  adapter: DbtAdapter = dbt_test_helper.context.adapter
78
- result = adapter.get_cll("model.model1", no_filter=True)
79
- assert_column(result, "model.model2", "c", "passthrough", [("model.model1", "c")])
118
+ result = adapter.get_cll("model.model1", "c")
119
+ assert_column(result, "model.model2", "c", transformation_type="passthrough", parents=[("model.model1", "c")])
80
120
 
81
121
 
82
122
  def test_seed(dbt_test_helper):
@@ -103,11 +143,17 @@ def test_seed(dbt_test_helper):
103
143
  )
104
144
  adapter: DbtAdapter = dbt_test_helper.context.adapter
105
145
 
106
- result = adapter.get_cll("model.model1", no_filter=True)
107
- assert_model(result, "seed.seed1", [])
108
- assert_column(result, "seed.seed1", "customer_id", "source", [])
109
- assert_model(result, "model.model1", [("seed.seed1", "age")])
110
- assert_column(result, "model.model1", "customer_id", "passthrough", [("seed.seed1", "customer_id")])
146
+ result = adapter.get_cll("model.model1")
147
+ assert_model(result, "seed.seed1", parents=[])
148
+ assert_column(result, "seed.seed1", "customer_id", transformation_type="source", parents=[])
149
+ assert_model(result, "model.model1", parents=["seed.seed1", ("seed.seed1", "age")])
150
+ assert_column(
151
+ result,
152
+ "model.model1",
153
+ "customer_id",
154
+ transformation_type="passthrough",
155
+ parents=[("seed.seed1", "customer_id")],
156
+ )
111
157
 
112
158
 
113
159
  def test_python_model(dbt_test_helper):
@@ -134,8 +180,9 @@ def test_python_model(dbt_test_helper):
134
180
  assert not adapter.is_python_model("model1")
135
181
  assert adapter.is_python_model("model2")
136
182
 
137
- result = adapter.get_cll("model1", no_filter=True)
138
- assert_column(result, "model2", "customer_id", "unknown", [])
183
+ result = adapter.get_cll("model2")
184
+ assert_model(result, "model2", parents=["model1"])
185
+ assert_column(result, "model2", "customer_id", transformation_type="unknown", parents=[])
139
186
 
140
187
 
141
188
  def test_source(dbt_test_helper):
@@ -161,43 +208,33 @@ def test_source(dbt_test_helper):
161
208
  depends_on=["source.source1.table1"],
162
209
  )
163
210
  adapter: DbtAdapter = dbt_test_helper.context.adapter
164
- result = adapter.get_cll("source.source1.table1", no_filter=True)
165
- assert_column(result, "source.source1.table1", "customer_id", "source", [])
166
- result = adapter.get_cll("model.model1", no_filter=True)
167
- assert_column(result, "model.model1", "customer_id", "passthrough", [("source.source1.table1", "customer_id")])
211
+ result = adapter.get_cll("model.model1")
212
+ assert_column(result, "source.source1.table1", "customer_id", transformation_type="source", parents=[])
213
+ assert_column(
214
+ result,
215
+ "model.model1",
216
+ "customer_id",
217
+ transformation_type="passthrough",
218
+ parents=[("source.source1.table1", "customer_id")],
219
+ )
168
220
 
169
221
 
170
222
  def test_parse_error(dbt_test_helper):
171
223
  dbt_test_helper.create_model("model1", curr_sql="select 1 as c", curr_columns={"c": "int"})
172
224
  dbt_test_helper.create_model("model2", curr_sql="this is not a valid sql", curr_columns={"c": "int"})
173
225
  adapter: DbtAdapter = dbt_test_helper.context.adapter
174
- result = adapter.get_cll("model2", no_filter=True)
175
- assert_column(result, "model2", "c", "unknown", [])
226
+ result = adapter.get_cll("model2")
227
+ assert_column(result, "model2", "c", transformation_type="unknown", parents=[])
176
228
 
177
229
 
178
230
  def test_model_without_catalog(dbt_test_helper):
179
231
  dbt_test_helper.create_model("model1", curr_sql="select 1 as c")
180
232
  adapter: DbtAdapter = dbt_test_helper.context.adapter
181
- result = adapter.get_cll("model1", no_filter=True)
233
+ result = adapter.get_cll("model1")
182
234
  assert not result.nodes["model1"].columns
183
235
 
184
236
 
185
- def assert_lineage_model(cll_data: CllData, nodes):
186
- assert len(nodes) == len(cll_data.nodes), "Model count mismatch"
187
- for node in nodes:
188
- assert node in cll_data.nodes, f"Model {node} not found in lineage"
189
-
190
-
191
- def assert_lineage_column(cll_data: CllData, columns):
192
- assert len(columns) == len(cll_data.columns), "Column count mismatch"
193
- for column in columns:
194
- column_key = f"{column[0]}_{column[1]}"
195
- assert column_key in cll_data.columns, f"Column {column} not found in lineage"
196
- assert column[0] == cll_data.columns[column_key].table_id, f"Column {column[0]} node mismatch"
197
- assert column[1] == cll_data.columns[column_key].name, f"Column {column[1]} name mismatch"
198
-
199
-
200
- def test_cll_column_filter(dbt_test_helper):
237
+ def test_column_level_lineage(dbt_test_helper):
201
238
  dbt_test_helper.create_model(
202
239
  "model1", unique_id="model.model1", curr_sql="select 1 as c", curr_columns={"c": "int"}
203
240
  )
@@ -226,19 +263,256 @@ def test_cll_column_filter(dbt_test_helper):
226
263
  adapter: DbtAdapter = dbt_test_helper.context.adapter
227
264
 
228
265
  result = adapter.get_cll("model.model2", "c")
229
- assert_lineage_model(result, [])
230
- assert_lineage_column(result, [("model.model1", "c"), ("model.model2", "c"), ("model.model3", "c")])
266
+ assert_cll_contain_nodes(result, [])
267
+ assert_cll_contain_columns(result, [("model.model1", "c"), ("model.model2", "c"), ("model.model3", "c")])
268
+ assert_column(result, "model.model2", "c", transformation_type="passthrough", parents=[("model.model1", "c")])
231
269
 
232
270
  result = adapter.get_cll("model.model2", "y")
233
- assert_lineage_model(result, ["model.model3"])
234
- assert_lineage_column(result, [("model.model2", "y"), ("model.model4", "y")])
271
+ assert_cll_contain_nodes(result, ["model.model3"])
272
+ assert_cll_contain_columns(result, [("model.model2", "y"), ("model.model4", "y")])
273
+ assert_column(result, "model.model2", "y", transformation_type="source", parents=[])
235
274
 
236
275
  result = adapter.get_cll("model.model3", "c")
237
- assert_lineage_model(result, [])
238
- assert_lineage_column(result, [("model.model1", "c"), ("model.model2", "c"), ("model.model3", "c")])
276
+ assert_cll_contain_nodes(result, [])
277
+ assert_cll_contain_columns(result, [("model.model1", "c"), ("model.model2", "c"), ("model.model3", "c")])
278
+ assert_column(result, "model.model2", "c", transformation_type="passthrough", parents=[("model.model1", "c")])
279
+
280
+ result = adapter.get_cll("model.model2", "c", no_upstream=True, no_downstream=True)
281
+ assert_cll_contain_nodes(result, [])
282
+ assert_cll_contain_columns(result, [("model.model2", "c")])
283
+ assert_column(result, "model.model2", "c", transformation_type="passthrough", parents=[])
284
+
285
+
286
+ def test_impact_radius_no_change_analysis_no_cll(dbt_test_helper):
287
+ dbt_test_helper.create_model(
288
+ "model1",
289
+ unique_id="model.model1",
290
+ curr_sql="select 1 as c",
291
+ base_sql="select 1 as c --- non-breaking",
292
+ curr_columns={"c": "int"},
293
+ base_columns={"c": "int"},
294
+ )
295
+ dbt_test_helper.create_model(
296
+ "model2",
297
+ unique_id="model.model2",
298
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
299
+ base_sql='select c, 2025 as y from {{ ref("model1") }} where c > 0 --- breaking',
300
+ curr_columns={"c": "int", "y": "int"},
301
+ base_columns={"c": "int", "y": "int"},
302
+ depends_on=["model.model1"],
303
+ )
304
+ dbt_test_helper.create_model(
305
+ "model3",
306
+ unique_id="model.model3",
307
+ curr_sql='select c from {{ ref("model2") }} where y < 2025',
308
+ base_sql='select c from {{ ref("model2") }} where y < 2025',
309
+ curr_columns={"c": "int"},
310
+ base_columns={"c": "int"},
311
+ depends_on=["model.model2"],
312
+ )
313
+ dbt_test_helper.create_model(
314
+ "model4",
315
+ unique_id="model.model4",
316
+ curr_sql='select y + 1 as year from {{ ref("model2") }} --- partial breaking',
317
+ base_sql='select y as year from {{ ref("model2") }}',
318
+ curr_columns={"year": "int"},
319
+ base_columns={"year": "int"},
320
+ depends_on=["model.model2"],
321
+ )
322
+ dbt_test_helper.create_model(
323
+ "model5",
324
+ unique_id="model.model5",
325
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
326
+ base_sql='select c, 2025 as y from {{ ref("model1") }}',
327
+ curr_columns={"c": "int", "y": "int"},
328
+ base_columns={"c": "int", "y": "int"},
329
+ depends_on=["model.model1"],
330
+ )
331
+
332
+ adapter: DbtAdapter = dbt_test_helper.context.adapter
333
+
334
+ result = adapter.get_cll(no_cll=True)
335
+ assert_cll_contain_nodes(result, ["model.model1", "model.model2", "model.model3", "model.model4", "model.model5"])
336
+ assert_model(result, "model.model1", parents=[])
337
+ assert_model(result, "model.model2", parents=["model.model1"])
338
+ assert_model(result, "model.model3", parents=["model.model2"])
339
+ assert_model(result, "model.model4", parents=["model.model2"])
340
+ assert_model(result, "model.model5", parents=["model.model1"])
341
+
342
+
343
+ def test_impact_radius_with_change_analysis_no_cll(dbt_test_helper):
344
+ dbt_test_helper.create_model(
345
+ "model1",
346
+ unique_id="model.model1",
347
+ curr_sql="select 1 as c",
348
+ base_sql="select 1 as c --- non-breaking",
349
+ curr_columns={"c": "int"},
350
+ base_columns={"c": "int"},
351
+ )
352
+ dbt_test_helper.create_model(
353
+ "model2",
354
+ unique_id="model.model2",
355
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
356
+ base_sql='select c, 2025 as y from {{ ref("model1") }} where c > 0 --- breaking',
357
+ curr_columns={"c": "int", "y": "int"},
358
+ base_columns={"c": "int", "y": "int"},
359
+ depends_on=["model.model1"],
360
+ )
361
+ dbt_test_helper.create_model(
362
+ "model3",
363
+ unique_id="model.model3",
364
+ curr_sql='select c from {{ ref("model2") }} where y < 2025',
365
+ base_sql='select c from {{ ref("model2") }} where y < 2025',
366
+ curr_columns={"c": "int"},
367
+ base_columns={"c": "int"},
368
+ depends_on=["model.model2"],
369
+ )
370
+ dbt_test_helper.create_model(
371
+ "model4",
372
+ unique_id="model.model4",
373
+ curr_sql='select y + 1 as year from {{ ref("model2") }} --- partial breaking',
374
+ base_sql='select y as year from {{ ref("model2") }}',
375
+ curr_columns={"year": "int"},
376
+ base_columns={"year": "int"},
377
+ depends_on=["model.model2"],
378
+ )
379
+ dbt_test_helper.create_model(
380
+ "model5",
381
+ unique_id="model.model5",
382
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
383
+ base_sql='select c, 2025 as y from {{ ref("model1") }}',
384
+ curr_columns={"c": "int", "y": "int"},
385
+ base_columns={"c": "int", "y": "int"},
386
+ depends_on=["model.model1"],
387
+ )
388
+
389
+ adapter: DbtAdapter = dbt_test_helper.context.adapter
390
+
391
+ # breaking
392
+ result = adapter.get_cll(change_analysis=True, no_cll=True, no_upstream=True)
393
+ assert_cll_contain_nodes(result, ["model.model1", "model.model2", "model.model3", "model.model4"])
394
+ assert_model(result, "model.model1", parents=[], change_category="non_breaking")
395
+ assert_model(result, "model.model2", parents=[], change_category="breaking")
396
+ assert_model(result, "model.model3", parents=["model.model2"], change_category=None)
397
+ assert_model(result, "model.model4", parents=["model.model2"], change_category="partial_breaking")
398
+
399
+
400
+ def test_impact_radius_with_change_analysis_no_cll_2(dbt_test_helper):
401
+ dbt_test_helper.create_model(
402
+ "model1",
403
+ unique_id="model.model1",
404
+ curr_sql="select 1 as c",
405
+ base_sql="select 2 as c",
406
+ curr_columns={"c": "int"},
407
+ base_columns={"c": "int"},
408
+ )
409
+ dbt_test_helper.create_model(
410
+ "model2",
411
+ unique_id="model.model2",
412
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
413
+ base_sql='select c, 2025 as y from {{ ref("model1") }} where c > 0 --- breaking',
414
+ curr_columns={"c": "int", "y": "int"},
415
+ base_columns={"c": "int", "y": "int"},
416
+ depends_on=["model.model1"],
417
+ )
418
+ dbt_test_helper.create_model(
419
+ "model3",
420
+ unique_id="model.model3",
421
+ curr_sql='select c from {{ ref("model2") }} where y < 2025',
422
+ base_sql='select c from {{ ref("model2") }} where y < 2025',
423
+ curr_columns={"c": "int"},
424
+ base_columns={"c": "int"},
425
+ depends_on=["model.model2"],
426
+ )
427
+ dbt_test_helper.create_model(
428
+ "model4",
429
+ unique_id="model.model4",
430
+ curr_sql='select y + 1 as year from {{ ref("model2") }} --- partial breaking',
431
+ base_sql='select y as year from {{ ref("model2") }}',
432
+ curr_columns={"year": "int"},
433
+ base_columns={"year": "int"},
434
+ depends_on=["model.model2"],
435
+ )
436
+ dbt_test_helper.create_model(
437
+ "model5",
438
+ unique_id="model.model5",
439
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
440
+ base_sql='select c, 2025 as y from {{ ref("model1") }}',
441
+ curr_columns={"c": "int", "y": "int"},
442
+ base_columns={"c": "int", "y": "int"},
443
+ depends_on=["model.model1"],
444
+ )
445
+
446
+ adapter: DbtAdapter = dbt_test_helper.context.adapter
447
+
448
+ # breaking
449
+ result = adapter.get_cll(change_analysis=True, no_cll=True, no_upstream=True)
450
+ assert_cll_contain_nodes(result, ["model.model1", "model.model2", "model.model3", "model.model4", "model.model5"])
451
+ assert_model(result, "model.model1", parents=[], change_category="partial_breaking")
452
+ assert_model(result, "model.model2", parents=["model.model1"], change_category="breaking")
453
+ assert_model(result, "model.model3", parents=["model.model2"], change_category=None)
454
+ assert_model(result, "model.model4", parents=["model.model2"], change_category="partial_breaking")
455
+ assert_model(result, "model.model5", parents=["model.model1"])
456
+
457
+
458
+ def test_impact_radius_with_change_analysis_with_cll(dbt_test_helper):
459
+ dbt_test_helper.create_model(
460
+ "model1",
461
+ unique_id="model.model1",
462
+ curr_sql="select 1 as c",
463
+ base_sql="select 1 as c --- non-breaking",
464
+ curr_columns={"c": "int"},
465
+ base_columns={"c": "int"},
466
+ )
467
+ dbt_test_helper.create_model(
468
+ "model2",
469
+ unique_id="model.model2",
470
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
471
+ base_sql='select c, 2025 as y from {{ ref("model1") }} where c > 0 --- breaking',
472
+ curr_columns={"c": "int", "y": "int"},
473
+ base_columns={"c": "int", "y": "int"},
474
+ depends_on=["model.model1"],
475
+ )
476
+ dbt_test_helper.create_model(
477
+ "model3",
478
+ unique_id="model.model3",
479
+ curr_sql='select c from {{ ref("model2") }} where y < 2025',
480
+ base_sql='select c from {{ ref("model2") }} where y < 2025',
481
+ curr_columns={"c": "int"},
482
+ base_columns={"c": "int"},
483
+ depends_on=["model.model2"],
484
+ )
485
+ dbt_test_helper.create_model(
486
+ "model4",
487
+ unique_id="model.model4",
488
+ curr_sql='select y + 1 as year from {{ ref("model2") }} --- partial breaking',
489
+ base_sql='select y as year from {{ ref("model2") }}',
490
+ curr_columns={"year": "int"},
491
+ base_columns={"year": "int"},
492
+ depends_on=["model.model2"],
493
+ )
494
+ dbt_test_helper.create_model(
495
+ "model5",
496
+ unique_id="model.model5",
497
+ curr_sql='select c, 2025 as y from {{ ref("model1") }}',
498
+ base_sql='select c, 2025 as y from {{ ref("model1") }}',
499
+ curr_columns={"c": "int", "y": "int"},
500
+ base_columns={"c": "int", "y": "int"},
501
+ depends_on=["model.model1"],
502
+ )
503
+
504
+ adapter: DbtAdapter = dbt_test_helper.context.adapter
505
+
506
+ result = adapter.get_cll(change_analysis=True, no_upstream=True)
507
+ assert_cll_contain_nodes(result, ["model.model1", "model.model2", "model.model3", "model.model4"])
508
+ assert_cll_contain_columns(result, [("model.model4", "year")])
509
+ assert_model(result, "model.model1", parents=[], change_category="non_breaking")
510
+ assert_model(result, "model.model2", parents=[], change_category="breaking")
511
+ assert_model(result, "model.model3", parents=["model.model2"], change_category=None)
512
+ assert_model(result, "model.model4", parents=["model.model2"], change_category="partial_breaking")
239
513
 
240
514
 
241
- def test_impact_radius_nodes(dbt_test_helper):
515
+ def test_impact_radius_by_node_no_cll(dbt_test_helper):
242
516
  # non-breaking
243
517
  dbt_test_helper.create_model(
244
518
  "model1",
@@ -280,15 +554,15 @@ def test_impact_radius_nodes(dbt_test_helper):
280
554
  adapter: DbtAdapter = dbt_test_helper.context.adapter
281
555
 
282
556
  # breaking
283
- result = adapter.get_impacted_nodes("model.model2")
284
- assert_lineage_model(result, ["model.model2", "model.model3", "model.model4"])
557
+ result = adapter.get_cll(node_id="model.model2", change_analysis=True, no_cll=True, no_upstream=True)
558
+ assert_cll_contain_nodes(result, ["model.model2", "model.model3", "model.model4"])
285
559
 
286
560
  # non-breaking
287
- result = adapter.get_impacted_nodes("model.model1")
288
- assert_lineage_model(result, [])
561
+ result = adapter.get_cll(node_id="model.model1", change_analysis=True, no_cll=True, no_upstream=True)
562
+ assert_cll_contain_nodes(result, ["model.model1"])
289
563
 
290
564
 
291
- def test_impact_radius_columns(dbt_test_helper):
565
+ def test_impact_radius_by_node_with_cll(dbt_test_helper):
292
566
  # added column
293
567
  dbt_test_helper.create_model(
294
568
  "model1",
@@ -329,16 +603,20 @@ def test_impact_radius_columns(dbt_test_helper):
329
603
 
330
604
  adapter: DbtAdapter = dbt_test_helper.context.adapter
331
605
 
332
- result = adapter.get_impacted_cll("model.model2")
333
- assert_lineage_model(result, ["model.model3"])
334
- assert_lineage_column(result, [("model.model2", "y"), ("model.model4", "y")])
606
+ result = adapter.get_cll(node_id="model.model2", change_analysis=True, no_upstream=True)
607
+ assert_model(result, "model.model2", parents=[], change_category="partial_breaking")
608
+ assert_column(result, "model.model2", "y", transformation_type="source", parents=[], change_status="modified")
609
+ assert_cll_contain_nodes(result, ["model.model2", "model.model3"])
610
+ assert_cll_contain_columns(result, [("model.model2", "y"), ("model.model4", "y")])
335
611
 
336
- result = adapter.get_impacted_cll("model.model1")
337
- assert_lineage_model(result, [])
338
- assert_lineage_column(result, [("model.model1", "d")])
612
+ result = adapter.get_cll(node_id="model.model1", change_analysis=True, no_upstream=True)
613
+ assert_cll_contain_nodes(result, ["model.model1"])
614
+ assert_cll_contain_columns(result, [("model.model1", "d")])
615
+ assert_model(result, "model.model1", parents=[], change_category="non_breaking")
616
+ assert_column(result, "model.model1", "d", transformation_type="source", parents=[], change_status="added")
339
617
 
340
618
 
341
- def test_impact_radius(dbt_test_helper):
619
+ def test_impact_radius_by_node_with_cll_2(dbt_test_helper):
342
620
  # added column
343
621
  dbt_test_helper.create_model(
344
622
  "model1",
@@ -379,6 +657,10 @@ def test_impact_radius(dbt_test_helper):
379
657
 
380
658
  adapter: DbtAdapter = dbt_test_helper.context.adapter
381
659
 
382
- result = adapter.get_impact_radius("model.model2")
383
- assert_lineage_model(result, ["model.model2", "model.model3", "model.model4"])
384
- assert_lineage_column(result, [("model.model2", "d"), ("model.model2", "y"), ("model.model4", "y")])
660
+ result = adapter.get_cll(node_id="model.model2", change_analysis=True, no_upstream=True)
661
+ assert_model(result, "model.model2", parents=[], change_category="breaking")
662
+ assert_column(result, "model.model2", "y", transformation_type="source", parents=[], change_status="modified")
663
+ assert_model(result, "model.model3", parents=["model.model2", ("model.model2", "y")])
664
+ assert_column(result, "model.model4", "y", transformation_type="passthrough", parents=[("model.model2", "y")])
665
+ assert_cll_contain_nodes(result, ["model.model2", "model.model3", "model.model4"])
666
+ assert_cll_contain_columns(result, [("model.model2", "d"), ("model.model2", "y"), ("model.model4", "y")])
tests/test_core.py CHANGED
@@ -24,6 +24,4 @@ def test_lineage_diff(dbt_test_helper):
24
24
  nodediff = result.diff.get("model1")
25
25
  assert nodediff is None
26
26
  nodediff2 = result.diff.get("model2")
27
- assert (
28
- nodediff2 is not None and nodediff2.change_status == "modified" and nodediff2.change.category == "non_breaking"
29
- )
27
+ assert nodediff2 is not None and nodediff2.change_status == "modified"