Skip to content

Commit ed8b404

Browse files
Fix: Preserve actual dataframe indices in unit test output (#4969)
1 parent 4be13ff commit ed8b404

File tree

2 files changed

+145
-4
lines changed

2 files changed

+145
-4
lines changed

sqlmesh/utils/rich.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def df_to_table(
9595

9696
rich_table.add_column(Align.center(column_name))
9797

98-
for index, value_list in enumerate(df.values.tolist()):
98+
for index, value_list in zip(df.index, df.values.tolist()):
9999
row = [str(index)] if show_index else []
100100
row += [str(x) for x in value_list]
101101
center = [Align.center(x) for x in row]

tests/core/test_test.py

Lines changed: 144 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,97 @@ def test_row_difference_failure() -> None:
10261026
)
10271027

10281028

1029+
def test_index_preservation_with_later_rows() -> None:
1030+
# Test comparison with differences in later rows
1031+
_check_successful_or_raise(
1032+
_create_test(
1033+
body=load_yaml(
1034+
"""
1035+
test_foo:
1036+
model: sushi.foo
1037+
inputs:
1038+
raw:
1039+
- id: 1
1040+
value: 100
1041+
- id: 2
1042+
value: 200
1043+
- id: 3
1044+
value: 300
1045+
- id: 4
1046+
value: 400
1047+
outputs:
1048+
query:
1049+
- id: 1
1050+
value: 100
1051+
- id: 2
1052+
value: 200
1053+
- id: 3
1054+
value: 999
1055+
- id: 4
1056+
value: 888
1057+
"""
1058+
),
1059+
test_name="test_foo",
1060+
model=_create_model("SELECT id, value FROM raw"),
1061+
context=Context(config=Config(model_defaults=ModelDefaultsConfig(dialect="duckdb"))),
1062+
).run(),
1063+
expected_msg=(
1064+
"AssertionError: Data mismatch (exp: expected, act: actual)\n\n"
1065+
" value \n"
1066+
" exp act\n"
1067+
"2 999.0 300.0\n"
1068+
"3 888.0 400.0\n"
1069+
),
1070+
)
1071+
1072+
# Test with null values in later rows
1073+
_check_successful_or_raise(
1074+
_create_test(
1075+
body=load_yaml(
1076+
"""
1077+
test_foo:
1078+
model: sushi.foo
1079+
inputs:
1080+
raw:
1081+
- id: 1
1082+
value: 100
1083+
- id: 2
1084+
value: 200
1085+
- id: 3
1086+
value: null
1087+
- id: 4
1088+
value: 400
1089+
- id: 5
1090+
value: null
1091+
outputs:
1092+
query:
1093+
- id: 1
1094+
value: 100
1095+
- id: 2
1096+
value: 200
1097+
- id: 3
1098+
value: 300
1099+
- id: 4
1100+
value: null
1101+
- id: 5
1102+
value: 500
1103+
"""
1104+
),
1105+
test_name="test_foo",
1106+
model=_create_model("SELECT id, value FROM raw"),
1107+
context=Context(config=Config(model_defaults=ModelDefaultsConfig(dialect="duckdb"))),
1108+
).run(),
1109+
expected_msg=(
1110+
"AssertionError: Data mismatch (exp: expected, act: actual)\n\n"
1111+
" value \n"
1112+
" exp act\n"
1113+
"2 300.0 NaN\n"
1114+
"3 NaN 400.0\n"
1115+
"4 500.0 NaN\n"
1116+
),
1117+
)
1118+
1119+
10291120
def test_unknown_column_error() -> None:
10301121
_check_successful_or_raise(
10311122
_create_test(
@@ -2277,7 +2368,7 @@ def test_test_output(tmp_path: Path) -> None:
22772368
┃ ┃ item_id: ┃ ┃ num_orders: ┃ num_orders: ┃
22782369
┃ Row ┃ Expected ┃ item_id: Actual ┃ Expected ┃ Actual ┃
22792370
┡━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
2280-
0 │ 4.0 │ 2.0 │ 3.0 │ 1.0 │
2371+
1 │ 4.0 │ 2.0 │ 3.0 │ 1.0 │
22812372
└─────┴─────────────────┴─────────────────┴─────────────────┴──────────────────┘
22822373
22832374
----------------------------------------------------------------------"""
@@ -2300,14 +2391,14 @@ def test_test_output(tmp_path: Path) -> None:
23002391
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
23012392
┃ Row ┃ Expected ┃ Actual ┃
23022393
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
2303-
0 │ 4.0 │ 2.0 │
2394+
1 │ 4.0 │ 2.0 │
23042395
└─────────────┴────────────────────────┴───────────────────┘
23052396
23062397
Column 'num_orders' mismatch
23072398
┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
23082399
┃ Row ┃ Expected ┃ Actual ┃
23092400
┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
2310-
0 │ 3.0 │ 1.0 │
2401+
1 │ 3.0 │ 1.0 │
23112402
└─────────────┴────────────────────────┴───────────────────┘
23122403
23132404
----------------------------------------------------------------------"""
@@ -2386,6 +2477,56 @@ def test_test_output(tmp_path: Path) -> None:
23862477
in captured_output.stdout
23872478
)
23882479

2480+
# Case 5: Test null value difference in the 3rd row (index 2)
2481+
rmtree(tmp_path / "tests")
2482+
tests_dir = tmp_path / "tests"
2483+
tests_dir.mkdir()
2484+
2485+
null_test_file = tmp_path / "tests" / "test_null_in_third_row.yaml"
2486+
null_test_file.write_text(
2487+
"""
2488+
test_null_third_row:
2489+
model: sqlmesh_example.full_model
2490+
description: Test null value in third row
2491+
inputs:
2492+
sqlmesh_example.incremental_model:
2493+
rows:
2494+
- id: 1
2495+
item_id: 1
2496+
- id: 2
2497+
item_id: 1
2498+
- id: 3
2499+
item_id: 2
2500+
- id: 4
2501+
item_id: 3
2502+
outputs:
2503+
query:
2504+
rows:
2505+
- item_id: 1
2506+
num_orders: 2
2507+
- item_id: 2
2508+
num_orders: 1
2509+
- item_id: 3
2510+
num_orders: null
2511+
"""
2512+
)
2513+
2514+
with capture_output() as captured_output:
2515+
context.test()
2516+
2517+
output = captured_output.stdout
2518+
2519+
# Check for null value difference in the 3rd row (index 2)
2520+
assert (
2521+
"""
2522+
┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┓
2523+
┃ Row ┃ num_orders: Expected ┃ num_orders: Actual ┃
2524+
┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━┩
2525+
│ 2 │ nan │ 1.0 │
2526+
└──────┴───────────────────────────┴───────────────────────┘"""
2527+
in output
2528+
)
2529+
23892530

23902531
@use_terminal_console
23912532
def test_test_output_with_invalid_model_name(tmp_path: Path) -> None:

0 commit comments

Comments
 (0)