From 6bbc1a312df195ddbd8f50f67e7d666892f6491f Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Jun 09 2016 13:16:18 +0000 Subject: [PATCH 1/2] Add tests for the QueryProcessor. --- diff --git a/tests/test_hub/test_query_processor.py b/tests/test_hub/test_query_processor.py new file mode 100644 index 0000000..5525aa0 --- /dev/null +++ b/tests/test_hub/test_query_processor.py @@ -0,0 +1,111 @@ +import unittest +import mock + +import kojihub + + +class TestQueryProcessor(unittest.TestCase): + def setUp(self): + self.simple_arguments = dict( + columns=['something'], + tables=['awesome'], + ) + self.complex_arguments = dict( + columns=['something'], + aliases=['other'], + tables=['awesome'], + joins=['morestuff'], + #values=... + #transform=... + opts={ + #'countOnly': True, + 'order': 'other', + 'offset': 10, + 'limit': 3, + #'rowlock': True, + }, + ) + self.original_chunksize = kojihub.QueryProcessor.iterchunksize + kojihub.QueryProcessor.iterchunksize = 2 + + def tearDown(self): + kojihub.QueryProcessor.iterchunksize = self.original_chunksize + + def test_basic_instantiation(self): + # TODO -- this doesn't make sense. A query with no arguments should + # probably raise an exception saying "this doesn't make sense." + kojihub.QueryProcessor() # No exception! + + def test_instantiation_with_cols_and_aliases(self): + proc = kojihub.QueryProcessor(columns=['wat'], aliases=['zap']) + assert 'zap' in proc.colsByAlias + assert proc.colsByAlias['zap'] == 'wat' + assert len(proc.colsByAlias) == 1 + + def test_empty_as_string(self): + # This should probably raise an exception, but it does not. + # What is a query if it has no arguments. Nonsense! + proc = kojihub.QueryProcessor() + actual = str(proc) + self.assertIn("SELECT", actual) + self.assertIn("FROM", actual) + + def test_simple_as_string(self): + proc = kojihub.QueryProcessor( + columns=['something'], + tables=['awesome'], + ) + actual = " ".join([token for token in str(proc).split() if token]) + expected = "SELECT something FROM awesome" + self.assertEqual(actual, expected) + + def test_complex_as_string(self): + proc = kojihub.QueryProcessor(**self.complex_arguments) + actual = " ".join([token for token in str(proc).split() if token]) + expected = "SELECT something FROM awesome JOIN morestuff ORDER BY something OFFSET 10 LIMIT 3" + self.assertEqual(actual, expected) + + @mock.patch('kojihub.context') + def test_simple_with_execution(self, context): + cursor = mock.MagicMock() + context.cnx.cursor.return_value = cursor + proc = kojihub.QueryProcessor(**self.simple_arguments) + proc.execute() + cursor.execute.assert_called_once_with('\nSELECT something\n FROM awesome\n\n\n \n\n \n', {}) + + @mock.patch('kojihub.context') + def test_simple_count_with_execution(self, context): + cursor = mock.MagicMock() + context.cnx.cursor.return_value = cursor + cursor.fetchall.return_value = [('some count',)] + args = self.simple_arguments.copy() + args['opts'] = {'countOnly': True} + proc = kojihub.QueryProcessor(**args) + results = proc.execute() + cursor.execute.assert_called_once_with('\nSELECT count(*)\n FROM awesome\n\n\n \n\n \n', {}) + self.assertEqual(results, 'some count') + + @mock.patch('kojihub.context') + def test_simple_execution_with_iterate(self, context): + cursor = mock.MagicMock() + context.cnx.cursor.return_value = cursor + cursor.fetchall.return_value = [ + ('value number 1',), + ('value number 2',), + ('value number 3',), + ] + proc = kojihub.QueryProcessor(**self.simple_arguments) + generator = proc.iterate() + calls = cursor.execute.mock_calls + result = next(generator) + # two calls so far.. + self.assertEqual(result, {'something': 'value number 1'}) + self.assertEqual(len(calls), 2) + result = next(generator) + # still two. + self.assertEqual(result, {'something': 'value number 2'}) + self.assertEqual(len(calls), 2) + # now three. + result = next(generator) + self.assertEqual(result, {'something': 'value number 3'}) + From a62e15324cc2381ad06ac2bb62ea33b3b0c2d805 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Jun 09 2016 13:17:34 +0000 Subject: [PATCH 2/2] Scrub comments based on feedback from @mikem in #93. --- diff --git a/tests/test_hub/test_query_processor.py b/tests/test_hub/test_query_processor.py index 5525aa0..7b229bd 100644 --- a/tests/test_hub/test_query_processor.py +++ b/tests/test_hub/test_query_processor.py @@ -32,8 +32,6 @@ class TestQueryProcessor(unittest.TestCase): kojihub.QueryProcessor.iterchunksize = self.original_chunksize def test_basic_instantiation(self): - # TODO -- this doesn't make sense. A query with no arguments should - # probably raise an exception saying "this doesn't make sense." kojihub.QueryProcessor() # No exception! def test_instantiation_with_cols_and_aliases(self): @@ -43,8 +41,6 @@ class TestQueryProcessor(unittest.TestCase): assert len(proc.colsByAlias) == 1 def test_empty_as_string(self): - # This should probably raise an exception, but it does not. - # What is a query if it has no arguments. Nonsense! proc = kojihub.QueryProcessor() actual = str(proc) self.assertIn("SELECT", actual)