Пример #1
0
def test_visits_in_pararell_allows_early_exit_while_visiting():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter(self, node, key, parent, *args):
            visited.append(
                ['enter',
                 type(node).__name__,
                 getattr(node, 'value', None)])

        def leave(self, node, key, parent, *args):
            visited.append(
                ['leave',
                 type(node).__name__,
                 getattr(node, 'value', None)])
            if type(node).__name__ == 'Name' and node.value == 'x':
                return BREAK

    visit(ast, ParallelVisitor([TestVisitor()]))
    assert visited == [['enter', 'Document', None],
                       ['enter', 'OperationDefinition', None],
                       ['enter', 'SelectionSet', None],
                       ['enter', 'Field', None], ['enter', 'Name', 'a'],
                       ['leave', 'Name', 'a'], ['leave', 'Field', None],
                       ['enter', 'Field', None], ['enter', 'Name', 'b'],
                       ['leave', 'Name', 'b'], ['enter', 'SelectionSet', None],
                       ['enter', 'Field', None], ['enter', 'Name', 'x'],
                       ['leave', 'Name', 'x']]
Пример #2
0
def test_visits_in_pararell_allows_for_editing_on_enter():
    # type: () -> None
    visited = []
    ast = parse("{ a, b, c { a, b, c } }", no_location=True)

    class TestVisitor1(Visitor):
        def enter(self, node, key, parent, *args):
            # type: (Any, Union[None, int, str], Any, *List[Any]) -> Optional[Any]
            if type(node).__name__ == "Field" and node.name.value == "b":
                return REMOVE

    class TestVisitor2(Visitor):
        def enter(self, node, key, parent, *args):
            # type: (Any, Union[None, int, str], Any, *List[Any]) -> None
            visited.append(["enter", type(node).__name__, getattr(node, "value", None)])

        def leave(
            self,
            node,  # type: Union[Field, Name]
            key,  # type: Union[int, str]
            parent,  # type: Union[List[Field], Field]
            *args  # type: List[Any]
        ):
            # type: (...) -> None
            visited.append(["leave", type(node).__name__, getattr(node, "value", None)])

    edited_ast = visit(ast, ParallelVisitor([TestVisitor1(), TestVisitor2()]))

    assert ast == parse("{ a, b, c { a, b, c } }", no_location=True)
    assert edited_ast == parse("{ a,    c { a,    c } }", no_location=True)

    assert visited == [
        ["enter", "Document", None],
        ["enter", "OperationDefinition", None],
        ["enter", "SelectionSet", None],
        ["enter", "Field", None],
        ["enter", "Name", "a"],
        ["leave", "Name", "a"],
        ["leave", "Field", None],
        ["enter", "Field", None],
        ["enter", "Name", "c"],
        ["leave", "Name", "c"],
        ["enter", "SelectionSet", None],
        ["enter", "Field", None],
        ["enter", "Name", "a"],
        ["leave", "Name", "a"],
        ["leave", "Field", None],
        ["enter", "Field", None],
        ["enter", "Name", "c"],
        ["leave", "Name", "c"],
        ["leave", "Field", None],
        ["leave", "SelectionSet", None],
        ["leave", "Field", None],
        ["leave", "SelectionSet", None],
        ["leave", "OperationDefinition", None],
        ["leave", "Document", None],
    ]
Пример #3
0
def test_visits_in_pararell_allows_for_editing_on_leave():
    visited = []
    ast = parse('{ a, b, c { a, b, c } }', no_location=True)

    class TestVisitor1(Visitor):
        def leave(self, node, key, parent, *args):
            if type(node).__name__ == 'Field' and node.name.value == 'b':
                return REMOVE

    class TestVisitor2(Visitor):
        def enter(self, node, key, parent, *args):
            visited.append(
                ['enter',
                 type(node).__name__,
                 getattr(node, 'value', None)])

        def leave(self, node, key, parent, *args):
            visited.append(
                ['leave',
                 type(node).__name__,
                 getattr(node, 'value', None)])

    edited_ast = visit(ast, ParallelVisitor([TestVisitor1(), TestVisitor2()]))

    assert ast == parse('{ a, b, c { a, b, c } }', no_location=True)
    assert edited_ast == parse('{ a,    c { a,    c } }', no_location=True)

    assert visited == [['enter', 'Document', None],
                       ['enter', 'OperationDefinition', None],
                       ['enter',
                        'SelectionSet', None], ['enter', 'Field', None],
                       ['enter', 'Name', 'a'], ['leave', 'Name', 'a'],
                       ['leave', 'Field', None], ['enter', 'Field', None],
                       ['enter', 'Name', 'b'], ['leave', 'Name', 'b'],
                       ['enter', 'Field', None], ['enter', 'Name', 'c'],
                       ['leave', 'Name', 'c'], ['enter', 'SelectionSet', None],
                       ['enter', 'Field', None], ['enter', 'Name', 'a'],
                       ['leave', 'Name', 'a'], ['leave', 'Field', None],
                       ['enter', 'Field', None], ['enter', 'Name', 'b'],
                       ['leave', 'Name', 'b'], ['enter', 'Field', None],
                       ['enter', 'Name', 'c'], ['leave', 'Name', 'c'],
                       ['leave', 'Field',
                        None], ['leave', 'SelectionSet', None],
                       ['leave', 'Field', None],
                       ['leave', 'SelectionSet', None],
                       ['leave', 'OperationDefinition', None],
                       ['leave', 'Document', None]]
Пример #4
0
def test_visits_in_pararell_allows_skipping_a_subtree():
    # type: () -> None
    visited = []
    ast = parse("{ a, b { x }, c }")

    class TestVisitor(Visitor):
        def enter(self, node, key, parent, *args):
            # type: (Any, Union[None, int, str], Any, *List[Any]) -> Optional[Any]
            visited.append(
                ["enter",
                 type(node).__name__,
                 getattr(node, "value", None)])
            if type(node).__name__ == "Field" and node.name.value == "b":
                return False

        def leave(
            self,
            node,  # type: Union[Field, Name, SelectionSet]
            key,  # type: Union[int, str]
            parent,  # type: Union[List[Field], Field, OperationDefinition]
            *args  # type: List[Any]
        ):
            # type: (...) -> None
            visited.append(
                ["leave",
                 type(node).__name__,
                 getattr(node, "value", None)])

    visit(ast, ParallelVisitor([TestVisitor()]))
    assert visited == [
        ["enter", "Document", None],
        ["enter", "OperationDefinition", None],
        ["enter", "SelectionSet", None],
        ["enter", "Field", None],
        ["enter", "Name", "a"],
        ["leave", "Name", "a"],
        ["leave", "Field", None],
        ["enter", "Field", None],
        ["enter", "Field", None],
        ["enter", "Name", "c"],
        ["leave", "Name", "c"],
        ["leave", "Field", None],
        ["leave", "SelectionSet", None],
        ["leave", "OperationDefinition", None],
        ["leave", "Document", None],
    ]
Пример #5
0
def test_visits_in_pararell_allows_early_exit_while_visiting():
    # type: () -> None
    visited = []
    ast = parse("{ a, b { x }, c }")

    class TestVisitor(Visitor):
        def enter(self, node, key, parent, *args):
            # type: (Any, Union[None, int, str], Any, *List[Any]) -> None
            visited.append(
                ["enter",
                 type(node).__name__,
                 getattr(node, "value", None)])

        def leave(
                self,
                node,  # type: Union[Field, Name]
                key,  # type: Union[int, str]
                parent,  # type: Union[List[Field], Field]
                *args  # type: List[Any]
        ):
            # type: (...) -> Optional[object]
            visited.append(
                ["leave",
                 type(node).__name__,
                 getattr(node, "value", None)])
            if type(node).__name__ == "Name" and node.value == "x":
                return BREAK

    visit(ast, ParallelVisitor([TestVisitor()]))
    assert visited == [
        ["enter", "Document", None],
        ["enter", "OperationDefinition", None],
        ["enter", "SelectionSet", None],
        ["enter", "Field", None],
        ["enter", "Name", "a"],
        ["leave", "Name", "a"],
        ["leave", "Field", None],
        ["enter", "Field", None],
        ["enter", "Name", "b"],
        ["leave", "Name", "b"],
        ["enter", "SelectionSet", None],
        ["enter", "Field", None],
        ["enter", "Name", "x"],
        ["leave", "Name", "x"],
    ]
Пример #6
0
def test_visits_in_pararell_allows_skipping_a_subtree():
    visited = []
    ast = parse('{ a, b { x }, c }')

    class TestVisitor(Visitor):
        def enter(self, node, key, parent, *args):
            visited.append(
                ['enter',
                 type(node).__name__,
                 getattr(node, 'value', None)])
            if type(node).__name__ == 'Field' and node.name.value == 'b':
                return False

        def leave(self, node, key, parent, *args):
            visited.append(
                ['leave',
                 type(node).__name__,
                 getattr(node, 'value', None)])

    visit(ast, ParallelVisitor([TestVisitor()]))
    assert visited == [
        ['enter', 'Document', None],
        ['enter', 'OperationDefinition', None],
        ['enter', 'SelectionSet', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'a'],
        ['leave', 'Name', 'a'],
        ['leave', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Field', None],
        ['enter', 'Name', 'c'],
        ['leave', 'Name', 'c'],
        ['leave', 'Field', None],
        ['leave', 'SelectionSet', None],
        ['leave', 'OperationDefinition', None],
        ['leave', 'Document', None],
    ]
Пример #7
0
def test_visits_in_pararell_allows_early_exit_from_different_points():
    visited = []
    ast = parse('{ a { y }, b { x } }')

    class TestVisitor(Visitor):
        def __init__(self, name):
            self.name = name

        def enter(self, node, key, parent, *args):
            visited.append([
                "break-{}".format(self.name), 'enter',
                type(node).__name__,
                getattr(node, 'value', None)
            ])

        def leave(self, node, key, parent, *args):
            visited.append([
                "break-{}".format(self.name), 'leave',
                type(node).__name__,
                getattr(node, 'value', None)
            ])
            if type(node).__name__ == 'Field' and node.name.value == self.name:
                return BREAK

    visit(ast, ParallelVisitor([TestVisitor('a'), TestVisitor('b')]))
    assert visited == [['break-a', 'enter', 'Document', None],
                       ['break-b', 'enter', 'Document', None],
                       ['break-a', 'enter', 'OperationDefinition', None],
                       ['break-b', 'enter', 'OperationDefinition', None],
                       ['break-a', 'enter', 'SelectionSet', None],
                       ['break-b', 'enter', 'SelectionSet', None],
                       ['break-a', 'enter', 'Field', None],
                       ['break-b', 'enter', 'Field', None],
                       ['break-a', 'enter', 'Name', 'a'],
                       ['break-b', 'enter', 'Name', 'a'],
                       ['break-a', 'leave', 'Name', 'a'],
                       ['break-b', 'leave', 'Name', 'a'],
                       ['break-a', 'enter', 'SelectionSet', None],
                       ['break-b', 'enter', 'SelectionSet', None],
                       ['break-a', 'enter', 'Field', None],
                       ['break-b', 'enter', 'Field', None],
                       ['break-a', 'enter', 'Name', 'y'],
                       ['break-b', 'enter', 'Name', 'y'],
                       ['break-a', 'leave', 'Name', 'y'],
                       ['break-b', 'leave', 'Name', 'y'],
                       ['break-a', 'leave', 'Field', None],
                       ['break-b', 'leave', 'Field', None],
                       ['break-a', 'leave', 'SelectionSet', None],
                       ['break-b', 'leave', 'SelectionSet', None],
                       ['break-a', 'leave', 'Field', None],
                       ['break-b', 'leave', 'Field', None],
                       ['break-b', 'enter', 'Field', None],
                       ['break-b', 'enter', 'Name', 'b'],
                       ['break-b', 'leave', 'Name', 'b'],
                       ['break-b', 'enter', 'SelectionSet', None],
                       ['break-b', 'enter', 'Field', None],
                       ['break-b', 'enter', 'Name', 'x'],
                       ['break-b', 'leave', 'Name', 'x'],
                       ['break-b', 'leave', 'Field', None],
                       ['break-b', 'leave', 'SelectionSet', None],
                       ['break-b', 'leave', 'Field', None]]
Пример #8
0
def test_visits_in_pararell_allows_early_exit_from_different_points():
    # type: () -> None
    visited = []
    ast = parse("{ a { y }, b { x } }")

    class TestVisitor(Visitor):
        def __init__(self, name):
            # type: (str) -> None
            self.name = name

        def enter(
            self,
            node,  # type: Union[Document, OperationDefinition, SelectionSet]
            key,  # type: Union[None, int, str]
            parent,  # type: Union[List[OperationDefinition], None, OperationDefinition]
            *args  # type: Any
        ):
            # type: (...) -> None
            visited.append(
                [
                    "break-{}".format(self.name),
                    "enter",
                    type(node).__name__,
                    getattr(node, "value", None),
                ]
            )

        def leave(
            self,
            node,  # type: Union[Field, Name]
            key,  # type: Union[int, str]
            parent,  # type: Union[List[Field], Field]
            *args  # type: List[Any]
        ):
            # type: (...) -> Optional[Any]
            visited.append(
                [
                    "break-{}".format(self.name),
                    "leave",
                    type(node).__name__,
                    getattr(node, "value", None),
                ]
            )
            if type(node).__name__ == "Field" and node.name.value == self.name:
                return BREAK

    visit(ast, ParallelVisitor([TestVisitor("a"), TestVisitor("b")]))
    assert visited == [
        ["break-a", "enter", "Document", None],
        ["break-b", "enter", "Document", None],
        ["break-a", "enter", "OperationDefinition", None],
        ["break-b", "enter", "OperationDefinition", None],
        ["break-a", "enter", "SelectionSet", None],
        ["break-b", "enter", "SelectionSet", None],
        ["break-a", "enter", "Field", None],
        ["break-b", "enter", "Field", None],
        ["break-a", "enter", "Name", "a"],
        ["break-b", "enter", "Name", "a"],
        ["break-a", "leave", "Name", "a"],
        ["break-b", "leave", "Name", "a"],
        ["break-a", "enter", "SelectionSet", None],
        ["break-b", "enter", "SelectionSet", None],
        ["break-a", "enter", "Field", None],
        ["break-b", "enter", "Field", None],
        ["break-a", "enter", "Name", "y"],
        ["break-b", "enter", "Name", "y"],
        ["break-a", "leave", "Name", "y"],
        ["break-b", "leave", "Name", "y"],
        ["break-a", "leave", "Field", None],
        ["break-b", "leave", "Field", None],
        ["break-a", "leave", "SelectionSet", None],
        ["break-b", "leave", "SelectionSet", None],
        ["break-a", "leave", "Field", None],
        ["break-b", "leave", "Field", None],
        ["break-b", "enter", "Field", None],
        ["break-b", "enter", "Name", "b"],
        ["break-b", "leave", "Name", "b"],
        ["break-b", "enter", "SelectionSet", None],
        ["break-b", "enter", "Field", None],
        ["break-b", "enter", "Name", "x"],
        ["break-b", "leave", "Name", "x"],
        ["break-b", "leave", "Field", None],
        ["break-b", "leave", "SelectionSet", None],
        ["break-b", "leave", "Field", None],
    ]