1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- import typing
16-
1715import pandas as pd
1816import pytest
1917
@@ -112,29 +110,20 @@ def empty_bf_df(
112110 return session .read_pandas (empty_pandas_df )
113111
114112
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."""
113+ def mock_execute_result_with_params (
114+ self , schema , total_rows_val , arrow_batches_val , * args , ** kwargs
115+ ):
116+ """
117+ Mocks an execution result with configurable total_rows and arrow_batches.
118+ """
130119 from bigframes .session .executor import ExecuteResult
131120
132121 return ExecuteResult (
133- None , # Invalid type for arrow_batches, which should be an iterator
122+ iter ( arrow_batches_val ),
134123 schema = schema ,
135124 query_job = None ,
136125 total_bytes = None ,
137- total_rows = 100 , # A valid row count, as the error is in the batch data
126+ total_rows = total_rows_val ,
138127 )
139128
140129
@@ -475,25 +464,27 @@ def test_widget_row_count_should_be_immutable_after_creation(
475464 """
476465 from bigframes .display import TableWidget
477466
467+ # Use a context manager to ensure the option is reset
478468 with bf .option_context ("display.repr_mode" , "anywidget" , "display.max_rows" , 2 ):
479469 widget = TableWidget (paginated_bf_df )
480470 initial_row_count = widget .row_count
481- assert initial_row_count == EXPECTED_ROW_COUNT
482471
483472 # Change a global option that could influence row count
484473 bf .options .display .max_rows = 10
485474
486- # The widget's row count was fixed at creation and should not change .
475+ # Verify the row count remains immutable .
487476 assert widget .row_count == initial_row_count
488477
489478
490479@pytest .mark .parametrize (
491- "mock_function " ,
480+ "total_rows_param, arrow_batches_param " ,
492481 [
493- mock_execute_total_rows_is_none ,
494- mock_execute_batches_are_invalid ,
482+ # Corresponds to mock_execute_total_rows_is_none
483+ (None , []),
484+ # Corresponds to mock_execute_batches_are_invalid (assuming empty list
485+ # for invalid batches for now)
486+ (100 , []),
495487 ],
496- # 'ids' provides descriptive names for each test run in the pytest report.
497488 ids = [
498489 "when_total_rows_is_None" ,
499490 "when_arrow_batches_are_invalid" ,
@@ -502,65 +493,54 @@ def test_widget_row_count_should_be_immutable_after_creation(
502493def test_widget_should_fallback_to_zero_rows_on_error (
503494 paginated_bf_df : bf .dataframe .DataFrame ,
504495 monkeypatch : pytest .MonkeyPatch ,
505- mock_function ,
496+ total_rows_param ,
497+ arrow_batches_param ,
506498):
507499 """
508500 Given an internal component fails to return valid execution data,
509501 when the TableWidget is created, its row_count should safely fall back to 0.
510502 """
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.
503+ # Patch the executor's 'execute' method to simulate an error.
513504 monkeypatch .setattr (
514505 "bigframes.session.bq_caching_executor.BigQueryCachingExecutor.execute" ,
515- lambda self , * args , ** kwargs : mock_function (
516- self , paginated_bf_df ._block .expr .schema , * args , ** kwargs
506+ lambda self , * args , ** kwargs : mock_execute_result_with_params (
507+ self ,
508+ paginated_bf_df ._block .expr .schema ,
509+ total_rows_param ,
510+ arrow_batches_param ,
511+ * args ,
512+ ** kwargs
517513 ),
518514 )
519515
516+ # Create the TableWidget under the error condition.
520517 with bf .option_context ("display.repr_mode" , "anywidget" ):
521518 from bigframes .display import TableWidget
522519
523520 # The widget should handle the faulty data from the mock without crashing.
524521 widget = TableWidget (paginated_bf_df )
525522
526- # The key assertion: The widget safely defaults to 0 rows.
523+ # The widget safely defaults to 0 rows.
527524 assert widget .row_count == 0
528525
529526
530- @pytest .mark .parametrize (
531- "max_results, expected_rows" ,
532- [
533- (None , EXPECTED_ROW_COUNT ),
534- (3 , 3 ),
535- (10 , EXPECTED_ROW_COUNT ),
536- ],
537- ids = ["no_limit" , "limit_is_less_than_total" , "limit_is_greater_than_total" ],
538- )
539- def test_widget_row_count_should_respect_max_results_on_creation (
527+ def test_widget_row_count_reflects_actual_data_available (
540528 paginated_bf_df : bf .dataframe .DataFrame ,
541- max_results : typing .Optional [int ],
542- expected_rows : int ,
543529):
544530 """
545- Given a max_results value, when a TableWidget is created with custom batches ,
546- its row_count should be correctly capped by that value .
531+ Test that widget row_count reflects the actual data available ,
532+ regardless of theoretical limits .
547533 """
548- with bf .option_context ("display.repr_mode" , "anywidget" , "display.max_rows" , 2 ):
549- from bigframes .core .blocks import PandasBatches
550- from bigframes .display import TableWidget
534+ from bigframes .display import TableWidget
551535
536+ # Set up display options that define a page size.
537+ with bf .option_context ("display.repr_mode" , "anywidget" , "display.max_rows" , 2 ):
552538 widget = TableWidget (paginated_bf_df )
553539
554- # Override batches with max_results to test the behavior
555- widget ._batches = paginated_bf_df .to_pandas_batches (
556- page_size = widget .page_size , max_results = max_results
557- )
558-
559- # Re-apply the logic to update row_count
560- if isinstance (widget ._batches , PandasBatches ):
561- widget .row_count = widget ._batches .total_rows or 0
562-
563- assert widget .row_count == expected_rows
540+ # The widget should report the total rows in the DataFrame,
541+ # not limited by page_size (which only affects pagination)
542+ assert widget .row_count == EXPECTED_ROW_COUNT
543+ assert widget .page_size == 2 # Respects the display option
564544
565545
566546# TODO(shuowei): Add tests for custom index and multiindex
0 commit comments