def implicit_cast(self, tree, val, values): """ Creates an AST with the cast. This boils down to - finding the right level to insert the new pow_expression with its respective as_operator - building a correct tree cascade in pow_expression to the old value """ if val == AnyType.instance(): return for i, v in enumerate(values): if i > 0: # ignore the arith_operator tree child i += 1 # check whether a tree child needs casting if v != val: element = tree.children[i] casted_type = self.type_to_tree(element, val) element = Tree('expression', [ element, Tree('as_operator', [ Tree('types', [ casted_type ]) ]) ]) element.kind = 'as_expression' tree.children[i] = element
def test_compiler_if_block_with_else(patch, compiler): patch.object(Objects, 'expression') patch.many(Compiler, ['add_line', 'subtree', 'subtrees']) tree = Tree('if_block', [Tree('nested_block', []), Tree('else_block', [])]) compiler.if_block(tree) compiler.subtrees.assert_called_with(tree.node('else_block'))
def test_objects_mutation_fragment_from_service(token): """ Ensures that mutations objects from service trees are compiled correctly. """ tree = Tree("service_fragment", [Tree("command", [token])]) expected = {"$OBJECT": "mutation", "mutation": token.value, "args": []} assert Objects().mutation_fragment(tree) == expected
def test_faketree_check_existing_multiple_fake(block, fake_tree): """ Checks checking for fake lines with multiple fake paths """ block.children = [ Tree( "assignment", [Tree("path", [Token("NAME", "__p-bar1", line="1.1")])], ), Tree("assignment", [Tree("path", [Token("NAME", "foo", line="1")])]), Tree( "assignment", [Tree("path", [Token("NAME", "__p-bar2", line="2.1")])], ), Tree("assignment", [Tree("path", [Token("NAME", "foo", line="2")])]), Tree( "assignment", [Tree("path", [Token("NAME", "__p-bar3", line="3.1")])], ), ] fake_tree._check_existing_fake_lines(block) assert fake_tree.new_lines == { "__p-bar1": False, "__p-bar2": False, "__p-bar3": False, }
def test_objects_list(patch, tree): patch.object(Objects, "base_expression") tree.children = [Tree("value", "value"), "token"] result = Objects().list(tree) Objects.base_expression.assert_called_with(Tree("value", "value")) items = [Objects.base_expression()] assert result == {"$OBJECT": "list", "items": items}
def test_objects_mutation_fragment_from_service(token): """ Ensures that mutations objects from service trees are compiled correctly. """ tree = Tree('service_fragment', [Tree('command', [token])]) expected = {'$OBJECT': 'mutation', 'mutation': token.value, 'args': []} assert Objects().mutation_fragment(tree) == expected
def test_objects_list(patch, tree): patch.object(Objects, 'base_expression') tree.children = [Tree('value', 'value'), 'token'] result = Objects().list(tree) Objects.base_expression.assert_called_with(Tree('value', 'value')) items = [Objects.base_expression()] assert result == {'$OBJECT': 'list', 'items': items}
def type_cast_expression(expr_node, target_type): """ Type casts the given expr_node to the target_type. This is done by creating a new AST for the expr_node with an `as_operator`. Args: expr_node: Tree node representing an expression. This is the expression for which this function will generate a new expression node which also contains an `as_operator` to represent the type cast. target_type: The type to type cast given expression (expr_node) into. Must be a `types` node. Note: This does not perform any checks around feasibility of performing the type cast operation and depends upon the caller to have had performed these checks before making the call. """ assert expr_node.data == 'expression' assert isinstance(target_type, BaseType) cast_type = SymbolExpressionVisitor.type_to_tree( expr_node, target_type ) element = Tree('expression', [ expr_node, Tree('as_operator', [ Tree('types', [ cast_type ]) ]) ]) element.kind = 'as_expression' return element
def test_tree_find_position_none(): """ Ensures Tree.find_first_token can find the correct Token """ expected = Tree('assignment', []) tree = Tree('start', [Tree('block', [Tree('line', [expected])], expected)]) assert tree._find_position('line') is None
def test_tree_find_position_none(): """ Ensures Tree.find_first_token can find the correct Token """ expected = Tree("assignment", []) tree = Tree("start", [Tree("block", [Tree("line", [expected])], expected)]) assert tree._find_position("line") is None
def test_tree_find_first_token(): """ Ensures Tree.find_first_token can find the correct Token """ expected = Tree('assignment', ['x']) tree = Tree('start', [Tree('block', [Tree('line', [expected])])]) assert tree.find('assignment') == [expected]
def type_to_tree(tree, t): """ Converts a type to its respective AST Tree representation. """ if isinstance(t, ListType): inner = SymbolExpressionVisitor.type_to_tree(tree, t.inner) return Tree('list_type', [ Tree('types', [inner]) ]) if isinstance(t, MapType): key = SymbolExpressionVisitor.type_to_tree(tree, t.key) value = SymbolExpressionVisitor.type_to_tree(tree, t.value) return Tree('map_type', [ key, Tree('types', [value]), ]) if t == BooleanType.instance(): base_type = tree.create_token('BOOLEAN_TYPE', 'boolean') elif t == IntType.instance(): base_type = tree.create_token('INTEGER_TYPE', 'int') elif t == FloatType.instance(): base_type = tree.create_token('FLOAT_TYPE', 'float') elif t == StringType.instance(): base_type = tree.create_token('STRING_TYPE', 'string') elif t == TimeType.instance(): base_type = tree.create_token('TIME_TYPE', 'time') elif t == RegExpType.instance(): base_type = tree.create_token('REGEXP_TYPE', 'regex') else: assert t == AnyType.instance() base_type = tree.create_token('ANY_TYPE', 'any') return Tree('base_type', [base_type])
def test_tree_find_first_token(): """ Ensures Tree.find_first_token can find the correct Token """ expected = Tree("assignment", ["x"]) tree = Tree("start", [Tree("block", [Tree("line", [expected])])]) assert tree.find("assignment") == [expected]
def type_to_tree(tree, t): """ Converts a type to its respective AST Tree representation. """ if isinstance(t, ListType): inner = SymbolExpressionVisitor.type_to_tree(tree, t.inner) return Tree("list_type", [Tree("types", [inner])]) if isinstance(t, MapType): key = SymbolExpressionVisitor.type_to_tree(tree, t.key) value = SymbolExpressionVisitor.type_to_tree(tree, t.value) return Tree("map_type", [key, Tree("types", [value]),]) if t == BooleanType.instance(): base_type = tree.create_token("BOOLEAN_TYPE", "boolean") elif t == IntType.instance(): base_type = tree.create_token("INTEGER_TYPE", "int") elif t == FloatType.instance(): base_type = tree.create_token("FLOAT_TYPE", "float") elif t == StringType.instance(): base_type = tree.create_token("STRING_TYPE", "string") elif t == TimeType.instance(): base_type = tree.create_token("TIME_TYPE", "time") elif t == RegExpType.instance(): base_type = tree.create_token("REGEXP_TYPE", "regex") else: assert t == AnyType.instance() base_type = tree.create_token("ANY_TYPE", "any") return Tree("base_type", [base_type])
def test_tree_walk_token(): """ Ensures that encountered tokens are skipped """ inner_tree = Tree('inner', []) tree = Tree('rule', [Token('test', 'test'), inner_tree]) result = Tree.walk(tree, 'inner') assert result == inner_tree
def test_tree_end_column(): """ Ensures Tree.end_column can find the end column of a tree. """ token = Token('WORD', 'word') token.end_column = 1 tree = Tree('outer', [Tree('path', [token])]) assert tree.end_column() == '1'
def test_tree_walk_token(): """ Ensures that encountered tokens are skipped """ inner_tree = Tree("inner", []) tree = Tree("rule", [Token("test", "test"), inner_tree]) result = Tree.walk(tree, "inner") assert result == inner_tree
def test_tree_end_column(): """ Ensures Tree.end_column can find the end column of a tree. """ token = Token("WORD", "word") token.end_column = 1 tree = Tree("outer", [Tree("path", [token])]) assert tree.end_column() == "1"
def test_compiler_parse_tree(compiler, patch): """ Ensures that the parse_tree method can parse a complete tree """ patch.object(Compiler, 'subtree') tree = Tree('start', [Tree('command', ['token'])]) compiler.parse_tree(tree) compiler.subtree.assert_called_with(Tree('command', ['token']), parent=None)
def test_tree_find_first_token_end(): """ Ensures Tree.find_first_token can find the correct Token """ t2 = Token("X", "x") e1 = Tree("assignment", []) e2 = Tree("assignment", [t2]) tree = Tree("start", [Tree("block", [Tree("line", [e1])]), e2]) assert tree.find_first_token() == t2
def test_objects_names_string(patch, magic, tree): """ Ensures that paths like x['y'] are compiled correctly """ patch.object(Objects, 'string') tree.children = [magic(), Tree('fragment', [Tree('string', 'token')])] result = Objects.names(tree) Objects.string.assert_called_with(Tree('string', 'token')) assert result[1] == Objects.string()
def test_tree_find_first_token_end(): """ Ensures Tree.find_first_token can find the correct Token """ t2 = Token('X', 'x') e1 = Tree('assignment', []) e2 = Tree('assignment', [t2]) tree = Tree('start', [Tree('block', [Tree('line', [e1])]), e2]) assert tree.find_first_token() == t2
def test_objects_objects_key_path(patch, tree): """ Ensures that objects like {x: 0} are compiled """ patch.many(Objects, ['path', 'expression']) subtree = Tree('key_value', [Tree('path', ['path'])]) tree.children = [subtree] result = Objects.objects(tree) assert result['items'][0][0] == Objects.path()
def test_objects_string_templating(patch): patch.object(Objects, 'path') patch.object(re, 'findall', return_value=['color']) tree = Tree('string', [Token('DOUBLE_QUOTED', '"{{color}}"')]) result = Objects.string(tree) re.findall.assert_called_with(r'{{([^}]*)}}', '{{color}}') Objects.path.assert_called_with(Tree('path', [Token('WORD', 'color')])) assert result['string'] == '{}' assert result['values'] == [Objects.path()]
def test_objects_names_string(patch, magic, tree): """ Ensures that paths like x['y'] are compiled correctly """ patch.object(Objects, "string") tree.children = [magic(), Tree("fragment", [Tree("string", "token")])] result = Objects().names(tree) Objects.string.assert_called_with(Tree("string", "token")) assert result[1] == Objects.string()
def test_faketree_check_existing_one_child(block, fake_tree): """ Checks checking for fake lines with an one child block """ block.children = [ Tree("path", [Token("NAME", "foo")]), Tree("assignment", [Tree("path", [Token("NAME", "foo")])]), ] fake_tree._check_existing_fake_lines(block) assert fake_tree.new_lines == {}
def test_objects_number(): """ Ensures that an int is compiled correctly. """ tree = Tree('number', [Token('INT', '1')]) assert Objects.number(tree) == 1 tree = Tree('number', [Token('INT', '+1')]) assert Objects.number(tree) == 1 tree = Tree('number', [Token('INT', '-1')]) assert Objects.number(tree) == -1
def test_objects_names_path(patch, magic, tree): """ Ensures that paths like x[y] are compiled correctly """ patch.object(Objects, 'path') subtree = Tree('path', ['token']) tree.children = [magic(), Tree('fragment', [subtree])] result = Objects.names(tree) Objects.path.assert_called_with(subtree) assert result[1] == Objects.path()
def test_objects_objects(patch, tree): patch.many(Objects, ['string', 'expression']) subtree = Tree('key_value', [Tree('string', ['key']), 'value']) tree.children = [subtree] result = Objects.objects(tree) Objects.string.assert_called_with(subtree.string) Objects.expression.assert_called_with('value') expected = {'$OBJECT': 'dict', 'items': [[Objects.string(), Objects.expression()]]} assert result == expected
def test_objects_number_float(): """ Ensures that a float is compiled correctly. """ tree = Tree('number', [Token('FLOAT', '1.2')]) assert Objects.number(tree) == 1.2 tree = Tree('number', [Token('FLOAT', '+1.2')]) assert Objects.number(tree) == 1.2 tree = Tree('number', [Token('FLOAT', '-1.2')]) assert Objects.number(tree) == -1.2