|
1 | 1 | from graphql.core.language.ast import Field, Name, SelectionSet
|
2 | 2 | from graphql.core.language.parser import parse
|
3 |
| -from graphql.core.language.visitor import BREAK, REMOVE, Visitor, visit, ParallelVisitor |
| 3 | +from graphql.core.language.visitor import ( |
| 4 | + BREAK, REMOVE, Visitor, visit, ParallelVisitor) |
4 | 5 |
|
5 | 6 | from .fixtures import KITCHEN_SINK
|
6 | 7 |
|
@@ -578,3 +579,98 @@ def leave(self, node, key, parent, *args):
|
578 | 579 | ['no-a', 'leave', 'Document', None],
|
579 | 580 | ['no-b', 'leave', 'Document', None],
|
580 | 581 | ]
|
| 582 | + |
| 583 | + |
| 584 | +def test_visits_in_pararell_allows_early_exit_while_visiting(): |
| 585 | + visited = [] |
| 586 | + ast = parse('{ a, b { x }, c }') |
| 587 | + |
| 588 | + class TestVisitor(Visitor): |
| 589 | + |
| 590 | + def enter(self, node, key, parent, *args): |
| 591 | + visited.append( |
| 592 | + ['enter', type(node).__name__, getattr(node, 'value', None)]) |
| 593 | + |
| 594 | + def leave(self, node, key, parent, *args): |
| 595 | + visited.append( |
| 596 | + ['leave', type(node).__name__, getattr(node, 'value', None)]) |
| 597 | + if type(node).__name__ == 'Name' and node.value == 'x': |
| 598 | + return BREAK |
| 599 | + |
| 600 | + visit(ast, ParallelVisitor([TestVisitor()])) |
| 601 | + assert visited == [ |
| 602 | + ['enter', 'Document', None], |
| 603 | + ['enter', 'OperationDefinition', None], |
| 604 | + ['enter', 'SelectionSet', None], |
| 605 | + ['enter', 'Field', None], |
| 606 | + ['enter', 'Name', 'a'], |
| 607 | + ['leave', 'Name', 'a'], |
| 608 | + ['leave', 'Field', None], |
| 609 | + ['enter', 'Field', None], |
| 610 | + ['enter', 'Name', 'b'], |
| 611 | + ['leave', 'Name', 'b'], |
| 612 | + ['enter', 'SelectionSet', None], |
| 613 | + ['enter', 'Field', None], |
| 614 | + ['enter', 'Name', 'x'], |
| 615 | + ['leave', 'Name', 'x'] |
| 616 | + ] |
| 617 | + |
| 618 | + |
| 619 | +def test_visits_in_pararell_allows_early_exit_from_different_points(): |
| 620 | + visited = [] |
| 621 | + ast = parse('{ a { y }, b { x } }') |
| 622 | + |
| 623 | + class TestVisitor(Visitor): |
| 624 | + |
| 625 | + def __init__(self, name): |
| 626 | + self.name = name |
| 627 | + |
| 628 | + def enter(self, node, key, parent, *args): |
| 629 | + visited.append(["break-{}".format(self.name), 'enter', |
| 630 | + type(node).__name__, getattr(node, 'value', None)]) |
| 631 | + |
| 632 | + def leave(self, node, key, parent, *args): |
| 633 | + visited.append(["break-{}".format(self.name), 'leave', |
| 634 | + type(node).__name__, getattr(node, 'value', None)]) |
| 635 | + if type(node).__name__ == 'Field' and node.name.value == self.name: |
| 636 | + return BREAK |
| 637 | + |
| 638 | + visit(ast, ParallelVisitor([TestVisitor('a'), TestVisitor('b')])) |
| 639 | + assert visited == [ |
| 640 | + ['break-a', 'enter', 'Document', None], |
| 641 | + ['break-b', 'enter', 'Document', None], |
| 642 | + ['break-a', 'enter', 'OperationDefinition', None], |
| 643 | + ['break-b', 'enter', 'OperationDefinition', None], |
| 644 | + ['break-a', 'enter', 'SelectionSet', None], |
| 645 | + ['break-b', 'enter', 'SelectionSet', None], |
| 646 | + ['break-a', 'enter', 'Field', None], |
| 647 | + ['break-b', 'enter', 'Field', None], |
| 648 | + ['break-a', 'enter', 'Name', 'a'], |
| 649 | + ['break-b', 'enter', 'Name', 'a'], |
| 650 | + ['break-a', 'leave', 'Name', 'a'], |
| 651 | + ['break-b', 'leave', 'Name', 'a'], |
| 652 | + ['break-a', 'enter', 'SelectionSet', None], |
| 653 | + ['break-b', 'enter', 'SelectionSet', None], |
| 654 | + ['break-a', 'enter', 'Field', None], |
| 655 | + ['break-b', 'enter', 'Field', None], |
| 656 | + ['break-a', 'enter', 'Name', 'y'], |
| 657 | + ['break-b', 'enter', 'Name', 'y'], |
| 658 | + ['break-a', 'leave', 'Name', 'y'], |
| 659 | + ['break-b', 'leave', 'Name', 'y'], |
| 660 | + ['break-a', 'leave', 'Field', None], |
| 661 | + ['break-b', 'leave', 'Field', None], |
| 662 | + ['break-a', 'leave', 'SelectionSet', None], |
| 663 | + ['break-b', 'leave', 'SelectionSet', None], |
| 664 | + ['break-a', 'leave', 'Field', None], |
| 665 | + ['break-b', 'leave', 'Field', None], |
| 666 | + ['break-b', 'enter', 'Field', None], |
| 667 | + ['break-b', 'enter', 'Name', 'b'], |
| 668 | + ['break-b', 'leave', 'Name', 'b'], |
| 669 | + ['break-b', 'enter', 'SelectionSet', None], |
| 670 | + ['break-b', 'enter', 'Field', None], |
| 671 | + ['break-b', 'enter', 'Name', 'x'], |
| 672 | + ['break-b', 'leave', 'Name', 'x'], |
| 673 | + ['break-b', 'leave', 'Field', None], |
| 674 | + ['break-b', 'leave', 'SelectionSet', None], |
| 675 | + ['break-b', 'leave', 'Field', None] |
| 676 | + ] |
0 commit comments