def _scan_test_helper(self, row_limits=(None, None), row_prefix=None,
                          columns=None, filter_=None, timestamp=None,
                          include_timestamp=False, limit=None, rr_result=None,
                          expected_result=None):
        import types
        from gcloud._testing import _Monkey
        from gcloud.bigtable.happybase import table as MUT

        name = 'table-name'
        row_start, row_stop = row_limits
        connection = None
        table = self._makeOne(name, connection)
        table._low_level_table = _MockLowLevelTable()
        rr_result = rr_result or _MockPartialRowsData()
        table._low_level_table.read_rows_result = rr_result
        self.assertEqual(rr_result.consume_next_calls, 0)

        # Set-up mocks.
        fake_col_filter = object()
        mock_columns = []

        def mock_columns_filter_helper(*args):
            mock_columns.append(args)
            return fake_col_filter

        fake_filter = object()
        mock_filters = []

        def mock_filter_chain_helper(**kwargs):
            mock_filters.append(kwargs)
            return fake_filter

        with _Monkey(MUT, _filter_chain_helper=mock_filter_chain_helper,
                     _columns_filter_helper=mock_columns_filter_helper):
            result = table.scan(row_start=row_start, row_stop=row_stop,
                                row_prefix=row_prefix, columns=columns,
                                filter=filter_, timestamp=timestamp,
                                include_timestamp=include_timestamp,
                                limit=limit)
            self.assertTrue(isinstance(result, types.GeneratorType))
            # Need to consume the result while the monkey patch is applied.
            # read_rows_result == Empty PartialRowsData --> No results.
            expected_result = expected_result or []
            self.assertEqual(list(result), expected_result)

        read_rows_args = ()
        if row_prefix:
            row_start = row_prefix
            row_stop = MUT._string_successor(row_prefix)
        read_rows_kwargs = {
            'end_key': row_stop,
            'filter_': fake_filter,
            'limit': limit,
            'start_key': row_start,
        }
        self.assertEqual(table._low_level_table.read_rows_calls, [
            (read_rows_args, read_rows_kwargs),
        ])
        self.assertEqual(rr_result.consume_next_calls,
                         rr_result.iterations + 1)

        if columns is not None:
            self.assertEqual(mock_columns, [(columns,)])
        else:
            self.assertEqual(mock_columns, [])

        filters = []
        if filter_ is not None:
            filters.append(filter_)
        if columns:
            filters.append(fake_col_filter)
        expected_kwargs = {
            'filters': filters,
            'versions': 1,
            'timestamp': timestamp,
        }
        self.assertEqual(mock_filters, [expected_kwargs])
 def _callFUT(self, *args, **kwargs):
     from gcloud.bigtable.happybase.table import _string_successor
     return _string_successor(*args, **kwargs)