Пример #1
0
    def test_init_from_object(self):
        query1 = Query.from_object([1, 3, 4, 2])
        self.assertEqual(query1.source, [1, 3, 4, 2])
        self.assertEqual(query1.args, ())
        self.assertEqual(query1.kwds, {})
        self.assertEqual(query1._query_steps, [])

        query2 = Query.from_object({'a': 1, 'b': 2})
        self.assertEqual(query2.source, {'a': 1, 'b': 2})
        self.assertEqual(query2.args, ())
        self.assertEqual(query2.kwds, {})
        self.assertEqual(query2._query_steps, [])

        # When from_object() receives a Query, it should return
        # a copy rather than trying to use it as a data object.
        query3 = Query.from_object(query2)
        self.assertIsNot(query3, query2)
        self.assertEqual(query3.source, {'a': 1, 'b': 2})
        self.assertEqual(query3.args, ())
        self.assertEqual(query3.kwds, {})
        self.assertEqual(query3._query_steps, [])

        query4 = Query.from_object('abc')
        self.assertEqual(query4.source, ['abc'], msg=\
            'Strings or non-iterables should be wrapped as a list')
        self.assertEqual(query4.args, ())
        self.assertEqual(query4.kwds, {})
        self.assertEqual(query4._query_steps, [])

        query5 = Query.from_object(123)
        self.assertEqual(query5.source, [123], msg=\
            'Strings or non-iterables should be wrapped as a list')
        self.assertEqual(query5.args, ())
        self.assertEqual(query5.kwds, {})
        self.assertEqual(query5._query_steps, [])
Пример #2
0
    def test_execute_other_source(self):
        query = Query.from_object([1, 3, 4, 2])
        result = query.execute()
        self.assertIsInstance(result, Result)
        self.assertEqual(result.fetch(), [1, 3, 4, 2])

        query = Query.from_object(iter([1, 3, 4, 2]))
        result = query.execute()
        self.assertIsInstance(result, Result)
        self.assertEqual(result.fetch(), [1, 3, 4, 2])

        query = Query.from_object(Result([1, 3, 4, 2], evaltype=list))
        result = query.execute()
        self.assertIsInstance(result, Result)
        self.assertEqual(result.fetch(), [1, 3, 4, 2])

        query = Query.from_object(Result({'a': 1, 'b': 2}, evaltype=dict))
        result = query.execute()
        self.assertIsInstance(result, Result)
        self.assertEqual(result.fetch(), {'a': 1, 'b': 2})

        query = Query.from_object(IterItems(iter([iter(['a', 1]), iter(['b', 2])])))
        result = query.execute()
        self.assertIsInstance(result, Result)
        self.assertEqual(result.fetch(), {'a': 1, 'b': 2})
Пример #3
0
    def test_flatten(self):
        query1 = Query({'col1': ('col2', 'col2')})
        query2 = query1.flatten()
        self.assertIsNot(query1, query2, 'should return new object')

        source = Select([('col1', 'col2'), ('a', '2'), ('b', '2')])
        result = query2.execute(source)
        self.assertEqual(result.fetch(), [('a', '2', '2'), ('b', '2', '2')])
Пример #4
0
    def test_starmap(self):
        query1 = Query([('col2', 'col2')])
        query2 = query1.starmap(lambda x, y: x + y)
        self.assertIsNot(query1, query2, 'should return new object')

        source = Select([('col1', 'col2'), ('a', 1), ('b', 2)])
        result = query2.execute(source)
        self.assertEqual(result.fetch(), [2, 4])
Пример #5
0
    def test_map(self):
        query1 = Query(['col2'])
        query2 = query1.map(int)
        self.assertIsNot(query1, query2, 'should return new object')

        source = Select([('col1', 'col2'), ('a', '2'), ('b', '2')])
        result = query2.execute(source)
        self.assertEqual(result.fetch(), [2, 2])
Пример #6
0
    def test_unwrap(self):
        query1 = Query({'col1': ['col2']})
        query2 = query1.unwrap()
        self.assertIsNot(query1, query2, 'should return new object')

        source = Select([('col1', 'col2'), ('a', 1), ('b', 2),  ('b', 3)])
        result = query2.execute(source)
        self.assertEqual(result.fetch(), {'a': 1, 'b': [2, 3]})
Пример #7
0
    def test_init_with_select(self):
        source = Select([('A', 'B'), (1, 2), (1, 2)])
        query = Query(source, ['A'], B=2)
        self.assertEqual(query.source, source)
        self.assertEqual(query.args, (['A'],))
        self.assertEqual(query.kwds, {'B': 2})
        self.assertEqual(query._query_steps, [])

        with self.assertRaises(TypeError):
            query = Query(None, ['foo'], bar='baz')
Пример #8
0
 def test_fetch_datasource(self):
     select = Select([('A', 'B'), ('1', '2'), ('1', '2')])
     query = Query(select, ['B'])
     query._query_steps = [
         ('map', (int,), {}),
         ('map', (lambda x: x * 2,), {}),
         ('sum', (), {}),
     ]
     result = query.fetch()
     self.assertEqual(result, 8)
Пример #9
0
 def test_explain(self):
     query = Query(['col1'])
     expected = """
         Data Source:
           <none given> (assuming Select object)
         Execution Plan:
           getattr, (<RESULT>, '_select'), {}
           <RESULT>, (['col1']), {}
     """
     expected = textwrap.dedent(expected).strip()
     self.assertEqual(query._explain(file=None), expected)
Пример #10
0
    def test_init_with_invalid_args(self):
        # Missing args.
        with self.assertRaises(TypeError, msg='should require select args'):
            Query()

        # Bad "select" field.
        source = Select([('A', 'B'), (1, 2), (1, 2)])
        with self.assertRaises(LookupError, msg='should fail immediately when fieldname conflicts with provided source'):
            query = Query(source, ['X'], B=2)

        # Bad "where" field.
        source = Select([('A', 'B'), (1, 2), (1, 2)])
        with self.assertRaises(LookupError, msg='should fail immediately when fieldname conflicts with provided "where" field'):
            query = Query(source, ['A'], Y=2)
Пример #11
0
 def test_bad_truncation(self):
     """Should not get truncated by preview_length."""
     select = Select([
         ('A', 'B'),
         ('x', 1),
         ('x', 2),
         ('x', 3),
         ('x', 4),
         ('x', 5),
         ('x', 6),
         ('x', 7),
         ('x', 8),
         ('x', 9),
     ])
     query = Query(select, {'A': 'B'})
     self.assertEqual(query.fetch(), {'x': [1, 2, 3, 4, 5, 6, 7, 8, 9]})
Пример #12
0
 def test_init_with_nested_dicts(self):
     """Support for nested dictionaries was removed (for now).
     It's likely that arbitrary nesting would complicate the ability
     to check complex data values that are, themselves, mappings
     (like probability mass functions represented as a dictionary).
     """
     regex = 'mappings can not be nested'
     with self.assertRaisesRegex(ValueError, regex):
         query = Query({'A': {'B': 'C'}}, D='x')
Пример #13
0
    def test_execute_datasource(self):
        select = Select([('A', 'B'), ('1', '2'), ('1', '2')])
        query = Query(select, ['B'])
        query._query_steps = [
            ('map', (int,), {}),
            ('map', (lambda x: x * 2,), {}),
            ('sum', (), {}),
        ]
        result = query.execute()
        self.assertEqual(result, 8)

        query = Query(['A'])
        regex = "expected 'Select', got 'list'"
        with self.assertRaisesRegex(TypeError, regex):
            query.execute(['hello', 'world'])  # <- Expects None or Query, not list!
Пример #14
0
    def test_explain2(self):
        query = Query(['label1'])

        expected = """
            Data Source:
              <none given> (assuming Select object)
            Execution Plan:
              getattr, (<RESULT>, '_select'), {}
              <RESULT>, (['label1']), {}
        """
        expected = textwrap.dedent(expected).strip()

        # Defaults to stdout (redirected to StringIO for testing).
        string_io = StringIO()
        returned_value = query._explain(file=string_io)
        self.assertIsNone(returned_value)

        printed_value = string_io.getvalue().strip()
        self.assertEqual(printed_value, expected)

        # Get result as string.
        returned_value = query._explain(file=None)
        self.assertEqual(returned_value, expected)
Пример #15
0
    def test_repr(self):
        # Check "no select" signature.
        query = Query(['label1'])
        regex = r"Query\(\[u?'label1'\]\)"
        self.assertRegex(repr(query), regex)

        # Check "no select" with keyword string.
        query = Query(['label1'], label2='x')
        regex = r"Query\(\[u?'label1'\], label2='x'\)"
        self.assertRegex(repr(query), regex)

        # Check "no select" with keyword list.
        query = Query(['label1'], label2=['x', 'y'])
        regex = r"Query\(\[u?'label1'\], label2=\[u?'x', u?'y'\]\)"
        self.assertRegex(repr(query), regex)

        # Check "select-provided" signature.
        select = Select([('A', 'B'), ('x', 1), ('y', 2), ('z', 3)])
        query = Query(select, ['B'])
        short_repr = super(Select, select).__repr__()
        expected = "Query({0}, {1!r})".format(short_repr, ['B'])
        #print(repr(query))
        self.assertEqual(repr(query), expected)

        # Check "from_object" signature.
        query = Query.from_object([1, 2, 3])
        expected = "Query.from_object([1, 2, 3])"
        self.assertEqual(repr(query), expected)

        # Check query steps.
        query = Query(['label1']).distinct().count()
        regex = r"Query\(\[u?'label1'\]\).distinct\(\).count\(\)"
        self.assertRegex(repr(query), regex)

        # Check query steps with function argument.
        def upper(x):
            return str(x.upper())
        query = Query(['label1']).map(upper)
        regex = r"Query\(\[u?'label1'\]\).map\(upper\)"
        self.assertRegex(repr(query), regex)

        # Check query steps with lambda argument.
        lower = lambda x: str(x).lower()
        query = Query(['label1']).map(lower)
        regex = r"Query\(\[u?'label1'\]\).map\(<lambda>\)"
        self.assertRegex(repr(query), regex)
Пример #16
0
    def test_reduce(self):
        query1 = Query.from_object({'a': [1, 3, 5], 'b': [2, 4, 6]})

        # Test simple case.
        query2 = query1.reduce(lambda x, y: x + y)
        self.assertEqual(query2.fetch(), {'a': 9, 'b': 12})

        # Test optional initializer_factory.
        def func(acc, upd):
            acc.append(upd)
            return acc
        query3 = query1.reduce(func, initializer_factory=list)
        self.assertEqual(query3.fetch(), {'a': [1, 3, 5], 'b': [2, 4, 6]})

        # Test bad initializer_factory.
        with self.assertRaises(TypeError):
            query4 = query1.reduce(func, initializer_factory=[])
Пример #17
0
    def test_filter(self):
        query1 = Query(['col1'])
        query2 = query1.filter(lambda x: x == 'a')
        self.assertIsNot(query1, query2, 'should return new object')

        source = Select([('col1', 'col2'), ('a', '2'), ('b', '2')])
        result = query2.execute(source)
        self.assertEqual(result.fetch(), ['a'])

        # No filter arg should default to bool()
        source = Select([('col1',), (1,), (2,), (0,), (3,)])
        query = Query(set(['col1'])).filter()  # <- No arg!
        result = query.execute(source)
        self.assertEqual(result.fetch(), set([1, 2, 3]))
Пример #18
0
    def test_optimize_distinct(self):
        """
        Unoptimized:
            Select._select({'col1': ['values']}, col2='xyz').distinct()

        Optimized:
            Select._select_distinct({'col1': ['values']}, col2='xyz')
        """
        unoptimized = (
            (getattr, (RESULT_TOKEN, '_select'), {}),
            (RESULT_TOKEN, ({'col1': ['values']},), {'col2': 'xyz'}),
            (_sqlite_distinct, (RESULT_TOKEN,), {}),
        )
        optimized = Query._optimize(unoptimized)

        expected = (
            (getattr, (RESULT_TOKEN, '_select_distinct'), {}),
            (RESULT_TOKEN, ({'col1': ['values']},), {'col2': 'xyz'}),
        )
        self.assertEqual(optimized, expected)
Пример #19
0
    def test_optimize_aggregation(self):
        """
        Unoptimized:
            Select._select({'col1': ['values']}, col2='xyz').sum()

        Optimized:
            Select._select_aggregate('SUM', {'col1': ['values']}, col2='xyz')
        """
        unoptimized = (
            (getattr, (RESULT_TOKEN, '_select'), {}),
            (RESULT_TOKEN, ({'col1': ['values']},), {'col2': 'xyz'}),
            (_apply_to_data, (_sqlite_sum, RESULT_TOKEN,), {}),
        )
        optimized = Query._optimize(unoptimized)

        expected = (
            (getattr, (RESULT_TOKEN, '_select_aggregate'), {}),
            (RESULT_TOKEN, ('SUM', {'col1': ['values']},), {'col2': 'xyz'}),
        )
        self.assertEqual(optimized, expected)
Пример #20
0
    def test__copy__(self):
        # Select-arg only.
        query = Query(['B'])
        copied = query.__copy__()
        self.assertIs(copied.source, query.source)
        self.assertEqual(copied.args, query.args)
        self.assertEqual(copied.kwds, query.kwds)
        self.assertEqual(copied._query_steps, query._query_steps)
        self.assertIsNot(copied.kwds, query.kwds)
        self.assertIsNot(copied._query_steps, query._query_steps)

        # Select and keyword.
        query = Query(['B'], C='x')
        copied = query.__copy__()
        self.assertIs(copied.source, query.source)
        self.assertEqual(copied.args, query.args)
        self.assertEqual(copied.kwds, query.kwds)
        self.assertEqual(copied._query_steps, query._query_steps)

        # Source, columns, and keyword.
        source = Select([('A', 'B'), (1, 2), (1, 2)])
        query = Query(source, ['B'])
        copied = query.__copy__()
        self.assertIs(copied.source, query.source)
        self.assertEqual(copied.args, query.args)
        self.assertEqual(copied.kwds, query.kwds)
        self.assertEqual(copied._query_steps, query._query_steps)

        # Select and additional query methods.
        query = Query(['B']).map(lambda x: str(x).upper())
        copied = query.__copy__()
        self.assertIs(copied.source, query.source)
        self.assertEqual(copied.args, query.args)
        self.assertEqual(copied.kwds, query.kwds)
        self.assertEqual(copied._query_steps, query._query_steps)
Пример #21
0
    def test_init_no_data(self):
        # Use column and where syntax.
        query = Query(['foo'], bar='baz')
        self.assertEqual(query.source, None)

        # Test query steps.
        query = Query(['foo'], bar='baz')
        self.assertEqual(query._query_steps, [])

        # Adding query steps.
        query = query.distinct().sum()
        expected = [
            ('distinct', (), {}),
            ('sum', (), {}),
        ]
        self.assertEqual(query._query_steps, expected)

        # Single-string defaults to list-of-single-string.
        query = Query('foo')
        self.assertEqual(query.args[0], ['foo'], 'should be wrapped as list')

        # Multi-item-container defaults to list-of-container.
        query = Query(['foo', 'bar'])
        self.assertEqual(query.args[0], [['foo', 'bar']], 'should be wrapped as list')

        # Mapping with single-string defaults to list-of-single-string.
        query = Query({'foo': 'bar'})
        self.assertEqual(query.args[0], {'foo': ['bar']}, 'value should be wrapped as list')

        # Mapping with multi-item-container defaults to list-of-container.
        query = Query({'foo': ['bar', 'baz']})
        self.assertEqual(query.args[0], {'foo': [['bar', 'baz']]}, 'value should be wrapped as list')
Пример #22
0
 def test_iterate_single_result(self):
     """Single items should be wrapped as iterators when iterated over."""
     select = Select([('A', 'B'), (1, 2), (1, 2)])
     query = Query(select, ['B']).sum()
     self.assertEqual(list(query), [4])
Пример #23
0
 def test_iterate_source(self):
     select = Select([('A', 'B'), (1, 2), (1, 2)])
     query = Query(select, ['B'])
     self.assertEqual(list(query), [2, 2])