Skip to content

Commit 699dc10

Browse files
committed
Fix issue with skipping subtrees in parallel visitor
Fixes #254
1 parent 3a6d35b commit 699dc10

File tree

2 files changed

+113
-2
lines changed

2 files changed

+113
-2
lines changed

src/language/__tests__/visitor.js

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { expect } from 'chai';
1111
import { describe, it } from 'mocha';
1212
import { parse } from '../parser';
1313
import { readFileSync } from 'fs';
14-
import { visit, BREAK } from '../visitor';
14+
import { visit, visitInParallel, BREAK } from '../visitor';
1515
import { join } from 'path';
1616

1717

@@ -509,4 +509,115 @@ describe('Visitor', () => {
509509
[ 'leave', 'OperationDefinition', 4, undefined ],
510510
[ 'leave', 'Document', undefined, undefined ] ]);
511511
});
512+
513+
describe('visitInParallel', () => {
514+
515+
// Note: nearly identical to the above test of the same test but
516+
// using visitInParallel.
517+
it('allows skipping a sub-tree', () => {
518+
519+
var visited = [];
520+
521+
var ast = parse('{ a, b { x }, c }');
522+
visit(ast, visitInParallel([ {
523+
enter(node) {
524+
visited.push([ 'enter', node.kind, node.value ]);
525+
if (node.kind === 'Field' && node.name.value === 'b') {
526+
return false;
527+
}
528+
},
529+
530+
leave(node) {
531+
visited.push([ 'leave', node.kind, node.value ]);
532+
}
533+
} ]));
534+
535+
expect(visited).to.deep.equal([
536+
[ 'enter', 'Document', undefined ],
537+
[ 'enter', 'OperationDefinition', undefined ],
538+
[ 'enter', 'SelectionSet', undefined ],
539+
[ 'enter', 'Field', undefined ],
540+
[ 'enter', 'Name', 'a' ],
541+
[ 'leave', 'Name', 'a' ],
542+
[ 'leave', 'Field', undefined ],
543+
[ 'enter', 'Field', undefined ],
544+
[ 'enter', 'Field', undefined ],
545+
[ 'enter', 'Name', 'c' ],
546+
[ 'leave', 'Name', 'c' ],
547+
[ 'leave', 'Field', undefined ],
548+
[ 'leave', 'SelectionSet', undefined ],
549+
[ 'leave', 'OperationDefinition', undefined ],
550+
[ 'leave', 'Document', undefined ],
551+
]);
552+
});
553+
554+
it('allows skipping different sub-trees', () => {
555+
var visited = [];
556+
557+
var ast = parse('{ a { x }, b { y} }');
558+
visit(ast, visitInParallel([
559+
{
560+
enter(node) {
561+
visited.push([ 'no-a', 'enter', node.kind, node.value ]);
562+
if (node.kind === 'Field' && node.name.value === 'a') {
563+
return false;
564+
}
565+
},
566+
leave(node) {
567+
visited.push([ 'no-a', 'leave', node.kind, node.value ]);
568+
}
569+
},
570+
{
571+
enter(node) {
572+
visited.push([ 'no-b', 'enter', node.kind, node.value ]);
573+
if (node.kind === 'Field' && node.name.value === 'b') {
574+
return false;
575+
}
576+
},
577+
leave(node) {
578+
visited.push([ 'no-b', 'leave', node.kind, node.value ]);
579+
}
580+
}
581+
]));
582+
583+
expect(visited).to.deep.equal([
584+
[ 'no-a', 'enter', 'Document', undefined ],
585+
[ 'no-b', 'enter', 'Document', undefined ],
586+
[ 'no-a', 'enter', 'OperationDefinition', undefined ],
587+
[ 'no-b', 'enter', 'OperationDefinition', undefined ],
588+
[ 'no-a', 'enter', 'SelectionSet', undefined ],
589+
[ 'no-b', 'enter', 'SelectionSet', undefined ],
590+
[ 'no-a', 'enter', 'Field', undefined ],
591+
[ 'no-b', 'enter', 'Field', undefined ],
592+
[ 'no-b', 'enter', 'Name', 'a' ],
593+
[ 'no-b', 'leave', 'Name', 'a' ],
594+
[ 'no-b', 'enter', 'SelectionSet', undefined ],
595+
[ 'no-b', 'enter', 'Field', undefined ],
596+
[ 'no-b', 'enter', 'Name', 'x' ],
597+
[ 'no-b', 'leave', 'Name', 'x' ],
598+
[ 'no-b', 'leave', 'Field', undefined ],
599+
[ 'no-b', 'leave', 'SelectionSet', undefined ],
600+
[ 'no-b', 'leave', 'Field', undefined ],
601+
[ 'no-a', 'enter', 'Field', undefined ],
602+
[ 'no-b', 'enter', 'Field', undefined ],
603+
[ 'no-a', 'enter', 'Name', 'b' ],
604+
[ 'no-a', 'leave', 'Name', 'b' ],
605+
[ 'no-a', 'enter', 'SelectionSet', undefined ],
606+
[ 'no-a', 'enter', 'Field', undefined ],
607+
[ 'no-a', 'enter', 'Name', 'y' ],
608+
[ 'no-a', 'leave', 'Name', 'y' ],
609+
[ 'no-a', 'leave', 'Field', undefined ],
610+
[ 'no-a', 'leave', 'SelectionSet', undefined ],
611+
[ 'no-a', 'leave', 'Field', undefined ],
612+
[ 'no-a', 'leave', 'SelectionSet', undefined ],
613+
[ 'no-b', 'leave', 'SelectionSet', undefined ],
614+
[ 'no-a', 'leave', 'OperationDefinition', undefined ],
615+
[ 'no-b', 'leave', 'OperationDefinition', undefined ],
616+
[ 'no-a', 'leave', 'Document', undefined ],
617+
[ 'no-b', 'leave', 'Document', undefined ],
618+
]);
619+
});
620+
621+
});
622+
512623
});

src/language/visitor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ export function visitInParallel(visitors) {
295295
if (fn) {
296296
fn.apply(visitors[i], arguments);
297297
}
298-
} else {
298+
} else if (skipping[i] === node) {
299299
skipping[i] = null;
300300
}
301301
}

0 commit comments

Comments
 (0)