def test_equivalence(self): """ Two constant sets A and B are equivalent if they have the same cardinality and each element in A is equivalent to one element in B. """ set1 = Set(String("hi"), Set(Number(3), String("hello"))) set2 = Set(String("hi"), Number(3), String("hello")) set3 = Set(Set(String("hello"), Number(3)), String("hi")) set4 = Set(String("hi"), String("hello")) ok_(set1 == set1) assert_false(set1 == set2) ok_(set1 == set3) assert_false(set1 == set4) assert_false(set2 == set1) ok_(set2 == set2) assert_false(set2 == set3) assert_false(set2 == set4) ok_(set3 == set1) assert_false(set3 == set2) ok_(set3 == set3) assert_false(set3 == set4) assert_false(set4 == set1) assert_false(set4 == set2) assert_false(set4 == set3) ok_(set4 == set4)
def test_representation(self): set1 = Set(Number(3), Number(5)) eq_(repr(set1), "<Set <Number 3.0>, <Number 5.0>>") # Now with an empty set: set2 = Set() eq_(repr(set2), "<Set>") # Now with Unicode stuff in it: set3 = Set(String(u"España"), String(u"carabobeño")) eq_(repr(set3), '<Set <String "España">, <String "carabobeño">>')
def test_instantiation(self): """All the members of a set must be operands""" # Instantiation with operands: Set(Number(3), String("hola")) # Instantiation with a non-operand value: try: Set(Number(3), "hola") assert False, "InvalidOperationError exception not raised" except InvalidOperationError, exc: assert 'Item "hola" is not an operand' in unicode(exc)
def test_string_without_symbol_table(self): # With ASCII characters: bind1 = Bind("pi", Number(3.1416)) bind1_as_unicode = unicode(bind1) eq_(bind1_as_unicode, 'Operand 3.1416 bound as "pi"') eq_(bind1_as_unicode, str(bind1)) # With non-ASCII characters: bind2 = Bind(u"pí", Number(3.1416)) bind2_as_unicode = unicode(bind2) eq_(bind2_as_unicode, u'Operand 3.1416 bound as "pí"') eq_(str(bind2), 'Operand 3.1416 bound as "pí"')
def test_python_numbers(self): """Constant numbers represent Python :class:`float` objects.""" integer_number = Number(4) float_number = Number(2.5) py_integer_number = integer_number.get_as_number(None) py_float_number = float_number.get_as_number(None) ok_(isinstance(py_integer_number, float)) ok_(isinstance(py_float_number, float)) eq_(py_integer_number, 4.0) eq_(py_float_number, 2.5)
def test_checking_duplicate_object_global_names(self): """ Two objects cannot have the same global names in the same table. """ st = SymbolTable( "global", ( Bind("e", Number(2.7183), es_VE=u"número e"), Bind("pi", Number(3.1416)), Bind("e", Number(2.71828), es_ES=u"número e"), ), ) assert_raises(ScopeError, st.validate_scope)
def test_left_less_than_right(self): l_op = Number(1) r_op = NumVar() operation = LessEqual(l_op, r_op) context = {'num': 2} ok_(operation(context))
def test_left_less_than_right(self): l_op = Number(1) r_op = NumVar() operation = GreaterEqual(l_op, r_op) context = {'num': 2} assert_false(operation(context))
def test_left_greater_than_right(self): l_op = Number(3) r_op = NumVar() operation = LessThan(l_op, r_op) context = {'num': 2} assert_false(operation(context))
def test_string_with_symbol_table(self): # With ASCII characters: bind1 = Bind("pi", Number(3.1416)) SymbolTable("global", [bind1]) bind1_as_unicode = unicode(bind1) eq_('Operand 3.1416 bound as "pi" (in Symbol table global)', bind1_as_unicode) eq_(str(bind1), bind1_as_unicode) # With non-ASCII characters: bind2 = Bind(u"pí", Number(3.1416)) SymbolTable("global", [bind2]) bind2_as_unicode = unicode(bind2) eq_(u'Operand 3.1416 bound as "pí" (in Symbol table global)', bind2_as_unicode) eq_('Operand 3.1416 bound as "pí" (in Symbol table global)', str(bind2))
def test_left_greater_than_right(self): l_op = Number(3) r_op = NumVar() operation = GreaterEqual(l_op, r_op) context = {'num': 2} ok_(operation(context))
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 constant numbers are equivalent if they represent the same number. """ number1 = Number(22) number2 = Number(23) number3 = Number(22) ok_(number1 == number1) assert_false(number1 == number2) ok_(number1 == number3) assert_false(number2 == number1) ok_(number2 == number2) assert_false(number2 == number3) ok_(number3 == number1) assert_false(number3 == number2) ok_(number3 == number3)
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_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_parsing_with_localized_grammars(self): castilian_grammar = Grammar(decimal_separator=",", thousands_separator=".") mgr = ConvertibleParseManager(Grammar(), es=castilian_grammar) parse_tree = mgr.parse(u"tráfico:peatones_cruzando_calle <= 3,00", "es") expected_tree = ConvertibleParseTree( LessEqual( PlaceholderVariable("peatones_cruzando_calle", (u"tráfico", )), Number(3.0))) eq_(parse_tree, expected_tree)
def test_python_numbers(self): """Constant numbers represent Python :class:`float` objects.""" integer_number = Number(4) float_number = Number(2.5) py_integer_number = integer_number.get_as_number(None) py_float_number = float_number.get_as_number(None) ok_(isinstance(py_integer_number, float)) ok_(isinstance(py_float_number, float)) eq_(py_integer_number, 4.0) eq_(py_float_number, 2.5)
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_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 '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 'fr'" ok_(info in log_handler.handler.messages['info']) log_handler.undo()
def test_checking_duplicate_object_localized_names(self): """ Two objects cannot have the same localized names in the same table. """ st1 = SymbolTable( "global", ( Bind("e", Number(2.7183), es_VE=u"número e"), Bind("pi", Number(3.1416)), Bind("eulers-number", Number(2.71828), es_VE=u"número e"), ), ) st2 = SymbolTable( "global", ( Bind("e", Number(2.7183), es_VE=u"número e"), Bind("pi", Number(3.1416)), # These object will be called "número e" in Spanish too: Bind(u"número e", Number(2.71828)), ), ) assert_raises(ScopeError, st1.validate_scope) assert_raises(ScopeError, st2.validate_scope)
def test_representation(self): number = Number(4) eq_(repr(number), "<Number 4.0>")
def test_node_type(self): """Numbers are leaf nodes and implement the Number datatype.""" number = Number(4) ok_(number.is_leaf) ok_(isinstance(number, NumberType))
def test_constant_evaluation(self): subset = Set(Number(3), Number(1), Number(7)) set_ = Set(Number(1), Number(3), Number(5), Number(7), Number(11)) operation = IsSubset(subset, set_) ok_(operation(None))
def test_set_and_set(self): subset = Set(Number(2), Number(4)) set_ = Set(Number(1), Number(3), Number(5), Number(7), Number(11)) operation = IsSubset(subset, set_) eq_(operation.master_operand, set_) eq_(operation.slave_operand, subset)
def test_constant_evaluation(self): item = Number(3) set_ = Set(Number(1), Number(3), Number(5), Number(7), Number(11)) operation = BelongsTo(item, set_) ok_(operation(None))
def convert_number(self, number): return Number(number)
def test_identical_values(self): l_op = Number(3) r_op = Number(3) operation = GreaterEqual(l_op, r_op) ok_(operation(None))
def test_identical_values(self): l_op = Number(3) r_op = Number(3) operation = GreaterThan(l_op, r_op) assert_false(operation(None))
def make_number(self, tokens): """Make a Number constant using the token passed.""" return Number(tokens[0])
def test_item_and_set(self): item = Number(3) set_ = Set(Number(1), Number(3), Number(5), Number(7), Number(11)) operation = BelongsTo(item, set_) eq_(operation.master_operand, set_) eq_(operation.slave_operand, item)