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())
def test_retrieving_namespace_with_partially_untrastlated_contents(self): """ When a namespace is requested in a locale in which not all items are available, the namespace with global names should be returned instead. """ bool_var = BoolVar() traffic = TrafficLightVar() st = SymbolTable( "global", (Bind("bool", BoolVar(), es="booleano", fr=u"booléen"), Bind("traffic", TrafficLightVar(), es=u"tráfico")), SymbolTable( "foo", ( Bind("bar", bool_var, es="fulano"), Bind("baz", traffic, es="mengano", fr="bonjour"), ), ), ) # Checking the namespace: namespace = st.get_namespace("fr") eq_(len(namespace.subnamespaces), 1) subnamespace = namespace.subnamespaces["foo"] subnamespace_objects = { 'bar': bool_var, 'bonjour': traffic, } eq_(subnamespace.objects, subnamespace_objects) expected_unbound_objects_global = { u'booléen': BoolVar(), 'traffic': TrafficLightVar(), } eq_(namespace.objects, expected_unbound_objects_global)
def test_constructor_with_variables(self): """The order must not change when the parameters are variable.""" l_op = BoolVar() r_op = BoolVar() operation = Equal(l_op, r_op) eq_(l_op, operation.master_operand) eq_(r_op, operation.slave_operand)
def test_retrieving_existing_global_object(self): objects = { 'bool': BoolVar(), 'traffic': TrafficLightVar(), } st = Namespace(objects) requested_object = st.get_object("bool") eq_(requested_object, BoolVar())
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)
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)
def test_evaluation_order(self): """ For efficiency, the second operand must not be evaluated if the first one is True. """ op1 = BoolVar() op2 = BoolVar() context = {'bool': True} Or(op1, op2)(context) ok_(op1.evaluated) assert_false(op2.evaluated)
def test_retrieving_existing_2nd_level_object(self): sub_objects = { 'bool': BoolVar(), 'traffic': TrafficLightVar(), } global_objects = { 'foo': TrafficLightVar(), } sub_namespace = {'sub1': Namespace(sub_objects)} st = Namespace(global_objects, sub_namespace) requested_object = st.get_object("bool", ["sub1"]) eq_(requested_object, BoolVar())
def test_checking_logical_support(self): class GreetingVariable(Variable): operations = set(["equality"]) def to_python(self, context): pass def equals(self, value, context): pass var1 = BoolVar() var2 = GreetingVariable() # Checking logical support: var1.check_logical_support() assert_raises(InvalidOperationError, var2.check_logical_support)
def test_retrieving_existing_3rd_level_object(self): third_level_objects = { 'bool': BoolVar(), } second_level_objects = { 'traffic': TrafficLightVar(), } global_objects = { 'foo': TrafficLightVar(), 'traffic-violation': TrafficViolationFunc(String("pedestrians")), } third_level_namespaces = {'sub2': Namespace(third_level_objects)} second_level_namespaces = { 'sub1': Namespace(second_level_objects, third_level_namespaces) } st = Namespace(global_objects, second_level_namespaces) requested_object = st.get_object("bool", ["sub1", "sub2"]) eq_(requested_object, BoolVar())
def test_checking_object_and_subtable_sharing_localized_name(self): """ It's valid for an object and a sub-table to share the localized name. """ st1 = SymbolTable( "global", (Bind("current_day", BoolVar(), es="hoy"), ), SymbolTable("today", (), es="hoy"), ) st2 = SymbolTable( "global", (Bind("current_day", BoolVar(), es="hoy"), ), # This sub-name will be called "hoy" in Spanish too: SymbolTable("hoy", ()), ) eq_(st1.validate_scope(), None) eq_(st2.validate_scope(), None)
def test_equivalence(self): tree1 = EvaluableParseTree(BoolVar()) tree2 = EvaluableParseTree(BoolVar()) tree3 = EvaluableParseTree(PedestriansCrossingRoad()) tree4 = ConvertibleParseTree(PlaceholderVariable("my_variable")) ok_(tree1 == tree2) ok_(tree2 == tree1) ok_(tree1 != None) ok_(tree1 != tree3) ok_(tree1 != tree4) ok_(tree2 != tree3) ok_(tree2 != tree4) ok_(tree3 != tree1) ok_(tree3 != tree2) ok_(tree3 != tree4) ok_(tree4 != tree1) ok_(tree4 != tree2) ok_(tree4 != tree3)
def test_constructor_with_variable_before_constant(self): """ The order must change when the first argument is a constant and the other is a variable. """ l_op = String("hello") r_op = BoolVar() operation = Equal(l_op, r_op) eq_(r_op, operation.master_operand) eq_(l_op, operation.slave_operand)
def test_equivalent(self): """Two conjunctions are equivalent if they have the same operands.""" op1 = And(BoolVar(), PedestriansCrossingRoad()) op2 = And(PedestriansCrossingRoad(), BoolVar()) op3 = And(DriversAwaitingGreenLightVar(), BoolVar()) 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)
def test_checking_object_and_subtable_sharing_global_name(self): """ It's valid for an object and a sub-table to share the global name. """ st = SymbolTable( "global", (Bind("today", BoolVar()), ), SymbolTable("today", ()), ) eq_(st.validate_scope(), None)
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)
def test_name_clash_in_grand_children(self): """ The scope must be validated even inside the sub-tables. """ sciences_st1 = SymbolTable( "sciences", (), SymbolTable("maths", (), es=u"matemática"), SymbolTable("computing", ()), SymbolTable("maths", ()), ) sciences_st2 = SymbolTable( "sciences", (), SymbolTable("maths", (), es=u"matemática"), SymbolTable("computing", ()), SymbolTable("mathematics", (), es=u"matemática"), ) sciences_st3 = SymbolTable( "sciences", (), SymbolTable("maths", (), es=u"matemática"), SymbolTable("computing", ()), # This sub-table will be called "matemática" in Spanish too: SymbolTable(u"matemática", ()), ) # Now a name clash at the objects level: sciences_st4 = SymbolTable("global", ( Bind("foo", BoolVar()), Bind("foo", TrafficLightVar(), es="bar"), )) st1 = SymbolTable("global", (), sciences_st1, SymbolTable("society", ())) st2 = SymbolTable("global", (), sciences_st2, SymbolTable("society", ())) st3 = SymbolTable("global", (), sciences_st3, SymbolTable("society", ())) st4 = SymbolTable("global", (), sciences_st4) assert_raises(ScopeError, st1.validate_scope) assert_raises(ScopeError, st2.validate_scope) assert_raises(ScopeError, st3.validate_scope) assert_raises(ScopeError, st4.validate_scope)
def test_checking_valid_table(self): st = SymbolTable( "global", # Bindings/global objects: ( Bind("bool", BoolVar(), es="booleano"), Bind("traffic", TrafficLightVar(), es=u"tráfico"), ), # Sub-tables: SymbolTable( "maths", ( Bind("pi", Number(3.1416)), Bind("e", Number(2.7183)), ), ), ) eq_(st.validate_scope(), None)
def test_equivalence(self): """Two variables are equivalent if they share the same class.""" var1 = TrafficLightVar() var2 = TrafficLightVar() var3 = BoolVar() var1.check_equivalence(var2) var2.check_equivalence(var1) assert_raises(AssertionError, var1.check_equivalence, var3) assert_raises(AssertionError, var2.check_equivalence, var3) assert_raises(AssertionError, var3.check_equivalence, var1) assert_raises(AssertionError, var3.check_equivalence, var1) ok_(var1 == var2) ok_(var2 == var1) ok_(var1 != var3) ok_(var2 != var3) ok_(var3 != var1) ok_(var3 != var2)
def test_equivalence(self): tree1 = ConvertibleParseTree(PlaceholderVariable("my_variable")) tree2 = ConvertibleParseTree(PlaceholderVariable("my_variable")) tree3 = ConvertibleParseTree(String("hello")) tree4 = EvaluableParseTree(BoolVar()) ok_(tree1 == tree2) ok_(tree2 == tree1) ok_(tree1 != None) ok_(tree1 != tree3) ok_(tree1 != tree4) ok_(tree2 != tree3) ok_(tree2 != tree4) ok_(tree3 != tree1) ok_(tree3 != tree2) ok_(tree3 != tree4) ok_(tree4 != tree1) ok_(tree4 != tree2) ok_(tree4 != tree3)
def test_retrieving_namespace_without_children(self): """ A namespace shouldn't have sub-namespaces if the original symbol table doesn't have sub-tables. """ bool_var = BoolVar() traffic = TrafficLightVar() st = SymbolTable( "global", (Bind("bool", bool_var, es="booleano"), Bind("traffic", traffic, es=u"tráfico")), ) # Checking the namespace: global_namespace = st.get_namespace() eq_(len(global_namespace.subnamespaces), 0) # Checking the namespace in Castilian: castilian_namespace = st.get_namespace("es") eq_(len(castilian_namespace.subnamespaces), 0)
def test_retrieving_namespace_with_children(self): """ A namespace should have sub-namespaces for the sub-tables of the original symbol table. """ bool_var = BoolVar() traffic = TrafficLightVar() st = SymbolTable( "global", (Bind("bool", bool_var, es="booleano"), Bind("traffic", traffic, es=u"tráfico")), SymbolTable( "foo", ( Bind("bar", bool_var, es="fulano"), Bind("baz", traffic, es="mengano"), ), ), ) # Checking the namespace: global_namespace = st.get_namespace() eq_(len(global_namespace.subnamespaces), 1) global_subnamespace = global_namespace.subnamespaces["foo"] global_subnamespace_objects = { 'bar': bool_var, 'baz': traffic, } eq_(global_subnamespace.objects, global_subnamespace_objects) # Checking the namespace in Castilian: castilian_namespace = st.get_namespace("es") eq_(len(castilian_namespace.subnamespaces), 1) castilian_subnamespace = castilian_namespace.subnamespaces["foo"] castilian_subnamespace_objects = { 'fulano': bool_var, 'mengano': traffic, } eq_(castilian_subnamespace.objects, castilian_subnamespace_objects)
def test_node_type(self): """Variables are leaf nodes.""" var = BoolVar() ok_(var.is_leaf()) assert_false(var.is_branch())
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)
def test_representation(self): op = Equal(String(u"¿qué hora es?"), BoolVar()) expected = '<Equal <Anonymous variable [BoolVar]> ' \ '<String "¿qué hora es?">>' eq_(repr(op), expected)
def test_with_both_results_as_true(self): operation = Or(BoolVar(), TrafficLightVar()) ok_(operation(dict(bool=True, traffic_light="red")))
def test_constructor_with_operands(self): """The constructor must support actual operands as arguments""" Xor(BoolVar(), TrafficLightVar())
def test_constructor_with_operators(self): """The constructor must support operators as arguments.""" Xor(Not(BoolVar()), Not(TrafficLightVar()))
def test_with_mixed_results(self): operation = Xor(BoolVar(), TrafficLightVar()) ok_(operation(dict(bool=False, traffic_light="red")))
def test_with_both_results_as_false(self): operation = Xor(BoolVar(), TrafficLightVar()) assert_false(operation(dict(bool=False, traffic_light="")))