Example #1
0
    def test_constructor_with_mixed_operands(self):
        """
        The constructor must support operators and actual operands as arguments.

        """
        Xor(BoolVar(), Not(TrafficLightVar()))
        Xor(Not(BoolVar()), TrafficLightVar())
Example #2
0
 def test_representation(self):
     # With an operand:
     op = Not(BoolVar())
     eq_(repr(op), '<Not <Anonymous variable [BoolVar]>>')
     # With an operation:
     op = Not(And(BoolVar(), BoolVar()))
     expected = "<Not <And <Anonymous variable [BoolVar]> " \
                          "<Anonymous variable [BoolVar]>>>"
     eq_(repr(op), expected)
Example #3
0
    def test_representation(self):
        op = Xor(BoolVar(), BoolVar())
        expected = "<Xor <Anonymous variable [BoolVar]> " \
                   "<Anonymous variable [BoolVar]>>"
        eq_(repr(op), expected)

        # Now with operators as operands:
        op = Xor(Not(BoolVar()), Not(BoolVar()))
        expected = "<Xor <Not <Anonymous variable [BoolVar]>> "\
                   "<Not <Anonymous variable [BoolVar]>>>"
        eq_(repr(op), expected)
Example #4
0
 def test_evaluation(self):
     # Setup:
     traffic_light = TrafficLightVar()
     operation = Not(traffic_light)
     # Evaluation:
     ok_(operation(dict(traffic_light="")))
     assert_false(operation(dict(traffic_light="green")))
Example #5
0
    def test_equivalent(self):
        """
        Two negation operations are equivalent if they evaluate the same
        operand.

        """
        op1 = Not(BoolVar())
        op2 = Not(BoolVar())
        op3 = Not(PedestriansCrossingRoad())

        op1.check_equivalence(op2)
        op2.check_equivalence(op1)

        assert_raises(AssertionError, op1.check_equivalence, op3)
        assert_raises(AssertionError, op2.check_equivalence, op3)
        assert_raises(AssertionError, op3.check_equivalence, op1)
        assert_raises(AssertionError, op3.check_equivalence, op2)

        ok_(op1 == op2)
        ok_(op2 == op1)
        ok_(op1 != op3)
        ok_(op2 != op3)
        ok_(op3 != op1)
        ok_(op3 != op2)
Example #6
0
 def make_not(self, tokens):
     """Make an *Not* connective using the token passed."""
     return Not(tokens[0][0])
Example #7
0
 def test_constructor_with_non_boolean_operand(self):
     # Constants cannot act as booleans
     constant = String("Paris")
     ok_(not Not(constant)(None))
Example #8
0
 def test_constructor_with_operator(self):
     """The Not operator must also support operators as operands"""
     traffic_light = TrafficLightVar()
     Not(And(traffic_light, traffic_light))
Example #9
0
 def test_constructor_with_boolean_operand(self):
     traffic_light = TrafficLightVar()
     Not(traffic_light)
Example #10
0
 def test_constructor_with_operators(self):
     """The constructor must support operators as arguments."""
     Xor(Not(BoolVar()), Not(TrafficLightVar()))
Example #11
0
 def test_existing_function_with_namespace(self):
     parse_tree = self.parser('~ traffic:traffic_violation("pedestrians")')
     expected_node = Not(TrafficViolationFunc(String("pedestrians")))
     eq_(parse_tree.root_node, expected_node)
Example #12
0
 def test_existing_function_without_namespace(self):
     parse_tree = self.parser('~ foo("baz")')
     eq_(parse_tree.root_node, Not(PermissiveFunction(String("baz"))))
Example #13
0
 def test_existing_variable_without_namespace(self):
     parse_tree = self.parser("~ bool")
     eq_(parse_tree.root_node, Not(self.global_objects['bool']))
Example #14
0
class TestDefaultGrammar(BaseGrammarTest):
    """
    Tests for the parser of the default/generic grammar.

    """

    grammar = Grammar()

    expressions = {
        # Literals-only expressions:
        '  "a string" == 245    ':
        Equal(String("a string"), Number(245)),
        '   2 > 5   ':
        GreaterThan(Number(2), Number(5)),
        # Identifiers-only expressions:
        '  today > yesterday ':
        GreaterThan(PlaceholderVariable("today"),
                    PlaceholderVariable("yesterday")),
        'time:today > time:yesterday ':
        GreaterThan(PlaceholderVariable("today", ("time", )),
                    PlaceholderVariable("yesterday", ("time", ))),
        # Literals + non-literal expressions:
        'today > "1999-06-01"':
        GreaterThan(PlaceholderVariable("today"), String("1999-06-01")),
        'get_parents("Gustavo") == {"Liliana", "Carlos"}':
        Equal(PlaceholderFunction("get_parents", None, String("Gustavo")),
              Set(String("Liliana"), String("Carlos"))),
        # Set-specific operations:
        u'"hi" ∈ {"hi", "bye"}':
        BelongsTo(String("hi"), Set(String("hi"), String("bye"))),
        u'salutation ∈ {"hi", "bye"}':
        BelongsTo(PlaceholderVariable("salutation"),
                  Set(String("hi"), String("bye"))),
        u'"good morning" ∈ salutations':
        BelongsTo(String("good morning"), PlaceholderVariable("salutations")),
        u'relatives:sister ∈ relatives:siblings':
        BelongsTo(PlaceholderVariable("sister", ("relatives", )),
                  PlaceholderVariable("siblings", ("relatives", ))),
        u'{"hi", "bye"} ⊂ {"hello", "hi", "bye"}':
        IsSubset(Set(String("hi"), String("bye")),
                 Set(String("hello"), String("hi"), String("bye"))),
        u'salutations ⊂ {"morning", "hi", "bye", "later"}':
        IsSubset(
            PlaceholderVariable("salutations"),
            Set(String("morning"), String("hi"), String("bye"),
                String("later"))),
        u'{"hi", "bye"} ⊂ salutations':
        IsSubset(Set(String("hi"), String("bye")),
                 PlaceholderVariable("salutations")),
        u'relatives:siblings ⊂ relatives:everyone':
        IsSubset(PlaceholderVariable("siblings", ("relatives", )),
                 PlaceholderVariable("everyone", ("relatives", ))),
        # Relational operations:
        'now == today:time':
        Equal(PlaceholderVariable("now"),
              PlaceholderVariable("time", ("today", ))),
        '3.1416 == Pi':
        Equal(Number(3.1416), PlaceholderVariable("pi")),
        'Pi == 3.1416':
        Equal(PlaceholderVariable("pi"), Number(3.1416)),
        'days:today != days:yesterday':
        NotEqual(PlaceholderVariable("today", ("days", )),
                 PlaceholderVariable("yesterday", ("days", ))),
        '3.00 != Pi':
        NotEqual(Number(3.0), PlaceholderVariable("pi")),
        'Pi != 3.00':
        Equal(PlaceholderVariable("pi"), Number(3.00)),
        'days:today > days:yesterday':
        GreaterThan(PlaceholderVariable("today", ("days", )),
                    PlaceholderVariable("yesterday", ("days", ))),
        '3.00 > Pi':
        GreaterThan(Number(3.0), PlaceholderVariable("pi")),
        'Pi > 3.00':
        GreaterThan(PlaceholderVariable("pi"), Number(3.00)),
        'days:today < days:yesterday':
        LessThan(PlaceholderVariable("today", ("days", )),
                 PlaceholderVariable("yesterday", ("days", ))),
        '3.00 < Pi':
        LessThan(Number(3.0), PlaceholderVariable("pi")),
        'Pi < 3.00':
        LessThan(PlaceholderVariable("pi"), Number(3.00)),
        'days:today >= days:yesterday':
        GreaterEqual(PlaceholderVariable("today", ("days", )),
                     PlaceholderVariable("yesterday", ("days", ))),
        '3.00 >= Pi':
        GreaterEqual(Number(3.0), PlaceholderVariable("pi")),
        'Pi >= 3.00':
        GreaterEqual(PlaceholderVariable("pi"), Number(3.00)),
        'days:today <= days:yesterday':
        LessEqual(PlaceholderVariable("today", ("days", )),
                  PlaceholderVariable("yesterday", ("days", ))),
        '3.00 <= Pi':
        LessEqual(Number(3.0), PlaceholderVariable("pi")),
        'Pi <= 3.00':
        LessEqual(PlaceholderVariable("pi"), Number(3.00)),
        # Logical connectives:
        '~today_will_rain()':
        Not(PlaceholderFunction("today_will_rain")),
        '~(today_will_rain())':
        Not(PlaceholderFunction("today_will_rain")),
        '~ today_will_rain()':
        Not(PlaceholderFunction("today_will_rain")),
        '~~today_will_rain()':
        Not(Not(PlaceholderFunction("today_will_rain"))),
        '~ today_is_friday':
        Not(PlaceholderVariable("today_is_friday")),
        '~ time:days:today > "1999-06-01"':
        Not(
            GreaterThan(PlaceholderVariable("today", ("time", "days")),
                        String("1999-06-01"))),
        '~ (time:days:today > "1999-06-01")':
        Not(
            GreaterThan(PlaceholderVariable("today", ("time", "days")),
                        String("1999-06-01"))),
        '~ today_is_friday & today_will_rain':
        And(Not(PlaceholderVariable("today_is_friday")),
            PlaceholderVariable("today_will_rain")),
        '~ today_is_friday & ~ today_will_rain':
        And(Not(PlaceholderVariable("today_is_friday")),
            Not(PlaceholderVariable("today_will_rain"))),
        'today_is_friday & ~ today_will_rain':
        And(PlaceholderVariable("today_is_friday"),
            Not(PlaceholderVariable("today_will_rain"))),
        '~ (today_is_friday & today_will_rain)':
        Not(
            And(PlaceholderVariable("today_is_friday"),
                PlaceholderVariable("today_will_rain"))),
        '~ X > 3 & Z < X':
        And(Not(GreaterThan(PlaceholderVariable("X"), Number(3))),
            LessThan(PlaceholderVariable("Z"), PlaceholderVariable("X"))),
        '~ X > 3 & ~ Z < X':
        And(Not(GreaterThan(PlaceholderVariable("X"), Number(3))),
            Not(LessThan(PlaceholderVariable("Z"), PlaceholderVariable("X")))),
        'X > 3 & ~ Z < X':
        And(GreaterThan(PlaceholderVariable("X"), Number(3)),
            Not(LessThan(PlaceholderVariable("Z"), PlaceholderVariable("X")))),
        '~ (X > 3 & Z < X)':
        Not(
            And(GreaterThan(PlaceholderVariable("X"), Number(3)),
                LessThan(PlaceholderVariable("Z"), PlaceholderVariable("X")))),
        '~ (X > 3 ^ Z < X)':
        Not(
            Xor(GreaterThan(PlaceholderVariable("X"), Number(3)),
                LessThan(PlaceholderVariable("Z"), PlaceholderVariable("X")))),
        '~ (X > 3 | Z < X)':
        Not(
            Or(GreaterThan(PlaceholderVariable("X"), Number(3)),
               LessThan(PlaceholderVariable("Z"), PlaceholderVariable("X")))),
        'today_will_rain() & Pi > 3.0':
        And(PlaceholderFunction("today_will_rain"),
            GreaterThan(PlaceholderVariable("Pi"), Number(3.0))),
        'weather:today_rains & Pi > e & today_is_monday()':
        And(
            PlaceholderVariable("today_rains", ("weather", )),
            And(
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e")),
                PlaceholderFunction("today_is_monday"))),
        'weather:today_rains & (Pi > e & today_is_monday())':
        And(
            PlaceholderVariable("today_rains", ("weather", )),
            And(
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e")),
                PlaceholderFunction("today_is_monday"))),
        '(weather:today_rains & Pi > e) & today_is_monday()':
        And(
            And(
                PlaceholderVariable("today_rains", ("weather", )),
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e"))),
            PlaceholderFunction("today_is_monday")),
        'today_will_rain() ^ Pi > 3.0':
        Xor(PlaceholderFunction("today_will_rain"),
            GreaterThan(PlaceholderVariable("Pi"), Number(3.0))),
        'weather:today_rains ^ Pi > e ^ today_is_monday()':
        Xor(
            PlaceholderVariable("today_rains", ("weather", )),
            Xor(
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e")),
                PlaceholderFunction("today_is_monday"))),
        'weather:today_rains ^ (Pi > e ^ today_is_monday())':
        Xor(
            PlaceholderVariable("today_rains", ("weather", )),
            Xor(
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e")),
                PlaceholderFunction("today_is_monday"))),
        '(weather:today_rains ^ Pi > e) ^ today_is_monday()':
        Xor(
            Xor(
                PlaceholderVariable("today_rains", ("weather", )),
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e"))),
            PlaceholderFunction("today_is_monday")),
        'today_will_rain() | Pi > 3.0':
        Or(PlaceholderFunction("today_will_rain"),
           GreaterThan(PlaceholderVariable("Pi"), Number(3.0))),
        'weather:today_rains | Pi > e | today_is_monday()':
        Or(
            PlaceholderVariable("today_rains", ("weather", )),
            Or(
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e")),
                PlaceholderFunction("today_is_monday"))),
        'weather:today_rains | (Pi > e | today_is_monday())':
        Or(
            PlaceholderVariable("today_rains", ("weather", )),
            Or(
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e")),
                PlaceholderFunction("today_is_monday"))),
        '(weather:today_rains | Pi > e) | today_is_monday()':
        Or(
            Or(
                PlaceholderVariable("today_rains", ("weather", )),
                GreaterThan(PlaceholderVariable("Pi"),
                            PlaceholderVariable("e"))),
            PlaceholderFunction("today_is_monday")),
        # Checking operator precedence rules:
        'today == "monday" & yesterday != "sunday" ^ Y > 0':
        Xor(
            And(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        '(today == "monday" & yesterday != "sunday") ^ Y > 0':
        Xor(
            And(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        'today == "monday" & (yesterday != "sunday" ^ Y > 0)':
        And(
            Equal(PlaceholderVariable("today"), String("monday")),
            Xor(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        'today == "monday" ^ yesterday != "sunday" & Y > 0':
        Xor(
            Equal(PlaceholderVariable("today"), String("monday")),
            And(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        'today == "monday" ^ (yesterday != "sunday" & Y > 0)':
        Xor(
            Equal(PlaceholderVariable("today"), String("monday")),
            And(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        '(today == "monday" ^ yesterday != "sunday") & Y > 0':
        And(
            Xor(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        'today == "monday" & yesterday != "sunday" | Y > 0':
        Or(
            And(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        '(today == "monday" & yesterday != "sunday") | Y > 0':
        Or(
            And(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        'today == "monday" & (yesterday != "sunday" | Y > 0)':
        And(
            Equal(PlaceholderVariable("today"), String("monday")),
            Or(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
               GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        'today == "monday" | yesterday != "sunday" & Y > 0':
        Or(
            Equal(PlaceholderVariable("today"), String("monday")),
            And(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        'today == "monday" | (yesterday != "sunday" & Y > 0)':
        Or(
            Equal(PlaceholderVariable("today"), String("monday")),
            And(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        '(today == "monday" | yesterday != "sunday") & Y > 0':
        And(
            Or(Equal(PlaceholderVariable("today"), String("monday")),
               NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        'today == "monday" ^ yesterday != "sunday" | Y > 0':
        Or(
            Xor(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        '(today == "monday" ^ yesterday != "sunday") | Y > 0':
        Or(
            Xor(Equal(PlaceholderVariable("today"), String("monday")),
                NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        'today == "monday" ^ (yesterday != "sunday" | Y > 0)':
        Xor(
            Equal(PlaceholderVariable("today"), String("monday")),
            Or(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
               GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        'today == "monday" | yesterday != "sunday" ^ Y > 0':
        Or(
            Equal(PlaceholderVariable("today"), String("monday")),
            Xor(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        'today == "monday" | (yesterday != "sunday" ^ Y > 0)':
        Or(
            Equal(PlaceholderVariable("today"), String("monday")),
            Xor(NotEqual(PlaceholderVariable("yesterday"), String("sunday")),
                GreaterThan(PlaceholderVariable("Y"), Number(0))),
        ),
        '(today == "monday" | yesterday != "sunday") ^ Y > 0':
        Xor(
            Or(Equal(PlaceholderVariable("today"), String("monday")),
               NotEqual(PlaceholderVariable("yesterday"), String("sunday"))),
            GreaterThan(PlaceholderVariable("Y"), Number(0))),
        'W == 0   &   X != 1   ^   Y > 2   |   Z < 3':
        Or(
            Xor(
                And(Equal(PlaceholderVariable("W"), Number(0)),
                    NotEqual(PlaceholderVariable("X"), Number(1))),
                GreaterThan(PlaceholderVariable("Y"), Number(2))),
            LessThan(PlaceholderVariable("Z"), Number(3))),
        'W == 0   |   X != 1   ^   Y > 2   &   Z < 3':
        Or(
            Equal(PlaceholderVariable("W"), Number(0)),
            Xor(
                NotEqual(PlaceholderVariable("X"), Number(1)),
                And(GreaterThan(PlaceholderVariable("Y"), Number(2)),
                    LessThan(PlaceholderVariable("Z"), Number(3))),
            ),
        ),
        'W == 0   |   (X != 1   ^   (Y > 2   &   Z < 3))':
        Or(
            Equal(PlaceholderVariable("W"), Number(0)),
            Xor(
                NotEqual(PlaceholderVariable("X"), Number(1)),
                And(GreaterThan(PlaceholderVariable("Y"), Number(2)),
                    LessThan(PlaceholderVariable("Z"), Number(3))),
            ),
        ),
        '(W == 0   |   X != 1)   ^   (Y > 2   &   Z < 3)':
        Xor(
            Or(Equal(PlaceholderVariable("W"), Number(0)),
               NotEqual(PlaceholderVariable("X"), Number(1))),
            And(GreaterThan(PlaceholderVariable("Y"), Number(2)),
                LessThan(PlaceholderVariable("Z"), Number(3)))),
        '(W == 0   |   X != 1   ^   Y > 2)   &   Z < 3':
        And(
            Or(
                Equal(PlaceholderVariable("W"), Number(0)),
                Xor(
                    NotEqual(PlaceholderVariable("X"), Number(1)),
                    GreaterThan(PlaceholderVariable("Y"), Number(2)),
                )), LessThan(PlaceholderVariable("Z"), Number(3))),
        '((W == 0   |   X != 1)   ^   Y > 2)   &   Z < 3':
        And(
            Xor(
                Or(Equal(PlaceholderVariable("W"), Number(0)),
                   NotEqual(PlaceholderVariable("X"), Number(1))),
                GreaterThan(PlaceholderVariable("Y"), Number(2))),
            LessThan(PlaceholderVariable("Z"), Number(3))),
        '(W == 0   |   (X != 1   ^   Y > 2))   &   Z < 3':
        And(
            Or(
                Equal(PlaceholderVariable("W"), Number(0)),
                Xor(NotEqual(PlaceholderVariable("X"), Number(1)),
                    GreaterThan(PlaceholderVariable("Y"), Number(2)))),
            LessThan(PlaceholderVariable("Z"), Number(3))),
        'W == 0   |   (X != 1   ^   Y > 2   &   Z < 3)':
        Or(
            Equal(PlaceholderVariable("W"), Number(0)),
            Xor(
                NotEqual(PlaceholderVariable("X"), Number(1)),
                And(GreaterThan(PlaceholderVariable("Y"), Number(2)),
                    LessThan(PlaceholderVariable("Z"), Number(3))))),
        'W == 0   |   (X != 1   ^   (Y > 2   &   Z < 3))':
        Or(
            Equal(PlaceholderVariable("W"), Number(0)),
            Xor(
                NotEqual(PlaceholderVariable("X"), Number(1)),
                And(GreaterThan(PlaceholderVariable("Y"), Number(2)),
                    LessThan(PlaceholderVariable("Z"), Number(3))))),
        'W == 0   |   ((X != 1   ^   Y > 2)   &   Z < 3)':
        Or(
            Equal(PlaceholderVariable("W"), Number(0)),
            And(
                Xor(
                    NotEqual(PlaceholderVariable("X"), Number(1)),
                    GreaterThan(PlaceholderVariable("Y"), Number(2)),
                ), LessThan(PlaceholderVariable("Z"), Number(3)))),
        # Let's make sure whitespace doesn't change anything:
        '''

        variable == "hi"

        ''':
        Equal(PlaceholderVariable("variable"), String("hi")),
        '''

        variable
        ==

        "hi"

        ''':
        Equal(PlaceholderVariable("variable"), String("hi")),
        '''
        \t variable == "hi"
        &
        \t today_is_thursday()
        ''':
        And(Equal(PlaceholderVariable("variable"), String("hi")),
            PlaceholderFunction("today_is_thursday")),
    }

    badformed_expressions = (
        "",
        " ",
        "\t",
        "\n",
        "\r",
        "== 3 4",
        "3 4 ==",
    )

    single_operands = {
        # ----- Strings
        '"oneword"': String("oneword"),
        '"double quotes"': String("double quotes"),
        "'single quotes'": String("single quotes"),
        "''": String(""),
        '""': String(""),
        "'something with \"quotes\"'": String('something with "quotes"'),
        '"something with \'quotes\'"': String("something with 'quotes'"),
        u'"áéíóúñçÁÉÍÓÚÑÇ"': String(u"áéíóúñçÁÉÍÓÚÑÇ"),
        u'"海納百川,有容乃大"': String(u"海納百川,有容乃大"),
        u"'مقالة مختارة'": String(u"مقالة مختارة"),
        u'"вільної енциклопедії"': String(u"вільної енциклопедії"),
        # ----- Numbers
        '1': Number(1),
        '01': Number(1),
        '5000': Number(5000),
        '+3': Number(3),
        '-3': Number(-3),
        '2.34': Number(2.34),
        '2.2': Number(2.2),
        '+3.1416': Number(3.1416),
        '-3.1416': Number(-3.1416),
        '5,000': Number(5000),
        '1,000,000.34': Number(1000000.34),
        '+1,000,000.22': Number(1000000.22),
        '-1,000,000.22': Number(-1000000.22),
        # ----- Sets:
        ' {} ': Set(),
        '{{}, {}}': Set(Set(), Set()),
        '{1,000, 3.05}': Set(Number(1000), Number(3.05)),
        '{1,234,567}': Set(Number(1234567)),
        '{23,24,25}': Set(Number(23), Number(24), Number(25)),
        '{100, 200, 300}': Set(Number(100), Number(200), Number(300)),
        '{1, 2, {"orange", "apple"}, 3}': Set(
            Number(1),
            Number(2),
            Number(3),
            Set(String("orange"), String("apple"))
            ),
        u'{"españa", {"caracas", {"las chimeneas", "el trigal"}}, "france"}': \
            Set(
                String(u"españa"),
                String("france"),
                Set(
                    String("caracas"),
                    Set(String("el trigal"), String("las chimeneas"))
                ),
            ),
        '{var1, var2}': Set(PlaceholderVariable("var1"),
                            PlaceholderVariable("var2")),
        '{var, "string"}': Set(PlaceholderVariable("var"), String("string")),
        '{3, var, "string"}': Set(Number(3), String("string"),
                                  PlaceholderVariable("var")),
        '{varA, funcB()}': Set(PlaceholderVariable("varA"),
                               PlaceholderFunction("funcB")),
        '{"hi", 3.1416, len({1, 2, 3, 5, 7}), var0}': Set(
            String("hi"),
            Number(3.1416),
            PlaceholderFunction("len", (), Set(
                Number(1), Number(2), Number(3), Number(5), Number(7))),
            PlaceholderVariable("var0")
            ),
        # ----- Variables:
        'today': PlaceholderVariable("today"),
        'camelCase': PlaceholderVariable("camelCase"),
        'with_underscore': PlaceholderVariable("with_underscore"),
        ' v1 ': PlaceholderVariable("v1"),
        'var1_here': PlaceholderVariable("var1_here"),
        u'résumé': PlaceholderVariable(u"résumé"),
        u'有容乃大': PlaceholderVariable(u"有容乃大"),
        '    spaces': PlaceholderVariable("spaces"),
        'spaces    ': PlaceholderVariable("spaces"),
        '  spaces  ': PlaceholderVariable("spaces"),
        '_protected_var': PlaceholderVariable("_protected_var"),
        '__private_var': PlaceholderVariable("__private_var"),
        'one_underscore': PlaceholderVariable("one_underscore"),
        'two__underscores__here': PlaceholderVariable("two__underscores__here"),
        'case_insensitive_var': PlaceholderVariable("CASE_INSENSITIVE_VAR"),
        'CASE_INSENSITIVE_VAR': PlaceholderVariable("case_insensitive_var"),
        'cAsE_iNsEnSiTiVe_VaR': PlaceholderVariable("CaSe_InSeNsItIvE_vAr"),
        u'MAYÚSCULA_minúscula': PlaceholderVariable(u"mayúscula_MINÚSCULA"),
        'ns:variable': PlaceholderVariable("variable", ("ns", )),
        'ns0:ns1:variable': PlaceholderVariable("variable", ("ns0", "ns1")),
        'ns0:ns1:ns2:variable': PlaceholderVariable("variable",
                                                    ("ns0", "ns1", "ns2")),
        'ns:sub_ns:variable': PlaceholderVariable("variable", ("ns", "sub_ns")),
        u'ñŝ0:ñŝ1:variable': PlaceholderVariable("variable", (u"ñŝ0", u"ñŝ1")),
        # ----- Functions:
        'stop()': PlaceholderFunction("stop"),
        'stop ()': PlaceholderFunction("stop"),
        'stop( )': PlaceholderFunction("stop"),
        'stop ( )': PlaceholderFunction("stop"),
        'camelCase()': PlaceholderFunction("camelCase"),
        'with_underscore()': PlaceholderFunction("with_underscore"),
        ' v1() ': PlaceholderFunction("v1"),
        'var1_here()': PlaceholderFunction("var1_here"),
        u'résumé()': PlaceholderFunction(u"résumé"),
        u'有容乃大()': PlaceholderFunction(u"有容乃大"),
        '    spaces()': PlaceholderFunction("spaces"),
        'spaces()    ': PlaceholderFunction("spaces"),
        '  spaces()  ': PlaceholderFunction("spaces"),
        '_protected_function()': PlaceholderFunction("_protected_function"),
        '__private_function()': PlaceholderFunction("__private_function"),
        'one_underscore()': PlaceholderFunction("one_underscore"),
        'two__underscores__()': PlaceholderFunction("two__underscores__"),
        'case_insensitive_func()': PlaceholderFunction("CASE_INSENSITIVE_FUNC"),
        'CASE_INSENSITIVE_FUNC()': PlaceholderFunction("case_insensitive_func"),
        'cAsE_iNsEnSiTiVe_FuNc()': PlaceholderFunction("CaSe_InSeNsItIvE_fUnC"),
        u'MAYÚSCULA_minúscula()': PlaceholderFunction(u"mayúscula_MINÚSCULA"),
        'func("argument")': PlaceholderFunction("func", (), String("argument")),
        'function("arg1", variable, 3)': PlaceholderFunction("function",
            (),
            String("arg1"),
            PlaceholderVariable("variable"),
            Number(3),
            ),
        'function("arg1", ns:variable, 3)': PlaceholderFunction(
            "function",
            (),
            String("arg1"),
            PlaceholderVariable("variable", ("ns", )),
            Number(3),
            ),
        'ns:function("arg1", ns:variable, 3)': PlaceholderFunction(
            "function",
            ("ns", ),
            String("arg1"),
            PlaceholderVariable("variable", ("ns", )),
            Number(3),
            ),
        'function("arg1", ns:sub_function(), 3.0)': PlaceholderFunction(
            "function",
            (),
            String("arg1"),
            PlaceholderFunction("sub_function", ("ns", )),
            Number(3),
            ),
        'ns:function("arg1", ns:sub_function(), 3.0)': PlaceholderFunction(
            "function",
            ("ns", ),
            String("arg1"),
            PlaceholderFunction("sub_function", ("ns", )),
            Number(3),
            ),
        'ns:function()': PlaceholderFunction("function", ("ns", )),
        'ns0:ns1:function()': PlaceholderFunction("function", ("ns0", "ns1")),
        'ns0:ns1:ns2:function()': PlaceholderFunction("function",
                                                      ("ns0", "ns1", "ns2")),
        'ns:sub_ns:function("with argument")': PlaceholderFunction("function",
            ("ns", "sub_ns"),
            String("with argument"),
            ),
        u'ñŝ:ñś1:function()': PlaceholderFunction("function", (u"ñŝ", u"ñś1")),
        u'ñŝ:ñś1:función()': PlaceholderFunction(u"función", (u"ñŝ", u"ñś1")),
    }

    invalid_operands = (
        # Invalid strings:
        '\'mixed quotes"',
        # Invalid numbers:
        "3 . 1416",
        "3. 1416",
        "3 .1416",
        "1,00",
        "12.4,500,000",
        # Invalid variables:
        "dashes-here-cant-you-see-them",
        "1st_variable",
        "25th_variable",
        "namespace-here:variable",
        "1stnamespace:var",
        "global:2ndlevel:var",
        "namespace:1st_variable",
        # Invalid functions:
        "func(",
        "func)",
        "func)(",
        "func[]",
        "func{}",
        "func(,)",
        "func(arg1, )",
        "func(, arg2)",
        "func(, arg2, )",
        "function-name()",
        "1st_function()",
        "25th_function()",
        "namespace-here:function()",
        "1stnamespace:function()",
        "global:2ndlevel:function()",
        "namespace:1st_function()",
        "foo( bad-namespace:baz() )",
        # Invalid sets:
        "[]",
        "{]",
        "[}",
        "}{",
        "{key: 'value'}",
        "[element1, element2, element3]",
        "{element 1, element 2}",
        "{element1; element2; element3}",
        "{element == 'string'}",
        # Default operators:
        "==",
        "!=",
        "<",
        ">",
        "<=",
        ">=",
        "~",
        "&",
        "^",
        "|",
        u"∈",
        u"⊂",
        # Miscellaneous:
        "-",
        "this is definitely not an operand",
    )

    def test_custom_tokens_against_trees(self):
        """
        All the custom tokens in the grammar must be taken into account by the
        parser.

        To test that custom tokens are used, and in order to test many scenarios
        writen few lines of code, we're going to convert operation nodes into
        boolean expressions (using the relevant grammar), and then these
        expressions will be parsed to check if the result is the original
        tree.

        """

        grammars = (
            # A grammar that overrides all the default tokens:
            Grammar(
                **{
                    'not': "not",
                    'and': "and",
                    'xor': "xor",
                    'or': "or",
                    'eq': "equals",
                    'ne': "different-from",
                    'lt': "less-than",
                    'le': "less-equal",
                    'gt': "greater-than",
                    'ge': "greater-equal",
                    'belongs_to': "belongs-to",
                    'is_subset': "is-subset-of",
                    'set_start': "\\",
                    'set_end': "/",
                    'element_separator': ";",
                    'arguments_start': "[",
                    'arguments_end': "]",
                    'arguments_separator': ";",
                    'namespace_separator': ".",
                }),
            # Now let's try a grammar where some operators represent the
            # initial characters of other operators:
            Grammar(
                **{
                    'eq': "is",
                    'ne': "isn't",
                    'lt': "is less than",
                    'gt': "is greater than",
                    'le': "is less than or equal to",
                    'ge': "is greater than or equal to",
                    'belongs_to': "is included in",
                    'is_subset': "is subset of",
                }))

        for grammar_num in range(len(grammars)):
            grammar = grammars[grammar_num]
            parser = ConvertibleParser(grammar)
            convert_to_string = StringConverter(grammar)

            for operation in self.expressions.values():
                expression = convert_to_string(operation)

                # Using a Nose test generator:
                def check():
                    new_operation = parser(expression).root_node
                    eq_(
                        operation, new_operation,
                        u'Original operation: %s --- Returned operation: %s' %
                        (repr(operation), repr(new_operation)))

                check.description = (u"The following expression is valid in "
                                     u"the grammar #%r: %r" %
                                     (grammar_num, expression))

                yield check
Example #15
0
 def convert_not(self, operand):
     return Not(operand)
Example #16
0
class TestActualConverter(object):
    """Tests for an actual converter."""

    parse_trees = (
        # Operands alone:
        String("this is a string"),
        String(u"¡Estás viendo un texto en castellano aquí!"),
        Number(12345),
        Number(123.45),
        Set(String("hola"), PlaceholderVariable("today", None), Number(4)),
        Set(),
        PlaceholderVariable("tomorrow", None),
        PlaceholderFunction("today_is_gonna_rain", None),
        PlaceholderFunction("distance", None,
                            PlaceholderFunction("where_am_i", None),
                            String("Paris")),
        # Unary operators:
        Not(PlaceholderFunction("near_paris",
                                None,
                                PlaceholderVariable("moon", None))),
        # Binary operators:
        And(
            PlaceholderFunction("in_europe", None),
            PlaceholderFunction("in_spain", None)
            ),
        And(
            Or(
               Equal(
                     PlaceholderVariable("venezuela", None),
                     String("Venezuela")
                     ),
               PlaceholderFunction("today_is_gonna_rain", None)),
            Xor(
                Equal(
                      PlaceholderVariable("venezuela", None),
                      String("Venezuela")
                      ),
                PlaceholderFunction("today_is_gonna_rain", None))
            ),
        Or(
           PlaceholderFunction("in_europe", None),
           PlaceholderFunction("in_spain", None)
           ),
        Or(
            And(
               Equal(
                     PlaceholderVariable("venezuela", None),
                     String("Venezuela")
                     ),
               PlaceholderFunction("today_is_gonna_rain", None)),
            Xor(
                Equal(
                      PlaceholderVariable("venezuela", None),
                      String("Venezuela")
                      ),
                PlaceholderFunction("today_is_gonna_rain", None))
            ),
        Xor(
            PlaceholderFunction("in_europe", None),
            PlaceholderFunction("in_spain", None)
            ),
        Xor(
            Or(
               Equal(
                     PlaceholderVariable("venezuela", None),
                     String("Venezuela")
                     ),
               PlaceholderFunction("today_is_gonna_rain", None)),
            And(
                Equal(
                      PlaceholderVariable("venezuela", None),
                      String("Venezuela")
                      ),
                PlaceholderFunction("today_is_gonna_rain", None))
            ),
        Equal(PlaceholderVariable("venezuela", None), String("Venezuela")),
        NotEqual(
                 PlaceholderVariable("venezuela", None),
                 PlaceholderVariable("here", None)
                 ),
        LessThan(Number(2), PlaceholderVariable("counter", None)),
        GreaterThan(Number(2), PlaceholderVariable("counter", None)),
        LessEqual(Number(2), PlaceholderVariable("counter", None)),
        GreaterEqual(Number(2), PlaceholderVariable("counter", None)),
        BelongsTo(Number(4), Set(Number(3), String("no"), Number(0))),
        IsSubset(Set(), Set(Number(3), String("no"), Number(0))),
    )

    def test_conversions(self):
        """Check that each parse tree is converted back to its original form."""
        for parse_tree in self.parse_trees:

            # Let's use a Nose test generator:
            def check():
                conversion = ANTI_CONVERTER(parse_tree)
                eq_(parse_tree, conversion,
                    'Parse tree %s changed to %s' % (repr(parse_tree),
                                                     repr(conversion)))
            check.description = ("Parse tree %s shouldn't change" %
                                 repr(parse_tree))

            yield check

    @raises(ConversionError)
    def test_converting_non_node(self):
        """Only nodes are tried to be converted."""
        ANTI_CONVERTER(12345)