Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pytest-local.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ testpaths =
tests/test_container_smoke.py
tests/test_data.py
tests/test_dataframe.py
tests/test_nooa_extract_dimensions.py
tests/test_openai_extract_ai.py
tests/recipes
tests/connectors/test_access.py
Expand Down
3 changes: 3 additions & 0 deletions requirements-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ psycopg2-binary>=2.9.10

# Parquet file support (file connector)
pyarrow

# AI agent framework (extract.dimensions), Python 3.12+ only
nooa==0.0.10; python_version >= "3.12"
110 changes: 110 additions & 0 deletions tests/recipes/wrangles/test_extract_dimensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""
Recipe-level wiring tests for extract.dimensions.

Fully offline: the plain wrangles.extract.dimensions() function is mocked,
so these tests exercise only the recipe wrangle's input/output column
handling - not the NOOA integration itself (see
tests/test_nooa_extract_dimensions.py for that).
"""
import pandas as pd
import pytest
import wrangles
from unittest.mock import patch


class TestExtractDimensions:
@patch("wrangles.recipe_wrangles.extract._extract.dimensions")
def test_single_input_column(self, dimensions):
dimensions.return_value = [
{"measurements": []},
{"measurements": [{"kind": "length", "value": 6, "unit": "m", "source": "6m cable"}]},
]
data = pd.DataFrame({"description": ["wrench 25mm", "6m cable"]})
recipe = """
wrangles:
- extract.dimensions:
input: description
output: Dimensions
model: gpt-5-mini
api_key: test-key
"""

result = wrangles.recipe.run(recipe, dataframe=data)

# Single input column -> raw column values passed through, not records
dimensions.assert_called_once()
assert dimensions.call_args.args[0] == ["wrench 25mm", "6m cable"]
assert result["Dimensions"].tolist() == [
{"measurements": []},
{"measurements": [{"kind": "length", "value": 6, "unit": "m", "source": "6m cable"}]},
]

@patch("wrangles.recipe_wrangles.extract._extract.dimensions")
def test_multiple_input_columns_combined_as_records(self, dimensions):
dimensions.return_value = [{"measurements": []}]
data = pd.DataFrame({
"Description": ["Bottle"],
"Size": ["750 mL"],
})
recipe = """
wrangles:
- extract.dimensions:
input:
- Description
- Size
output: Dimensions
api_key: test-key
"""

wrangles.recipe.run(recipe, dataframe=data)

rows = dimensions.call_args.args[0]
assert rows == [{"Description": "Bottle", "Size": "750 mL"}]

@patch("wrangles.recipe_wrangles.extract._extract.dimensions")
def test_omitted_input_uses_all_columns(self, dimensions):
dimensions.return_value = [{"measurements": []}]
data = pd.DataFrame({"Description": ["Bottle"], "Packaging": ["Boxed"]})
recipe = """
wrangles:
- extract.dimensions:
output: Dimensions
api_key: test-key
"""

wrangles.recipe.run(recipe, dataframe=data)

rows = dimensions.call_args.args[0]
assert rows == [{"Description": "Bottle", "Packaging": "Boxed"}]

@patch("wrangles.recipe_wrangles.extract._extract.dimensions")
def test_model_api_key_and_threads_forwarded(self, dimensions):
dimensions.return_value = [{"measurements": []}]
data = pd.DataFrame({"description": ["wrench 25mm"]})
recipe = """
wrangles:
- extract.dimensions:
input: description
output: Dimensions
model: gpt-5.4-mini
api_key: ${API_KEY}
threads: 4
"""

wrangles.recipe.run(recipe, dataframe=data, variables={"API_KEY": "secret"})

kwargs = dimensions.call_args.kwargs
assert kwargs["model"] == "gpt-5.4-mini"
assert kwargs["api_key"] == "secret"
assert kwargs["threads"] == 4

def test_missing_output_is_rejected(self):
data = pd.DataFrame({"description": ["wrench 25mm"]})
recipe = """
wrangles:
- extract.dimensions:
input: description
api_key: test-key
"""
with pytest.raises(Exception):
wrangles.recipe.run(recipe, dataframe=data)
Loading
Loading