Skip to content

Commit 99cc97f

Browse files
author
Jürgen Zornig
committed
fix(fixtures/update): correct DBFit semantics — '=' suffix marks SET, bare marks WHERE
The previous implementation had the convention inverted. In DBFit, a header written as 'colname=' reads as 'set this column to the cell value' (SET); a bare 'colname' means 'find the row by matching this column' (WHERE). Tests + docstring updated. KBGSuite end-to-end against live Oracle: 6/6 pages green.
1 parent a4b8173 commit 99cc97f

2 files changed

Lines changed: 23 additions & 16 deletions

File tree

src/dbression/fixtures/basic.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,10 @@ class Update(Fixture):
231231
232232
Convention (DBFit-compatible):
233233
234-
* Headers ending in ``=`` mark **WHERE columns** (the row's value is used in the WHERE clause).
235-
* All other headers are **SET columns** (assigned to the new value).
234+
* Headers ending in ``=`` mark **SET columns** (assigned to the new value — the ``=``
235+
reads as "set this to whatever").
236+
* All other headers are **WHERE columns** (the row's value is used in the WHERE
237+
clause to locate the row).
236238
237239
Data-cell substitution: ``<<sym`` reads from the symbol table, empty / ``null`` becomes NULL.
238240
Each data row issues one ``UPDATE`` statement. NULL on a WHERE column generates ``IS NULL``
@@ -241,10 +243,10 @@ class Update(Fixture):
241243
Example::
242244
243245
!|Update|wlk.app_selectset|
244-
|selected|oid=|table_name=|
245-
|true |42 |WB |
246+
|selected=|oid|table_name|
247+
|true |42 |WB |
246248
247-
runs ``UPDATE wlk.app_selectset SET selected = :v_0 WHERE oid = :v_1 AND table_name = :v_2``.
249+
runs ``UPDATE wlk.app_selectset SET selected = :s_0 WHERE oid = :w_1 AND table_name = :w_2``.
248250
"""
249251

250252
def run(self, table: Table, ctx: FixtureContext) -> FixtureResult:
@@ -260,13 +262,13 @@ def run(self, table: Table, ctx: FixtureContext) -> FixtureResult:
260262
for c_i, raw in enumerate(table.headers):
261263
h = raw.strip()
262264
if h.endswith("="):
263-
where_columns.append((c_i, h[:-1].strip()))
265+
set_columns.append((c_i, h[:-1].strip()))
264266
else:
265-
set_columns.append((c_i, h))
267+
where_columns.append((c_i, h))
266268
if not set_columns:
267269
return FixtureResult(
268270
passed=False,
269-
message="Update has no SET columns (every header ends with `=`)",
271+
message="Update has no SET columns (no header ends with `=`)",
270272
)
271273

272274
updated = 0

tests/test_update_fixture.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
"""Update fixture tests against in-memory SQLite (no DB setup needed)."""
1+
"""Update fixture tests against in-memory SQLite (no DB setup needed).
2+
3+
DBFit convention recap:
4+
- Header ending in `=` → SET column ("set this to whatever")
5+
- Bare header → WHERE column (lookup criterion)
6+
"""
27
from __future__ import annotations
38

49
import pytest
@@ -40,7 +45,7 @@ def test_update_set_one_column_where_id(conn) -> None:
4045
res, _ = _run_update(
4146
conn,
4247
args=["kunde"],
43-
headers=["ort", "id="],
48+
headers=["ort=", "id"], # SET ort, WHERE id
4449
rows=[["Salzburg", "1"]],
4550
)
4651
assert res.passed, res.message
@@ -53,7 +58,7 @@ def test_update_multi_set_multi_where(conn) -> None:
5358
res, _ = _run_update(
5459
conn,
5560
args=["kunde"],
56-
headers=["name", "ort", "id="],
61+
headers=["name=", "ort=", "id"],
5762
rows=[["BobNeu", "Graz", "2"]],
5863
)
5964
assert res.passed
@@ -65,7 +70,7 @@ def test_update_multiple_rows_each_with_own_where(conn) -> None:
6570
res, _ = _run_update(
6671
conn,
6772
args=["kunde"],
68-
headers=["ort", "id="],
73+
headers=["ort=", "id"],
6974
rows=[["Graz", "1"], ["Innsbruck", "3"]],
7075
)
7176
assert res.passed
@@ -82,7 +87,7 @@ def test_update_with_symbol_substitution(conn) -> None:
8287
tbl = Table(
8388
name="Update",
8489
header_args=["kunde"],
85-
headers=["ort", "id="],
90+
headers=["ort=", "id"],
8691
rows=[["<<new_ort", "<<target_id"]],
8792
)
8893
res = cls().run(tbl, ctx)
@@ -97,7 +102,7 @@ def test_update_null_in_where_uses_is_null(conn) -> None:
97102
res, _ = _run_update(
98103
conn,
99104
args=["kunde"],
100-
headers=["name", "ort="],
105+
headers=["name=", "ort"],
101106
rows=[["Found", "null"]],
102107
)
103108
assert res.passed
@@ -109,14 +114,14 @@ def test_update_no_set_columns_fails_gracefully(conn) -> None:
109114
res, _ = _run_update(
110115
conn,
111116
args=["kunde"],
112-
headers=["id=", "name="],
117+
headers=["id", "name"], # no `=` anywhere → no SET columns
113118
rows=[["1", "Anna"]],
114119
)
115120
assert not res.passed
116121
assert "no SET columns" in res.message
117122

118123

119124
def test_update_without_table_name_fails(conn) -> None:
120-
res, _ = _run_update(conn, args=[], headers=["x"], rows=[["1"]])
125+
res, _ = _run_update(conn, args=[], headers=["x="], rows=[["1"]])
121126
assert not res.passed
122127
assert "table name" in res.message

0 commit comments

Comments
 (0)