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_datetime_attributes(self): timestamp = datetime.datetime(2019, 9, 11, 20, 46, 57, 506406, tzinfo=dateutil.tz.UTC) symbol = ast.DatetimeExpression(engine.Context(), timestamp) attributes = { 'day': 11, 'hour': 20, 'microsecond': 506406, 'millisecond': 506.406, 'minute': 46, 'month': 9, 'second': 57, 'weekday': timestamp.strftime('%A'), 'year': 2019, 'zone_name': 'UTC', } for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate(None), value, "attribute {} failed".format(attribute_name))
def test_ast_expression_string_attributes_flt(self): combos = (('3.14159', decimal.Decimal('3.14159')), ('0xdead', 0xdead), ('3.14e5', decimal.Decimal('3.14e5'))) for str_value, flt_value in combos: symbol = ast.StringExpression(context, str_value) expression = ast.GetAttributeExpression(context, symbol, 'to_flt') self.assertEqual(expression.evaluate(None), flt_value, "attribute {} failed".format(str_value))
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_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_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 test_ast_expression_string_attributes_numeric(self): symbol = ast.StringExpression(context, '123') attributes = { 'to_int': 123.0, 'to_flt': 123.0, } for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate(None), value, "attribute {} failed".format(attribute_name)) expression = ast.GetAttributeExpression( context, ast.StringExpression(context, 'Foobar'), 'to_flt') self.assertTrue(math.isnan(expression.evaluate(None))) with self.assertRaises(errors.EvaluationError): expression = ast.GetAttributeExpression( context, ast.StringExpression(context, 'Foobar'), 'to_int') self.assertEqual(expression.evaluate(None), float('nan')) expression = ast.GetAttributeExpression( context, ast.StringExpression(context, 'inf'), 'to_flt') self.assertEqual(expression.evaluate(None), float('inf'))
def test_ast_expression_string_attributes(self): string = 'Rule Engine' symbol = ast.StringExpression(engine.Context(), string) attributes = { 'as_lower': string.lower(), 'as_upper': string.upper(), 'length': len(string), } for attribute_name, value in attributes.items(): expression = ast.GetAttributeExpression(context, symbol, attribute_name) self.assertEqual(expression.evaluate(None), value, "attribute {} failed".format(attribute_name))
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_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)