Skip to content

Commit 37554fa

Browse files
Add test for range_timestamp_dtype in type_mapper
This commit adds a new test case to `tests/unit/test__pandas_helpers.py` to cover the `range_timestamp_dtype` branch in the `default_types_mapper` function. Due to issues importing `RangeTIMESTAMPDtype` directly, a mock class (`MockRangeTSDtype`) was used to simulate the necessary `pyarrow_dtype` attribute for the test. This ensures the logic of the `default_types_mapper` for `range_timestamp_dtype` is correctly tested. The `pragma: NO COVER` comment associated with this branch in `google/cloud/bigquery/_pandas_helpers.py` has been removed as the branch is now covered by this new test. All existing tests continue to pass.
1 parent b863291 commit 37554fa

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

google/cloud/bigquery/_pandas_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ def types_mapper(arrow_data_type):
341341
# recognized by coverage, hence the pragma. See Issue: #2132
342342
elif (
343343
range_timestamp_dtype is not None
344-
and arrow_data_type.equals( # pragma: NO COVER
344+
and arrow_data_type.equals(
345345
range_timestamp_dtype.pyarrow_dtype
346346
)
347347
):

tests/unit/test__pandas_helpers.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from google.cloud.bigquery import _versions_helpers
5252
from google.cloud.bigquery import schema
5353
from google.cloud.bigquery._pandas_helpers import determine_requested_streams
54+
# from google.cloud.bigquery.dtypes import RangeTIMESTAMPDtype # Commented out as it causes ImportError and test uses a mock
5455

5556
pyarrow = _versions_helpers.PYARROW_VERSIONS.try_import()
5657

@@ -1294,6 +1295,51 @@ def test_dataframe_to_bq_schema_returns_schema_with_pandas_gbq(
12941295
assert got is not None
12951296

12961297

1298+
@pytest.mark.skipif(isinstance(pyarrow, mock.Mock), reason="Requires `pyarrow`")
1299+
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`") # default_types_mapper is pandas-specific
1300+
def test_default_types_mapper_range_timestamp(module_under_test):
1301+
"""Test default_types_mapper with a mock RangeTIMESTAMPDtype."""
1302+
1303+
# Define a duck-typed class that mimics RangeTIMESTAMPDtype's structure
1304+
# for the purpose of this test, as the actual class import is problematic.
1305+
class MockRangeTSDtype:
1306+
def __init__(self):
1307+
self.pyarrow_dtype = pyarrow.struct(
1308+
[
1309+
("start", pyarrow.timestamp("us", tz="UTC")),
1310+
("end", pyarrow.timestamp("us", tz="UTC")),
1311+
]
1312+
)
1313+
1314+
def __eq__(self, other):
1315+
if not isinstance(other, MockRangeTSDtype):
1316+
return NotImplemented
1317+
return self.pyarrow_dtype == other.pyarrow_dtype
1318+
1319+
# PyArrow dtype that the mapper will receive
1320+
range_timestamp_pyarrow_dtype = pyarrow.struct(
1321+
[
1322+
("start", pyarrow.timestamp("us", tz="UTC")),
1323+
("end", pyarrow.timestamp("us", tz="UTC")),
1324+
]
1325+
)
1326+
1327+
# Instantiate the mock RangeTIMESTAMPDtype
1328+
mock_range_ts_dtype = MockRangeTSDtype()
1329+
1330+
# Get the mapper function from the module_under_test fixture
1331+
mapper = module_under_test.default_types_mapper(
1332+
range_timestamp_dtype=mock_range_ts_dtype
1333+
)
1334+
1335+
# Call the mapper with the created PyArrow struct
1336+
result_dtype = mapper(range_timestamp_pyarrow_dtype)
1337+
1338+
# Assert the result
1339+
assert isinstance(result_dtype, MockRangeTSDtype)
1340+
assert result_dtype == mock_range_ts_dtype
1341+
1342+
12971343
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
12981344
def test_dataframe_to_bq_schema_w_named_index(module_under_test, monkeypatch):
12991345
monkeypatch.setattr(module_under_test, "pandas_gbq", None)

0 commit comments

Comments
 (0)