#93 Add tests for the QueryProcessor.
Merged 5 years ago by mikem. Opened 5 years ago by ralph.

@@ -0,0 +1,107 @@ 

+ 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):

+         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):

+         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'})

+ 

Slow and steady wins the race.

rebased

5 years ago

I disagree with a number of these comments. This class to construct a query in multiple steps. An error can be deferred until execute time.
Also, this....

koji=> select;
--
(1 row)

Thanks @mikem. I scrubbed those comments in a62e153.

rebased

5 years ago

Pull-Request has been merged by mikem

5 years ago
Metadata