Skip to content

Commit 8a32aea

Browse files
committed
test: refactor and parameterize for clarity
1 parent 5996e47 commit 8a32aea

File tree

1 file changed

+46
-93
lines changed

1 file changed

+46
-93
lines changed

python/cocoindex/tests/test_convert.py

Lines changed: 46 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -101,31 +101,28 @@ def test_make_engine_value_converter_basic_types():
101101
converter = build_engine_value_converter(engine_type_in_py)
102102
assert converter(value) == value
103103

104-
def test_make_engine_value_converter_struct():
105-
converter = build_engine_value_converter(Order)
106-
# All fields match
107-
engine_val = ["O123", "mixed nuts", 25.0, "default_extra"]
108-
assert converter(engine_val) == Order("O123", "mixed nuts", 25.0, "default_extra")
109-
# Extra field in Python dataclass (should ignore extra)
110-
engine_val_extra = ["O123", "mixed nuts", 25.0, "default_extra", "unexpected"]
111-
assert converter(engine_val_extra) == Order("O123", "mixed nuts", 25.0, "default_extra")
112-
# Fewer fields in engine value (should fill with default, so provide all fields)
113-
engine_val_short = ["O123", "mixed nuts", 0.0, "default_extra"]
114-
assert converter(engine_val_short) == Order("O123", "mixed nuts", 0.0, "default_extra")
115-
# More fields in engine value (should ignore extra)
116-
engine_val_long = ["O123", "mixed nuts", 25.0, "unexpected"]
117-
assert converter(engine_val_long) == Order("O123", "mixed nuts", 25.0, "unexpected")
118-
# Truly extra field (should ignore the fifth field)
119-
engine_val_extra_long = ["O123", "mixed nuts", 25.0, "default_extra", "ignored"]
120-
assert converter(engine_val_extra_long) == Order("O123", "mixed nuts", 25.0, "default_extra")
121-
122-
def test_make_engine_value_converter_struct_field_order():
123-
# Engine fields in different order
124-
# Use encode_enriched_type to avoid manual mistakes
125-
converter = build_engine_value_converter(Order)
126-
# Provide all fields in the correct order
127-
engine_val = ["O123", "mixed nuts", 25.0, "default_extra"]
128-
assert converter(engine_val) == Order("O123", "mixed nuts", 25.0, "default_extra")
104+
@pytest.mark.parametrize(
105+
"converter_type, engine_val, expected",
106+
[
107+
# All fields match
108+
(Order, ["O123", "mixed nuts", 25.0, "default_extra"], Order("O123", "mixed nuts", 25.0, "default_extra")),
109+
# Extra field in engine value (should ignore extra)
110+
(Order, ["O123", "mixed nuts", 25.0, "default_extra", "unexpected"], Order("O123", "mixed nuts", 25.0, "default_extra")),
111+
# Fewer fields in engine value (should fill with default)
112+
(Order, ["O123", "mixed nuts", 0.0, "default_extra"], Order("O123", "mixed nuts", 0.0, "default_extra")),
113+
# More fields in engine value (should ignore extra)
114+
(Order, ["O123", "mixed nuts", 25.0, "unexpected"], Order("O123", "mixed nuts", 25.0, "unexpected")),
115+
# Truly extra field (should ignore the fifth field)
116+
(Order, ["O123", "mixed nuts", 25.0, "default_extra", "ignored"], Order("O123", "mixed nuts", 25.0, "default_extra")),
117+
# Missing optional field in engine value (tags=None)
118+
(Customer, ["Alice", ["O1", "item1", 10.0, "default_extra"], None], Customer("Alice", Order("O1", "item1", 10.0, "default_extra"), None)),
119+
# Extra field in engine value for Customer (should ignore)
120+
(Customer, ["Alice", ["O1", "item1", 10.0, "default_extra"], [["vip"]], "extra"], Customer("Alice", Order("O1", "item1", 10.0, "default_extra"), [Tag("vip")])),
121+
]
122+
)
123+
def test_struct_conversion_cases(converter_type, engine_val, expected):
124+
converter = build_engine_value_converter(converter_type)
125+
assert converter(engine_val) == expected
129126

130127
def test_make_engine_value_converter_collections():
131128
# List of structs
@@ -152,74 +149,6 @@ def test_make_engine_value_converter_collections():
152149
2
153150
)
154151

155-
def test_make_engine_value_converter_defaults_and_missing_fields():
156-
# Missing optional field in engine value
157-
converter = build_engine_value_converter(Customer)
158-
engine_val = ["Alice", ["O1", "item1", 10.0, "default_extra"], None] # tags explicitly None
159-
assert converter(engine_val) == Customer("Alice", Order("O1", "item1", 10.0, "default_extra"), None)
160-
# Extra field in engine value (should ignore)
161-
engine_val = ["Alice", ["O1", "item1", 10.0, "default_extra"], [["vip"]], "extra"]
162-
assert converter(engine_val) == Customer("Alice", Order("O1", "item1", 10.0, "default_extra"), [Tag("vip")])
163-
164-
def test_engine_python_schema_field_order():
165-
"""
166-
Engine and Python dataclasses have the same fields but different order.
167-
Converter should map by field name, not order.
168-
"""
169-
@dataclass
170-
class EngineOrder:
171-
id: str
172-
name: str
173-
price: float
174-
@dataclass
175-
class PythonOrder:
176-
name: str
177-
id: str
178-
price: float
179-
extra: str = "default"
180-
converter = build_engine_value_converter(EngineOrder, PythonOrder)
181-
engine_val = ["O123", "mixed nuts", 25.0] # matches EngineOrder order
182-
assert converter(engine_val) == PythonOrder("mixed nuts", "O123", 25.0, "default")
183-
184-
def test_engine_python_schema_extra_field():
185-
"""
186-
Python dataclass has an extra field not present in engine schema.
187-
Converter should fill with default value.
188-
"""
189-
@dataclass
190-
class EngineOrder:
191-
id: str
192-
name: str
193-
@dataclass
194-
class PythonOrder:
195-
id: str
196-
name: str
197-
price: float = 0.0
198-
converter = build_engine_value_converter(EngineOrder, PythonOrder)
199-
engine_val = ["O123", "mixed nuts"]
200-
assert converter(engine_val) == PythonOrder("O123", "mixed nuts", 0.0)
201-
202-
def test_engine_python_schema_missing_field():
203-
"""
204-
Engine dataclass has a field missing in Python dataclass.
205-
Converter should ignore the missing field.
206-
"""
207-
from dataclasses import dataclass
208-
@dataclass
209-
class EngineOrder:
210-
id: str
211-
name: str
212-
price: float
213-
@dataclass
214-
class PythonOrder:
215-
id: str
216-
name: str
217-
converter = build_engine_value_converter(EngineOrder, PythonOrder)
218-
engine_val = ["O123", "mixed nuts", 25.0]
219-
assert converter(engine_val) == PythonOrder("O123", "mixed nuts")
220-
221-
222-
223152
def make_engine_order(fields):
224153
return make_dataclass('EngineOrder', fields)
225154

@@ -269,6 +198,30 @@ def make_python_order(fields, defaults=None):
269198
["unexpected", "mixed nuts", 25.0],
270199
("mixed nuts", 25.0),
271200
),
201+
# Field order difference (should map by name)
202+
(
203+
[("id", str), ("name", str), ("price", float)],
204+
[("name", str), ("id", str), ("price", float), ("extra", str)],
205+
{"extra": "default"},
206+
["O123", "mixed nuts", 25.0],
207+
("mixed nuts", "O123", 25.0, "default"),
208+
),
209+
# Extra field (Python has extra field with default)
210+
(
211+
[("id", str), ("name", str)],
212+
[("id", str), ("name", str), ("price", float)],
213+
{"price": 0.0},
214+
["O123", "mixed nuts"],
215+
("O123", "mixed nuts", 0.0),
216+
),
217+
# Missing field (Engine has extra field)
218+
(
219+
[("id", str), ("name", str), ("price", float)],
220+
[("id", str), ("name", str)],
221+
{},
222+
["O123", "mixed nuts", 25.0],
223+
("O123", "mixed nuts"),
224+
),
272225
]
273226
)
274227
def test_field_position_cases(engine_fields, python_fields, python_defaults, engine_val, expected_python_val):

0 commit comments

Comments
 (0)