diff --git a/tests/test_postgrestclient.py b/tests/test_postgrestclient.py index 265b046d7aae392cb8f550591194556558ea1ca2..33eeed59629bd62d06d3e0f9e24fccfca9ea38b9 100644 --- a/tests/test_postgrestclient.py +++ b/tests/test_postgrestclient.py @@ -258,104 +258,15 @@ class TestPgrestClientFilterStrategyNone(TestCase): @Mocker() -class TestPgrestClientFilterStrategyExact(TestCase): +class TestPgrestClientFilterCountingStrategies(TestCase): def setUp(self): super().setUp() self.data = SUPERHERO_TEST_DATA - - def test_fetch_all_first(self, mock): - # in order to fetch all - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers=DEFAULT_HEADERS, - status_code=200, - reason='OK', - json=self.data + self.counting_strategies = ( + postgrestutils.Count.EXACT, + postgrestutils.Count.PLANNED, + postgrestutils.Count.ESTIMATED ) - with default_session(count=postgrestutils.Count.EXACT) as s: - res = s.filter('superhero') - - self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object - self.assertFalse(mock.called) # no request should have been made yet - - self.assertEqual(list(res), self.data) # fetch data - self.assertTrue(mock.called_once) # should have been called once - self.assertEqual(res._result_cache, self.data) # fetched data should be cached - self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should also be cached - self.assertEqual(list(res), self.data) # should utilize cache - self.assertEqual(res[:1], self.data[:1]) # should utilize cache - self.assertEqual(res[:0], self.data[:0]) # should return empty list - self.assertEqual(res[4:2], self.data[4:2]) # should return empty list - self.assertEqual(res[2:], self.data[2:]) # should utilize cache - self.assertEqual(res[0], self.data[0]) # should utilize cache - self.assertTrue(mock.called_once) # should not have been called again - - def test_fetch_len_first(self, mock): - # in order to fetch all - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers=DEFAULT_HEADERS, - status_code=200, - reason='OK', - json=self.data - ) - # in order to fetch first - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={**DEFAULT_HEADERS, **{'Range-Unit': 'items', 'Range': '0-0'}}, - status_code=200, - reason='OK', - headers={'Content-Range': '0-0/*'}, - json=[self.data[0]] - ) - # in order to fetch range since index 2 - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={**DEFAULT_HEADERS, **{'Range-Unit': 'items', 'Range': '2-'}}, - status_code=200, - reason='OK', - headers={'Content-Range': '2-4/*'}, - json=self.data[2:] - ) - # in order to fetch length - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={**DEFAULT_HEADERS, **{'Range-Unit': 'items', 'Range': '0-0', 'Prefer': 'count=exact'}}, - status_code=206, - reason='Partial Content', - headers={'Content-Range': '0-0/5'}, - json=self.data[0] - ) - with default_session(count=postgrestutils.Count.EXACT) as s: - res = s.filter('superhero') - - self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object - self.assertFalse(mock.called) # no request should have been made yet - - self.assertEqual(len(res), len(self.data)) # should fetch len - self.assertTrue(mock.called_once) # should have been called once - self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should be cached - self.assertEqual(res[:1], self.data[:1]) # should fetch first element as range - self.assertEqual(res[:0], self.data[:0]) # should return empty list - self.assertEqual(res[4:2], self.data[4:2]) # should return empty list - self.assertEqual(res[2:], self.data[2:]) # should fetch range starting at index 2 - self.assertEqual(res[0], self.data[0]) # should fetch first element as range but return dict - self.assertEqual(list(res), self.data) # should fetch all elements - self.assertEqual(res._result_cache, self.data) # should cache all elements - self.assertTrue(mock.called) # should have been called at least once - self.assertEqual(mock.call_count, 5) # should have been called 5 times (fetch len, range, first and all) - - -@Mocker() -class TestPgrestClientFilterStrategyPlanned(TestCase): - def setUp(self): - super().setUp() - self.data = SUPERHERO_TEST_DATA def test_fetch_all_first(self, mock): # in order to fetch all @@ -367,117 +278,26 @@ class TestPgrestClientFilterStrategyPlanned(TestCase): reason='OK', json=self.data ) - with default_session(count=postgrestutils.Count.PLANNED) as s: - res = s.filter('superhero') - - self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object - self.assertFalse(mock.called) # no request should have been made yet - - self.assertEqual(list(res), self.data) # fetch data - self.assertTrue(mock.called_once) # should have been called once - self.assertEqual(res._result_cache, self.data) # fetched data should be cached - self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should also be cached - self.assertEqual(list(res), self.data) # should utilize cache - self.assertEqual(res[:1], self.data[:1]) # should utilize cache - self.assertEqual(res[:0], self.data[:0]) # should return empty list - self.assertEqual(res[4:2], self.data[4:2]) # should return empty list - self.assertEqual(res[2:], self.data[2:]) # should utilize cache - self.assertEqual(res[0], self.data[0]) # should utilize cache - self.assertTrue(mock.called_once) # should not have been called again - - def test_fetch_len_first(self, mock): - # in order to fetch all - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers=DEFAULT_HEADERS, - status_code=200, - reason='OK', - json=self.data - ) - # in order to fetch first - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={**DEFAULT_HEADERS, **{'Range-Unit': 'items', 'Range': '0-0'}}, - status_code=200, - reason='OK', - headers={'Content-Range': '0-0/*'}, - json=[self.data[0]] - ) - # in order to fetch range since index 2 - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={**DEFAULT_HEADERS, **{'Range-Unit': 'items', 'Range': '2-'}}, - status_code=200, - reason='OK', - headers={'Content-Range': '2-4/*'}, - json=self.data[2:] - ) - # in order to fetch length - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={**DEFAULT_HEADERS, **{'Range-Unit': 'items', 'Range': '0-0', 'Prefer': 'count=planned'}}, - status_code=206, - reason='Partial Content', - headers={'Content-Range': '0-0/5'}, - json=self.data[0] - ) - with default_session(count=postgrestutils.Count.PLANNED) as s: - res = s.filter('superhero') - - self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object - self.assertFalse(mock.called) # no request should have been made yet - - self.assertEqual(len(res), len(self.data)) # should fetch len - self.assertTrue(mock.called_once) # should have been called once - self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should be cached - self.assertEqual(res[:1], self.data[:1]) # should fetch first element as range - self.assertEqual(res[:0], self.data[:0]) # should return empty list - self.assertEqual(res[4:2], self.data[4:2]) # should return empty list - self.assertEqual(res[2:], self.data[2:]) # should fetch range starting at index 2 - self.assertEqual(res[0], self.data[0]) # should fetch first element as range but return dict - self.assertEqual(list(res), self.data) # should fetch all elements - self.assertEqual(res._result_cache, self.data) # should cache all elements - self.assertTrue(mock.called) # should have been called at least once - self.assertEqual(mock.call_count, 5) # should have been called 5 times (fetch len, range, first and all) + for strategy in self.counting_strategies: + mock.reset() + with default_session(count=strategy) as s: + res = s.filter('superhero') + self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object + self.assertFalse(mock.called) # no request should have been made yet -@Mocker() -class TestPgrestClientFilterStrategyEstimated(TestCase): - def setUp(self): - super().setUp() - self.data = SUPERHERO_TEST_DATA + self.assertEqual(list(res), self.data) # fetch data + self.assertTrue(mock.called_once) # should have been called once + self.assertEqual(res._result_cache, self.data) # fetched data should be cached + self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should be cached - def test_fetch_all_first(self, mock): - # in order to fetch all - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers=DEFAULT_HEADERS, - status_code=200, - reason='OK', - json=self.data - ) - with default_session(count=postgrestutils.Count.ESTIMATED) as s: - res = s.filter('superhero') - - self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object - self.assertFalse(mock.called) # no request should have been made yet - - self.assertEqual(list(res), self.data) # fetch data - self.assertTrue(mock.called_once) # should have been called once - self.assertEqual(res._result_cache, self.data) # fetched data should be cached - self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should also be cached - self.assertEqual(list(res), self.data) # should utilize cache - self.assertEqual(res[:1], self.data[:1]) # should utilize cache - self.assertEqual(res[:0], self.data[:0]) # should return empty list - self.assertEqual(res[4:2], self.data[4:2]) # should return empty list - self.assertEqual(res[2:], self.data[2:]) # should utilize cache - self.assertEqual(res[0], self.data[0]) # should utilize cache - self.assertTrue(mock.called_once) # should not have been called again + self.assertEqual(list(res), self.data) # should utilize cache + self.assertEqual(res[:1], self.data[:1]) # should utilize cache + self.assertEqual(res[:0], self.data[:0]) # should return empty list + self.assertEqual(res[4:2], self.data[4:2]) # should return empty list + self.assertEqual(res[2:], self.data[2:]) # should utilize cache + self.assertEqual(res[0], self.data[0]) # should utilize cache + self.assertTrue(mock.called_once) # should not have been called again def test_fetch_len_first(self, mock): # in order to fetch all @@ -509,37 +329,44 @@ class TestPgrestClientFilterStrategyEstimated(TestCase): headers={'Content-Range': '2-4/*'}, json=self.data[2:] ) - # in order to fetch length - mock.register_uri( - 'GET', - 'http://example.com/superhero', - request_headers={ - **DEFAULT_HEADERS, - **{'Range-Unit': 'items', 'Range': '0-0', 'Prefer': 'count=estimated'} - }, - status_code=206, - reason='Partial Content', - headers={'Content-Range': '0-0/5'}, - json=self.data[0] - ) - with default_session(count=postgrestutils.Count.ESTIMATED) as s: - res = s.filter('superhero') - - self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object - self.assertFalse(mock.called) # no request should have been made yet + # in order to fetch length using different strategies + for strategy in self.counting_strategies: + mock.register_uri( + 'GET', + 'http://example.com/superhero', + request_headers={ + **DEFAULT_HEADERS, + **{'Range-Unit': 'items', 'Range': '0-0', 'Prefer': 'count={}'.format(strategy.value)} + }, + status_code=206, + reason='Partial Content', + headers={'Content-Range': '0-0/5'}, + json=self.data[0] + ) + mock.reset() - self.assertEqual(len(res), len(self.data)) # should fetch len - self.assertTrue(mock.called_once) # should have been called once - self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should be cached - self.assertEqual(res[:1], self.data[:1]) # should fetch first element as range - self.assertEqual(res[:0], self.data[:0]) # should return empty list - self.assertEqual(res[4:2], self.data[4:2]) # should return empty list - self.assertEqual(res[2:], self.data[2:]) # should fetch range starting at index 2 - self.assertEqual(res[0], self.data[0]) # should fetch first element as range but return dict - self.assertEqual(list(res), self.data) # should fetch all elements - self.assertEqual(res._result_cache, self.data) # should cache all elements - self.assertTrue(mock.called) # should have been called at least once - self.assertEqual(mock.call_count, 5) # should have been called 5 times (fetch len, range, first and all) + with default_session(count=strategy) as s: + res = s.filter('superhero') + + self.assertIsInstance(res, postgrestutils.JsonResultSet) # should return lazy object + self.assertFalse(mock.called) # no request should have been made yet + + self.assertEqual(len(res), len(self.data)) # should fetch len + self.assertTrue(mock.called_once) # should have been called once + self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should be cached + + self.assertEqual(res[:1], self.data[:1]) # should fetch first element as range + self.assertEqual(res[:0], self.data[:0]) # should return empty list + self.assertEqual(res[4:2], self.data[4:2]) # should return empty list + self.assertEqual(res[2:], self.data[2:]) # should fetch range starting at index 2 + self.assertEqual(res[0], self.data[0]) # should fetch first element as range but return dict + self.assertEqual(list(res), self.data) # should fetch all elements + self.assertEqual(res._result_cache, self.data) # should fetch all elements + self.assertEqual(res._result_cache, self.data) # should cache all elements + self.assertTrue(mock.called) # should have been called at least once + # should have been called 5 times (fetch len, fetch 2 ranges, + # fetch first and fetch all) + self.assertEqual(mock.call_count, 5) @Mocker()