@@ -112,6 +112,32 @@ def empty_bf_df(
112
112
return session .read_pandas (empty_pandas_df )
113
113
114
114
115
+ def mock_execute_total_rows_is_none (self , schema , * args , ** kwargs ):
116
+ """Mocks an execution result where the total row count is missing."""
117
+ from bigframes .session .executor import ExecuteResult
118
+
119
+ return ExecuteResult (
120
+ iter ([]), # arrow_batches
121
+ schema = schema ,
122
+ query_job = None ,
123
+ total_bytes = None ,
124
+ total_rows = None , # The specific failure condition for this case
125
+ )
126
+
127
+
128
+ def mock_execute_batches_are_invalid (self , schema , * args , ** kwargs ):
129
+ """Mocks an execution result where the batch data is an invalid type."""
130
+ from bigframes .session .executor import ExecuteResult
131
+
132
+ return ExecuteResult (
133
+ None , # Invalid type for arrow_batches, which should be an iterator
134
+ schema = schema ,
135
+ query_job = None ,
136
+ total_bytes = None ,
137
+ total_rows = 100 , # A valid row count, as the error is in the batch data
138
+ )
139
+
140
+
115
141
def _assert_html_matches_pandas_slice (
116
142
table_html : str ,
117
143
expected_pd_slice : pd .DataFrame ,
@@ -461,46 +487,43 @@ def test_widget_row_count_should_be_immutable_after_creation(
461
487
assert widget .row_count == initial_row_count
462
488
463
489
464
- def test_widget_should_fallback_to_zero_rows_when_total_rows_is_none (
465
- paginated_bf_df : bf .dataframe .DataFrame , monkeypatch : pytest .MonkeyPatch
466
- ):
467
- """
468
- Given an internal component that fails to provide a total row count,
469
- when the widget is created, the row_count should safely fall back to 0.
470
- """
471
- from bigframes .core .blocks import PandasBatches
472
-
473
- # Simulate an internal failure where total_rows returns None
474
- monkeypatch .setattr (PandasBatches , "total_rows" , property (lambda self : None ))
475
-
476
- with bf .option_context ("display.repr_mode" , "anywidget" ):
477
- from bigframes .display import TableWidget
478
-
479
- widget = TableWidget (paginated_bf_df )
480
-
481
- assert widget .row_count == 0
482
-
483
-
484
- def test_widget_should_fallback_to_zero_rows_when_batches_are_invalid_type (
485
- paginated_bf_df : bf .dataframe .DataFrame , monkeypatch : pytest .MonkeyPatch
490
+ @pytest .mark .parametrize (
491
+ "mock_function" ,
492
+ [
493
+ mock_execute_total_rows_is_none ,
494
+ mock_execute_batches_are_invalid ,
495
+ ],
496
+ # 'ids' provides descriptive names for each test run in the pytest report.
497
+ ids = [
498
+ "when_total_rows_is_None" ,
499
+ "when_arrow_batches_are_invalid" ,
500
+ ],
501
+ )
502
+ def test_widget_should_fallback_to_zero_rows_on_error (
503
+ paginated_bf_df : bf .dataframe .DataFrame ,
504
+ monkeypatch : pytest .MonkeyPatch ,
505
+ mock_function ,
486
506
):
487
507
"""
488
- Given an internal component that returns an unexpected data type ,
489
- when the widget is created, the row_count should safely fall back to 0.
508
+ Given an internal component fails to return valid execution data ,
509
+ when the TableWidget is created, its row_count should safely fall back to 0.
490
510
"""
491
- # Simulate internal method returning an unexpected type (a simple iterator)
492
- def mock_to_pandas_batches (self , ** kwargs ):
493
- return iter ([paginated_bf_df .to_pandas ().iloc [:2 ]])
494
-
511
+ # The 'self' argument is automatically handled when monkeypatch calls the method.
512
+ # We use a lambda to pass the DataFrame's schema to our mock function.
495
513
monkeypatch .setattr (
496
- "bigframes.dataframe.DataFrame.to_pandas_batches" , mock_to_pandas_batches
514
+ "bigframes.session.bq_caching_executor.BigQueryCachingExecutor.execute" ,
515
+ lambda self , * args , ** kwargs : mock_function (
516
+ self , paginated_bf_df ._block .expr .schema , * args , ** kwargs
517
+ ),
497
518
)
498
519
499
520
with bf .option_context ("display.repr_mode" , "anywidget" ):
500
521
from bigframes .display import TableWidget
501
522
523
+ # The widget should handle the faulty data from the mock without crashing.
502
524
widget = TableWidget (paginated_bf_df )
503
525
526
+ # The key assertion: The widget safely defaults to 0 rows.
504
527
assert widget .row_count == 0
505
528
506
529
0 commit comments