Example #1
0
 def test_creation_table_with_type(self):
     vb = SymbolTableBuilder()
     vb.register(six.text_type, self.FakeVariable)
     vb.register(int, self.FakeVariableSub)
     st = vb("root", {"name": six.text_type, "age": 15})
     assert_equal(
         st,
         SymbolTable('root', (
             Bind("name", self.FakeVariable),
             Bind("age", self.FakeVariableSub),
         )))
Example #2
0
    def create_grammar(self):
        root_table = SymbolTable(
            "root",
            map(lambda f: Bind(f['name'], GeometryProperty(f['name'])),
                self.fields))

        tokens = {
            'not': "not",
            'eq': "==",
            'ne': "!=",
            'belongs_to': "in",
            'is_subset': "are included in"
        }
        grammar = Grammar(**tokens)
        self.parse_manager = EvaluableParseManager(root_table, grammar)
Example #3
0
  def create_grammar(self):
    root_table = SymbolTable("Shop_root",
                             map( lambda f: Bind(f['name'], GeometryProperty(f['name'])), self.fields )
                             )

    tokens = {
      'not': 'not',
      'eq': '==',
      'ne': '!=',
      'belongs_to': 'in',
      'is_subset': 'are included in',
      'or': "or",
      'and': 'and'
    }
    grammar = Grammar(**tokens)
    self.parse_manager = EvaluableParseManager(root_table, grammar)
    def __call__(self, name, sample):
        """
        create a SymbolTalbe from the sample data
        :param string name: the name of the symbolTable
        :param dict sample: the sample of data
        :return: the SymbolTable
        :rtype: SymbolTable
        """
        from booleano.parser import Bind, SymbolTable  # isort:skip

        binds = []
        for k, v in sample.items():
            var_type = v if isinstance(v, six.class_types) else type(v)

            var = self.find_for_type(var_type)

            binds.append(Bind(k, var(k if self.use_key else v)))
        return SymbolTable(name, binds)
Example #5
0
class TestEvaluableParseManager(object):
    """
    Tests for the :class:`EvaluableParseManager` with caching disabled.

    """

    # A symbol table to be used across the tests:
    symbol_table = SymbolTable(
        "root",
        (
            Bind("boolean", BoolVar(), es="booleano"),
            Bind("message", String("Hello world"), es="mensaje"),
            Bind("foo", PermissiveFunction, es="fulano"),
        ),
        SymbolTable("traffic", (
            Bind("traffic_light", TrafficLightVar(), es=u"semáforo"),
            Bind("pedestrians_crossing_road",
                 PedestriansCrossingRoad(),
                 es="peatones_cruzando_calle"),
            Bind("drivers_awaiting_green",
                 DriversAwaitingGreenLightVar(),
                 es="conductores_esperando_verde"),
            Bind("traffic_violation", TrafficViolationFunc, es=u"infracción"),
        ),
                    es=u"tráfico"),
    )

    def test_parsing_with_no_localized_grammars(self):
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        parse_tree1 = mgr.parse('message == "2009-07-13"')
        parse_tree2 = mgr.parse('message == "2009-07-13"', None)
        expected_tree = EvaluableParseTree(
            Equal(String("Hello world"), String("2009-07-13")))
        eq_(parse_tree1, parse_tree2)
        eq_(parse_tree1, expected_tree)

    def test_parsing_with_localized_grammars(self):
        castilian_grammar = Grammar(decimal_separator=",",
                                    thousands_separator=".")
        mgr = EvaluableParseManager(self.symbol_table,
                                    Grammar(),
                                    es=castilian_grammar)
        parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3,00",
                               "es")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3.0)))
        eq_(parse_tree, expected_tree)

    def test_parsing_with_undefined_grammar_but_available_translations(self):
        """
        When an expression is written in an unsupported grammar, a parser
        based on the generic grammar must be created and used.

        The respective translated bindings must be used if available.

        """
        log_handler = LoggingHandlerFixture()
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        # Castilian grammar is not supported:
        parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3.0", "es")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3)))
        eq_(parse_tree, expected_tree)
        # Checking the log:
        info = "Generated parser for unknown grammar %s" % repr(u'es')

        ok_(info in log_handler.handler.messages['info'])
        log_handler.undo()

    def test_parsing_with_undefined_grammar_and_no_translated_bindings(self):
        """
        When an expression is written in an unsupported grammar, a parser
        based on the generic grammar must be created and used.

        If there are no translated bindings, the default names must be used.

        """
        log_handler = LoggingHandlerFixture()
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        # French grammar is not supported:
        parse_tree = mgr.parse("traffic:pedestrians_crossing_road <= 3.0",
                               "fr")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3)))
        eq_(parse_tree, expected_tree)
        # Checking the log:
        info = "Generated parser for unknown grammar %s" % repr('fr')
        ok_(info in log_handler.handler.messages['info'])
        log_handler.undo()

    def test_parsing_with_defined_grammar_but_no_available_translations(self):
        """
        When an expression is written in an supported grammar but there are no
        translated bindings, the default names must be used along with the
        custom grammar.

        """
        french_grammar = Grammar(decimal_separator=",",
                                 thousands_separator=".")
        mgr = EvaluableParseManager(self.symbol_table,
                                    Grammar(),
                                    fr=french_grammar)
        # French grammar is not supported:
        parse_tree = mgr.parse("traffic:pedestrians_crossing_road <= 3,0",
                               "fr")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3)))
        eq_(parse_tree, expected_tree)

    def test_adding_grammar(self):
        """It should be possible to add grammars after instantiation."""
        castilian_grammar = Grammar(decimal_separator=",",
                                    thousands_separator=".")
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        mgr.add_parser("es", castilian_grammar)
        parse_tree = mgr.parse(u'tráfico:peatones_cruzando_calle <= 3,00',
                               "es")
        expected_tree = EvaluableParseTree(
            LessEqual(PedestriansCrossingRoad(), Number(3.0)))
        eq_(parse_tree, expected_tree)

    def test_adding_existing_grammar(self):
        """There can't be duplicate/overlapped parsers."""
        mgr = EvaluableParseManager(self.symbol_table, Grammar(), es=Grammar())
        assert_raises(GrammarError, mgr.add_parser, "es", Grammar())

    def test_evaluating_expressions(self):
        """Managers should be able to evaluate the expressions too."""
        mgr = EvaluableParseManager(self.symbol_table, Grammar())
        context = {'pedestrians_crossroad': (u"gustavo", u"carla")}
        evaluation1 = mgr.evaluate("traffic:pedestrians_crossing_road <= 3",
                                   None, context)
        evaluation2 = mgr.evaluate(
            u'"carla" ∈ traffic:pedestrians_crossing_road', None, context)
        evaluation3 = mgr.evaluate("traffic:pedestrians_crossing_road > 2",
                                   None, context)
        ok_(evaluation1)
        ok_(evaluation2)
        assert_false(evaluation3)
Example #6
0
	root_table = SymbolTable("root",
	                         [
		                         Bind("stock", stock_symbol_var),
		                         Bind("date", today_var),
	                         ],
	                         SymbolTable("stock",
	                                     [
		                                     Bind("symbol", stock_symbol_var),
		                                     Bind("open_price", stockVars.StockOpenPrice()),
		                                     Bind("close_price", stockVars.StockClosePrice()),
		                                     Bind("price", stockVars.StockPrice()),
		                                     Bind("increase_rank", stockVars.StockIncreaseRank()),
		                                     Bind("decrease_rank", stockVars.StockDecreaseRank()),
		                                     Bind("change_percent", stockVars.StockPercChange()),
		                                     Bind("owned", stockVars.StockOwned()),
		                                     Bind("buy_price", stockVars.StockBuyPrice()),
	                                     ],
	                                     SymbolTable("decrease_rank", []),
	                                     SymbolTable("increase_rank", []),
	                                     SymbolTable("open_price", []),
	                                     SymbolTable("close_price", []),
	                                     SymbolTable("price", []),
	                                     SymbolTable("change_percent", []),
	                                     ),
	                         SymbolTable("date",
	                                     [
		                                     Bind("today", today_var),
		                                     Bind("buy", stockVars.DateBuy()),
		                                     Bind("days_of_history", stockVars.DateDaysOfHistory()),
		                                     Bind("day_of_week", stockVars.DateDayOfWeek()),
		                                     Bind("month", stockVars.DateMonth()),
		                                     Bind("days", stockVars.DateDays()),
		                                     Bind("months", stockVars.DateMonths()),
		                                     Bind("years", stockVars.DateYears()),
	                                     ],
	                                     SymbolTable("today", []),
	                                     SymbolTable("days_of_history", []),
	                                     SymbolTable("day_of_week", []),
	                                     SymbolTable("month", [])
	                                     )
	                         )
Example #7
0
class TestNativeVariableEvaluableParseManager(object):
    """
    Tests for the :class:`EvaluableParseManager` with caching disabled.

    """

    # A symbol table to be used across the tests:
    symbol_table = SymbolTable(
        "root", (
            Bind("myint", NumberVariable("myint")),
            Bind("mybool", BooleanVariable("mybool")),
            Bind("mystring", StringVariable("mystring")),
            Bind("mydate", DateVariable("mydate")),
            Bind("mydate2", DateVariable("mydate2")),
            Bind("mydatetime", DateTimeVariable("mydatetime")),
            Bind("mydatetime2", DateTimeVariable("mydatetime2")),
            Bind("myset", SetVariable("myset")),
            Bind("myintbis", NumberVariable("myint")),
        ), SymbolTable(
            "sub",
            (Bind("myint", NumberVariable("sub.myint")), ),
        ),
        SymbolTable("const", (
            Bind("hello", String("hello")),
            Bind("li", String("li")),
        )))

    mgr = EvaluableParseManager(
        symbol_table, Grammar(belongs_to='in', is_subset='is subset of'))

    def test_variable_values_myint(self):
        ok_(self.mgr.parse('myint > 0')({'myint': 1}))
        ok_(not self.mgr.parse('myint > 0')({'myint': 0}))
        ok_(self.mgr.parse('myint == 1')({'myint': 1}))
        ok_(not self.mgr.parse('myint == 1')({'myint': 0}))
        ok_(self.mgr.parse('myint < 1')({'myint': 0}))
        ok_(not self.mgr.parse('myint < 0')({'myint': 2}))

    def test_variable_values_mybool(self):
        ok_(self.mgr.parse('mybool')({'mybool': True}))
        ok_(not self.mgr.parse('mybool')({'mybool': False}))
        ok_(self.mgr.parse('mybool > 0')({'mybool': True}))
        ok_(not self.mgr.parse('mybool > 0')({'mybool': False}))
        ok_(self.mgr.parse('mybool == 1')({'mybool': True}))
        ok_(not self.mgr.parse('mybool == 1')({'mybool': False}))
        ok_(self.mgr.parse('mybool < 1')({'mybool': False}))
        ok_(not self.mgr.parse('mybool < 0')({'mybool': True}))

    def test_variable_values_mystring(self):
        mystring = {'mystring': "hello"}
        # equiality
        ok_(self.mgr.parse('mystring == "hello"')(mystring))
        ok_(not self.mgr.parse('mystring != "hello"')(mystring))
        ok_(self.mgr.parse('mystring != "hell"')(mystring))
        ok_(not self.mgr.parse('mystring == "hell"')(mystring))
        # inequality
        ok_(self.mgr.parse('mystring >  "hella"')(mystring))
        ok_(self.mgr.parse('mystring <  "hellz"')(mystring))
        ok_(self.mgr.parse('mystring <  "hellz"')(mystring))
        ok_(self.mgr.parse('mystring <= "hello"')(mystring))
        ok_(self.mgr.parse('mystring >= "hello"')(mystring))
        # inequality reversed
        ok_(self.mgr.parse('"hella" <  mystring')(mystring))
        ok_(self.mgr.parse('"hellz" >  mystring')(mystring))
        ok_(self.mgr.parse('"hellz" >  mystring')(mystring))
        ok_(self.mgr.parse('"hello" >= mystring')(mystring))
        ok_(self.mgr.parse('"hello" >= mystring')(mystring))
        # bool
        ok_(self.mgr.parse('mystring')(mystring))
        ok_(not self.mgr.parse('~ mystring')(mystring))
        ok_(not self.mgr.parse('mystring')({'mystring': ''}))
        ok_(self.mgr.parse('~ mystring')({'mystring': ''}))
        # membership
        ok_(self.mgr.parse('mystring is subset of "zhelloy"')(mystring))
        ok_(not self.mgr.parse('mystring is subset of "zhellai"')(mystring))
        ok_(not self.mgr.parse('mystring is subset of "hello"')(mystring))
        ok_(self.mgr.parse('mystring in "ahelloa"')(mystring))
        ok_(self.mgr.parse('mystring in "hello"')(mystring))
        ok_(not self.mgr.parse('mystring in "hola"')(mystring))
        # inversed membership
        ok_(self.mgr.parse('"he" in mystring')(mystring))
        ok_(self.mgr.parse('"lo" in mystring')(mystring))
        ok_(not self.mgr.parse('"li" in mystring')(mystring))
        ok_(self.mgr.parse('"he" is subset of mystring')(mystring))
        ok_(self.mgr.parse('"lo" is subset of mystring')(mystring))
        ok_(not self.mgr.parse('"li" is subset of mystring')(mystring))
        ok_(not self.mgr.parse(' "hello" is subset of mystring')(mystring))
        # test to string
        ok_(not self.mgr.parse('const:hello is subset of mystring')(mystring))
        ok_(not self.mgr.parse('const:li in mystring')(mystring))

    def test_variable_str(self):
        eq_("%s" % NativeVariable('coucou'),
            'Scop variable for coucou [NativeVariable]')
        eq_("%s" % BooleanVariable('name'),
            'Scop variable for name [BooleanVariable]')
        eq_("%s" % NumberVariable('age'),
            'Scop variable for age [NumberVariable]')

    def test_variable_values_date(self):
        mydate = {
            'mydate': datetime.date(2017, 1, 15),
            'mydate2': datetime.date(2017, 1, 17),
        }
        ok_(self.mgr.parse('mydate')(mydate))

        ok_(self.mgr.parse('mydate < "2017-01-18"')(mydate))
        ok_(self.mgr.parse('mydate < "18-01-2017"')(mydate))
        ok_(not self.mgr.parse('mydate < "12-01-2017"')(mydate))
        ok_(self.mgr.parse('mydate > "12-01-2017"')(mydate))

        ok_(self.mgr.parse('mydate == "15-01-2017"')(mydate))
        ok_(not self.mgr.parse('mydate == 1')(mydate))
        ok_(not self.mgr.parse('mydate == "13-01-2017"')(mydate))
        ok_(self.mgr.parse('mydate < mydate2')(mydate))
        ok_(not self.mgr.parse('mydate > mydate2')(mydate))
        ok_(not self.mgr.parse('mydate == mydate2')(mydate))

    def test_variable_values_datetime(self):
        mydatetime = {
            'mydatetime': datetime.datetime(2017, 1, 15, 12, 25),
            'mydatetime2': datetime.datetime(2017, 1, 17, 12, 23),
        }
        ok_(self.mgr.parse('mydatetime')(mydatetime))

        ok_(self.mgr.parse('mydatetime < "2017-01-15 12:25:02"')(mydatetime))
        ok_(self.mgr.parse('mydatetime > "2017-01-15 12:24:52"')(mydatetime))
        ok_(self.mgr.parse('mydatetime < "2017-01-15 13:00:00"')(mydatetime))
        ok_(self.mgr.parse('mydatetime < "18-01-2017 12:25:02"')(mydatetime))
        ok_(self.mgr.parse('mydatetime < "18-01-2017 12:25:02"')(mydatetime))
        ok_(not self.mgr.parse('mydatetime < "12-01-2017 12:25:02"')
            (mydatetime))
        ok_(self.mgr.parse('mydatetime > "12-01-2017 12:25:02"')(mydatetime))

        ok_(self.mgr.parse('mydatetime == "15-01-2017 12:25:00"')(mydatetime))
        ok_(not self.mgr.parse('mydatetime == 1')(mydatetime))
        ok_(not self.mgr.parse('mydatetime == "13-01-2017 12:25:02"')
            (mydatetime))
        ok_(self.mgr.parse('mydatetime < mydatetime2')(mydatetime))
        ok_(not self.mgr.parse('mydatetime > mydatetime2')(mydatetime))
        ok_(not self.mgr.parse('mydatetime == mydatetime2')(mydatetime))

    def test_variable_values_set(self):
        myset = {
            "myset": {1, 2, 3},
        }
        ok_(self.mgr.parse("1 is subset of myset ")(myset))
        ok_(self.mgr.parse("{1, 2} is subset of myset ")(myset))
        ok_(not self.mgr.parse("{1, 2, 3} is subset of myset ")(myset))
        ok_(self.mgr.parse("1 in myset ")(myset))
        ok_(self.mgr.parse("{1, 2} in myset ")(myset))
        ok_(self.mgr.parse("{1, 2, 3} in myset ")(myset))

    def test_variable_values_namespaced(self):
        myints = {"myint": 1, "sub.myint": 4}
        ok_(self.mgr.parse('sub:myint > 3')(myints))
        ok_(self.mgr.parse('sub:myint < 5')(myints))
        ok_(self.mgr.parse('sub:myint == 4')(myints))
        ok_(self.mgr.parse('sub:myint > myint')(myints))
        ok_(not self.mgr.parse('sub:myint < myint')(myints))
        ok_(not self.mgr.parse('sub:myint == myint')(myints))

    def test_format_date(self):
        dt = DateVariable("mydate", '%d %m %y')
        assert_raises(ValueError, dt._from_native_string, "2001-03-04")
        eq_(dt._from_native_string("04 03 01"), datetime.date(2001, 3, 4))

    def test_multi_formats(self):
        dt = DateVariable("mydate", ['%d %m %Y', '%Y %m %d'])
        assert_raises(ValueError, dt._from_native_string, "2001-03-04")
        assert_raises(ValueError, dt._from_native_string, "04-03-2001")
        eq_(dt._from_native_string("04 03 2001"), datetime.date(2001, 3, 4))
        eq_(dt._from_native_string("2001 03 04"), datetime.date(2001, 3, 4))
Example #8
0
    def greater_than(self, value, context):
        return context.average_rating > value
    
    def less_than(self, value, context):
        return context.average_rating < value


# Defining the scope:

symbols = SymbolTable("global",
    (
        Bind("movie", MovieId(), nl="film", es=u"película"),
    ),
    SymbolTable("movie",
        (
            Bind("id", MovieId(), nl="id", es="id"),
            Bind("title", MovieTitle(), nl="titel", es=u"título"),
            Bind("year", MovieYear(), nl="jaar", es=u"año"),
            Bind("average_rating", MovieAverageRating(), nl="gemiddelde_rating",
                 es=u"puntuación_promedio")
        ),
        nl="film",
        es=u"película"
    ),
)


# Finally, the parse manager:
parse_manager = EvaluableParseManager(symbols, english_grammar, nl=dutch_grammar,
                                      es=castilian_grammar)