@@ -112,6 +112,32 @@ def empty_bf_df(
112112 return session .read_pandas (empty_pandas_df )
113113
114114
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+
115141def _assert_html_matches_pandas_slice (
116142 table_html : str ,
117143 expected_pd_slice : pd .DataFrame ,
@@ -461,46 +487,43 @@ def test_widget_row_count_should_be_immutable_after_creation(
461487 assert widget .row_count == initial_row_count
462488
463489
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 ,
486506):
487507 """
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.
490510 """
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.
495513 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+ ),
497518 )
498519
499520 with bf .option_context ("display.repr_mode" , "anywidget" ):
500521 from bigframes .display import TableWidget
501522
523+ # The widget should handle the faulty data from the mock without crashing.
502524 widget = TableWidget (paginated_bf_df )
503525
526+ # The key assertion: The widget safely defaults to 0 rows.
504527 assert widget .row_count == 0
505528
506529
0 commit comments