def test_ast_conditional_comprehension_error(self): iterable_expression = ast.SymbolExpression(context, 'iterable') comprehension = ast.ComprehensionExpression( context, ast.NullExpression(context), 'member', iterable_expression) with self.assertRaises(errors.EvaluationError): comprehension.evaluate({'iterable': None})
def test_ast_expression_symbol_type(self): context = engine.Context(type_resolver=self._type_resolver) symbol = ast.SymbolExpression(context, self.sym_name) self.assertIs(symbol.result_type, ast.DataType.STRING) self.assertEqual(symbol.name, self.sym_name) self.assertEqual(symbol.evaluate({self.sym_name: self.sym_value}), self.sym_value)
def test_ast_expression_symbol(self): symbol = ast.SymbolExpression(engine.Context(), self.sym_strname) self.assertIs(symbol.result_type, ast.DataType.UNDEFINED) self.assertEqual(symbol.name, self.sym_strname) self.assertEqual( symbol.evaluate({self.sym_strname: self.sym_strvalue}), self.sym_strvalue)
def test_ast_expression_attribute_error(self): symbol = ast.SymbolExpression(context, 'foo') expression = ast.GetAttributeExpression(context, symbol, 'bar') with self.assertRaises(errors.AttributeResolutionError): expression.evaluate({'foo': 1}) with self.assertRaises(errors.AttributeResolutionError): expression.evaluate({'foo': 'baz'})
def test_ast_expression_left_operator_right_comparison(self): chain = tuple( itertools.chain((ast.SymbolExpression(context, 'pi'), ), trueish, falseish)) for left, right in itertools.product(chain, chain): self.assertExpressionTests('eq', left, right, left is right) for left, right in itertools.product(chain, chain): self.assertExpressionTests('ne', left, right, left is not right)
def test_ast_expression_symbol_scope_error(self): symbol = ast.SymbolExpression(context, 'fake-name', scope='fake-scope') try: symbol.evaluate(None) except errors.SymbolResolutionError as error: self.assertEqual(error.symbol_name, 'fake-name') self.assertEqual(error.symbol_scope, 'fake-scope') else: self.fail('SymbolResolutionError was not raised')
def test_ast_expression_array_attributes(self): ary = [1, 2, 3] symbol = ast.SymbolExpression(context, 'ary') attributes = {'length': len(ary), 'to_set': set(ary)} for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate({'ary': ary}), value, "attribute {} failed".format(attribute_name))
def test_ast_expression_set_attributes(self): set_ = {1, 2, 3} symbol = ast.SymbolExpression(context, 'set') attributes = {'length': len(set_), 'to_ary': tuple(set_)} for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate({'set': set_}), value, "attribute {} failed".format(attribute_name))
def test_ast_expression_symbol_type_errors(self): context = engine.Context(type_resolver=self._type_resolver) symbol = ast.SymbolExpression(context, self.sym_name) self.assertIs(symbol.result_type, ast.DataType.STRING) self.assertEqual(symbol.name, self.sym_name) with self.assertRaises(errors.SymbolTypeError): self.assertEqual( symbol.evaluate({self.sym_name: not self.sym_value}), self.sym_value) self.assertIsNone(symbol.evaluate({self.sym_name: None}))
def test_ast_expression_getitem_safe(self): sym_name = ''.join( random.choice(string.ascii_letters) for _ in range(10)) container = ast.SymbolExpression(context, sym_name) member = ast.FloatExpression(context, 0) get_item = ast.GetItemExpression(context, container, member) with self.assertRaises(errors.EvaluationError): get_item.evaluate({sym_name: None}) get_item = ast.GetItemExpression(context, container, member, safe=True) self.assertIsNone(get_item.evaluate({sym_name: None}))
def test_ast_conditional_comprehension(self): iterable = (None, ) iterable_expression = ast.LiteralExpressionBase.from_value( context, iterable) comprehension = ast.ComprehensionExpression( context, ast.NullExpression(context), 'test', iterable_expression, condition=ast.SymbolExpression(context, 'test')) self.assertEqual(comprehension.evaluate(None), ())
def test_ast_expression_mapping_attributes(self): mapping = dict(one=1, two=2, three=3) symbol = ast.SymbolExpression(context, 'map') attributes = { 'keys': tuple(mapping.keys()), 'is_empty': len(mapping) == 0, 'length': len(mapping), 'values': tuple(mapping.values()), } for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate({'map': mapping}), value, "attribute {} failed".format(attribute_name))
def test_ast_expression_getslice_safe(self): sym_name = ''.join( random.choice(string.ascii_letters) for _ in range(10)) container = ast.SymbolExpression(context, sym_name) start = ast.FloatExpression(context, 0) stop = ast.FloatExpression(context, -1) get_slice = ast.GetSliceExpression(context, container, start, stop) with self.assertRaises(errors.EvaluationError): get_slice.evaluate({sym_name: None}) get_slice = ast.GetSliceExpression(context, container, start, stop, safe=True) self.assertIsNone(get_slice.evaluate({sym_name: None}))
def test_ast_expression_symbol_type_errors(self): context = engine.Context(type_resolver=self._type_resolver) symbol = ast.SymbolExpression(context, self.sym_strname) self.assertIs(symbol.result_type, ast.DataType.STRING) self.assertEqual(symbol.name, self.sym_strname) with self.assertRaises(errors.SymbolTypeError): self.assertEqual( symbol.evaluate({self.sym_strname: not self.sym_strvalue}), self.sym_strvalue) self.assertIsNone(symbol.evaluate({self.sym_strname: None})) symbol = ast.SymbolExpression(context, self.sym_aryname) with self.assertRaises(errors.SymbolTypeError): symbol.evaluate({self.sym_aryname: self.sym_aryvalue_nullable}) try: symbol.evaluate({self.sym_aryname: self.sym_aryvalue}) except errors.SymbolTypeError: self.fail('raises SymbolTypeError when it should not') symbol = ast.SymbolExpression(context, self.sym_aryname_nontyped) try: symbol.evaluate({self.sym_aryname_nontyped: self.sym_aryvalue}) symbol.evaluate( {self.sym_aryname_nontyped: self.sym_aryvalue_nontyped}) symbol.evaluate( {self.sym_aryname_nontyped: self.sym_aryvalue_nullable}) except errors.SymbolTypeError: self.fail('raises SymbolTypeError when it should not') symbol = ast.SymbolExpression(context, self.sym_aryname_nullable) try: symbol.evaluate({self.sym_aryname_nullable: self.sym_aryvalue}) symbol.evaluate( {self.sym_aryname_nullable: self.sym_aryvalue_nullable}) except errors.SymbolTypeError: self.fail('raises SymbolTypeError when it should not')
def test_ast_expression_mapping_attributes(self): mapping = dict(one=1, two=2, three=3) symbol = ast.SymbolExpression(context, 'map') attributes = { 'keys': tuple(mapping.keys()), 'is_empty': len(mapping) == 0, 'length': len(mapping), 'values': tuple(mapping.values()), } for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate({'map': mapping}), value, "attribute {} failed".format(attribute_name)) # verify that accessing mapping keys as attributes maintains the preference of attributes over keys expression = ast.GetAttributeExpression(context, symbol, 'length') self.assertEqual(expression.evaluate({'map': {'length': -1}}), 1)
def test_ast_expression_left_operator_right_fuzzycomparison_type_errors( self): operations = ('eq_fzm', 'eq_fzs', 'ne_fzm', 'ne_fzs') for operation, left, right in itertools.product( operations, trueish, falseish): if isinstance( left, (ast.NullExpression, ast.StringExpression)) and isinstance( right, (ast.NullExpression, ast.StringExpression)): continue with self.assertRaises(errors.EvaluationError): self.assertExpressionTests(operation, left, right) string = ast.StringExpression(context, 'string') symbol = ast.SymbolExpression(context, 'zero') for operation in operations: with self.assertRaises(errors.EvaluationError): self.assertExpressionTests(operation, string, symbol) with self.assertRaises(errors.EvaluationError): self.assertExpressionTests(operation, symbol, string)
def test_ast_expression_left_operator_right_fuzzycomparison_symbolic(self): fuzzy = functools.partial(ast.SymbolExpression, context) darth = ast.SymbolExpression(context, 'darth') self.assertExpressionTests('eq_fzm', right_value=self.luke, equals_value=True) self.assertExpressionTests('eq_fzm', right_value=fuzzy('luke'), equals_value=False) self.assertExpressionTests('eq_fzm', right_value=darth, equals_value=False) self.assertExpressionTests('eq_fzs', right_value=self.luke, equals_value=True) self.assertExpressionTests('eq_fzs', right_value=fuzzy('luke'), equals_value=True) self.assertExpressionTests('eq_fzs', right_value=darth, equals_value=False) self.assertExpressionTests('ne_fzm', right_value=self.luke, equals_value=False) self.assertExpressionTests('ne_fzm', right_value=fuzzy('luke'), equals_value=True) self.assertExpressionTests('ne_fzm', right_value=darth, equals_value=True) self.assertExpressionTests('ne_fzs', right_value=self.luke, equals_value=False) self.assertExpressionTests('ne_fzs', right_value=fuzzy('luke'), equals_value=False) self.assertExpressionTests('ne_fzs', right_value=darth, equals_value=True)
def test_ast_expression_float_attributes(self): flt = decimal.Decimal('3.14159') symbol = ast.SymbolExpression(context, 'flt') attributes = { 'ceiling': decimal.Decimal('4'), 'floor': decimal.Decimal('3'), 'to_str': '3.14159' } for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate({'flt': flt}), value, "attribute {} failed".format(attribute_name)) # check special values too expression = ast.GetAttributeExpression(context, symbol, 'to_str') for value in ('nan', 'inf', '-inf'): flt = decimal.Decimal(value) self.assertEqual(expression.evaluate({'flt': flt}), value, "attribute {} failed".format(attribute_name))
def setUp(self): self.sym_name = ''.join( random.choice(string.ascii_letters) for _ in range(10)) self.symbol = ast.SymbolExpression(context, self.sym_name) self.assertEqual(self.symbol.name, self.sym_name)
def test_ast_expression_symbol_scope(self): symbol = ast.SymbolExpression(context, 'test', scope='built-in') expression = ast.GetAttributeExpression(context, symbol, 'one') value = expression.evaluate(None) self.assertIsInstance(value, float) self.assertEqual(value, 1.0)