"""Test Python utilities related to query language processing."""

import itertools
import json
import unittest
import querylang as ql


data = [
    {'age': 19},
    {'age': 21},
    {'age': 23}
]


class TestQueryLanguage(unittest.TestCase):
    """Test suite."""

    def run_expressions(self, ast_file, data, baseline):
        """Test several ASTs on a sequence of data against a set of baselines."""
        asts = None
        with open(ast_file) as f:
            asts = json.load(f)

        funcs = map(ql.astToFunction, asts)

        for ((f, a), d), b in zip(itertools.product(zip(funcs, asts), data), baseline):
            self.assertEqual(f(d), b, '%s on %s should be %s' % (a, d, not b))

    def test_operator_expressions(self):
        """Test operator expressions."""
        self.run_expressions('test/operator-ast-baselines.json', data, [
            True, False, False,
            True, True, False,
            False, False, True,
            False, True, True,
            False, True, False,
            True, False, True
        ])

    def test_conjunction_expressions(self):
        """Test conjunction expressions."""
        self.run_expressions('test/conjunction-ast-baselines.json', data, [False, True, False])

    def test_disjunction_expressions(self):
        """Test disjunction expressions."""
        self.run_expressions('test/disjunction-ast-baselines.json', data, [True, False, True])


class TestQueryLanguageMongo(unittest.TestCase):
    """Test functions for generating Mongo queries from query language expressions."""

    def test_conjunction_expressions(self):
        """Test conjunction expressions."""
        asts = None
        with open('test/conjunction-ast-baselines.json') as f:
            asts = json.load(f)

        baselines = [
            {'$and': [{'age': {'$lt': 22}},
                      {'age': {'$gt': 20}}]}
        ]

        for expr, baseline in zip(map(ql.astToMongo, asts), baselines):
            self.assertEqual(expr, baseline)


if __name__ == '__main__':
    unittest.main()

@@ -2005,16 +2005,900 @@
 eline)%0A%0A
+    def test_not_expressions(self):%0A        %22%22%22Test not expressions.%22%22%22%0A        asts = None%0A        with open('test/not-ast-baselines.json') as f:%0A            asts = json.load(f)%0A%0A        baselines = %5B%0A            %7B'$or': %5B%7B'age': %7B'$gte': 22%7D%7D,%0A                     %7B'age': %7B'$lte': 20%7D%7D%5D%7D,%0A            %7B'$or': %5B%7B'age': %7B'$gt': 22%7D%7D,%0A                     %7B'age': %7B'$lte': 20%7D%7D%5D%7D,%0A            %7B'$or': %5B%7B'age': %7B'$lte': 22%7D%7D,%0A                     %7B'age': %7B'$gte': 20%7D%7D%5D%7D,%0A            %7B'$or': %5B%7B'age': %7B'$lt': 22%7D%7D,%0A                     %7B'age': %7B'$gte': 20%7D%7D%5D%7D,%0A            %7B'age': %7B'$ne': 10%7D%7D,%0A            %7B'age': %7B'$eq': 10%7D%7D,%0A            %7B'age': %7B'$nin': %5B1, 2, 3, 4, 5%5D%7D%7D,%0A            %7B'age': %7B'$in': %5B1, 2, 3, 4, 5%5D%7D%7D,%0A            %7B'age': %7B'$gt': 22%7D%7D%0A        %5D%0A%0A        for expr, baseline in zip(map(ql.astToMongo, asts), baselines):%0A            self.assertEqual(expr, baseline)%0A
 %0Aif __na

Add Python tests for Mongo not-expressions