@parcel/graph 3.2.1-canary.3266 → 3.2.1-canary.3269
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Graph.js +2 -92
- package/package.json +3 -3
- package/src/Graph.js +6 -110
- package/test/Graph.test.js +173 -183
package/lib/Graph.js
CHANGED
@@ -7,13 +7,6 @@ exports.default = exports.ALL_EDGE_TYPES = void 0;
|
|
7
7
|
exports.mapVisitor = mapVisitor;
|
8
8
|
var _types = require("./types");
|
9
9
|
var _AdjacencyList = _interopRequireDefault(require("./AdjacencyList"));
|
10
|
-
function _featureFlags() {
|
11
|
-
const data = require("@parcel/feature-flags");
|
12
|
-
_featureFlags = function () {
|
13
|
-
return data;
|
14
|
-
};
|
15
|
-
return data;
|
16
|
-
}
|
17
10
|
var _BitSet = require("./BitSet");
|
18
11
|
function _nullthrows() {
|
19
12
|
const data = _interopRequireDefault(require("nullthrows"));
|
@@ -195,11 +188,7 @@ class Graph {
|
|
195
188
|
if (type === ALL_EDGE_TYPES && enter && (typeof visit === 'function' || !visit.exit)) {
|
196
189
|
return this.dfsFast(enter, startNodeId);
|
197
190
|
} else {
|
198
|
-
return
|
199
|
-
visit,
|
200
|
-
startNodeId,
|
201
|
-
getChildren: nodeId => this.getNodeIdsConnectedFrom(nodeId, type)
|
202
|
-
}) : this.dfs({
|
191
|
+
return this.dfs({
|
203
192
|
visit,
|
204
193
|
startNodeId,
|
205
194
|
getChildren: nodeId => this.getNodeIdsConnectedFrom(nodeId, type)
|
@@ -327,7 +316,7 @@ class Graph {
|
|
327
316
|
*
|
328
317
|
* This replaces `dfs` and will replace `dfsFast`.
|
329
318
|
*/
|
330
|
-
|
319
|
+
dfs({
|
331
320
|
visit,
|
332
321
|
startNodeId,
|
333
322
|
getChildren
|
@@ -425,85 +414,6 @@ class Graph {
|
|
425
414
|
}
|
426
415
|
this._visited = visited;
|
427
416
|
}
|
428
|
-
|
429
|
-
/**
|
430
|
-
* @deprecated Will be replaced by `dfsNew`
|
431
|
-
*/
|
432
|
-
dfs({
|
433
|
-
visit,
|
434
|
-
startNodeId,
|
435
|
-
getChildren
|
436
|
-
}) {
|
437
|
-
let traversalStartNode = (0, _nullthrows().default)(startNodeId ?? this.rootNodeId, 'A start node is required to traverse');
|
438
|
-
this._assertHasNodeId(traversalStartNode);
|
439
|
-
let visited;
|
440
|
-
if (!this._visited || this._visited.capacity < this.nodes.length) {
|
441
|
-
this._visited = new _BitSet.BitSet(this.nodes.length);
|
442
|
-
visited = this._visited;
|
443
|
-
} else {
|
444
|
-
visited = this._visited;
|
445
|
-
visited.clear();
|
446
|
-
}
|
447
|
-
// Take shared instance to avoid re-entrancy issues.
|
448
|
-
this._visited = null;
|
449
|
-
let stopped = false;
|
450
|
-
let skipped = false;
|
451
|
-
let actions = {
|
452
|
-
skipChildren() {
|
453
|
-
skipped = true;
|
454
|
-
},
|
455
|
-
stop() {
|
456
|
-
stopped = true;
|
457
|
-
}
|
458
|
-
};
|
459
|
-
let walk = (nodeId, context) => {
|
460
|
-
if (!this.hasNode(nodeId)) return;
|
461
|
-
visited.add(nodeId);
|
462
|
-
skipped = false;
|
463
|
-
let enter = typeof visit === 'function' ? visit : visit.enter;
|
464
|
-
if (enter) {
|
465
|
-
let newContext = enter(nodeId, context, actions);
|
466
|
-
if (typeof newContext !== 'undefined') {
|
467
|
-
// $FlowFixMe[reassign-const]
|
468
|
-
context = newContext;
|
469
|
-
}
|
470
|
-
}
|
471
|
-
if (skipped) {
|
472
|
-
return;
|
473
|
-
}
|
474
|
-
if (stopped) {
|
475
|
-
return context;
|
476
|
-
}
|
477
|
-
for (let child of getChildren(nodeId)) {
|
478
|
-
if (visited.has(child)) {
|
479
|
-
continue;
|
480
|
-
}
|
481
|
-
visited.add(child);
|
482
|
-
let result = walk(child, context);
|
483
|
-
if (stopped) {
|
484
|
-
return result;
|
485
|
-
}
|
486
|
-
}
|
487
|
-
if (typeof visit !== 'function' && visit.exit &&
|
488
|
-
// Make sure the graph still has the node: it may have been removed between enter and exit
|
489
|
-
this.hasNode(nodeId)) {
|
490
|
-
let newContext = visit.exit(nodeId, context, actions);
|
491
|
-
if (typeof newContext !== 'undefined') {
|
492
|
-
// $FlowFixMe[reassign-const]
|
493
|
-
context = newContext;
|
494
|
-
}
|
495
|
-
}
|
496
|
-
if (skipped) {
|
497
|
-
return;
|
498
|
-
}
|
499
|
-
if (stopped) {
|
500
|
-
return context;
|
501
|
-
}
|
502
|
-
};
|
503
|
-
let result = walk(traversalStartNode);
|
504
|
-
this._visited = visited;
|
505
|
-
return result;
|
506
|
-
}
|
507
417
|
bfs(visit) {
|
508
418
|
let rootNodeId = (0, _nullthrows().default)(this.rootNodeId, 'A root node is required to traverse');
|
509
419
|
let queue = [rootNodeId];
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@parcel/graph",
|
3
|
-
"version": "3.2.1-canary.
|
3
|
+
"version": "3.2.1-canary.3269+9eff0bfeb",
|
4
4
|
"description": "Blazing fast, zero configuration web application bundler",
|
5
5
|
"license": "MIT",
|
6
6
|
"publishConfig": {
|
@@ -20,8 +20,8 @@
|
|
20
20
|
"node": ">= 16.0.0"
|
21
21
|
},
|
22
22
|
"dependencies": {
|
23
|
-
"@parcel/feature-flags": "2.12.1-canary.
|
23
|
+
"@parcel/feature-flags": "2.12.1-canary.3269+9eff0bfeb",
|
24
24
|
"nullthrows": "^1.1.1"
|
25
25
|
},
|
26
|
-
"gitHead": "
|
26
|
+
"gitHead": "9eff0bfeb655845c8ffd86d8acdba9a21bbafc82"
|
27
27
|
}
|
package/src/Graph.js
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
import {fromNodeId} from './types';
|
4
4
|
import AdjacencyList, {type SerializedAdjacencyList} from './AdjacencyList';
|
5
5
|
import type {Edge, NodeId} from './types';
|
6
|
-
import {getFeatureFlag} from '@parcel/feature-flags';
|
7
6
|
import type {
|
8
7
|
TraversalActions,
|
9
8
|
GraphVisitor,
|
@@ -335,17 +334,11 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
335
334
|
) {
|
336
335
|
return this.dfsFast(enter, startNodeId);
|
337
336
|
} else {
|
338
|
-
return
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
})
|
344
|
-
: this.dfs({
|
345
|
-
visit,
|
346
|
-
startNodeId,
|
347
|
-
getChildren: nodeId => this.getNodeIdsConnectedFrom(nodeId, type),
|
348
|
-
});
|
337
|
+
return this.dfs({
|
338
|
+
visit,
|
339
|
+
startNodeId,
|
340
|
+
getChildren: nodeId => this.getNodeIdsConnectedFrom(nodeId, type),
|
341
|
+
});
|
349
342
|
}
|
350
343
|
}
|
351
344
|
|
@@ -506,7 +499,7 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
506
499
|
*
|
507
500
|
* This replaces `dfs` and will replace `dfsFast`.
|
508
501
|
*/
|
509
|
-
|
502
|
+
dfs<TContext>({
|
510
503
|
visit,
|
511
504
|
startNodeId,
|
512
505
|
getChildren,
|
@@ -609,103 +602,6 @@ export default class Graph<TNode, TEdgeType: number = 1> {
|
|
609
602
|
this._visited = visited;
|
610
603
|
}
|
611
604
|
|
612
|
-
/**
|
613
|
-
* @deprecated Will be replaced by `dfsNew`
|
614
|
-
*/
|
615
|
-
dfs<TContext>({
|
616
|
-
visit,
|
617
|
-
startNodeId,
|
618
|
-
getChildren,
|
619
|
-
}: DFSParams<TContext>): ?TContext {
|
620
|
-
let traversalStartNode = nullthrows(
|
621
|
-
startNodeId ?? this.rootNodeId,
|
622
|
-
'A start node is required to traverse',
|
623
|
-
);
|
624
|
-
this._assertHasNodeId(traversalStartNode);
|
625
|
-
|
626
|
-
let visited;
|
627
|
-
if (!this._visited || this._visited.capacity < this.nodes.length) {
|
628
|
-
this._visited = new BitSet(this.nodes.length);
|
629
|
-
visited = this._visited;
|
630
|
-
} else {
|
631
|
-
visited = this._visited;
|
632
|
-
visited.clear();
|
633
|
-
}
|
634
|
-
// Take shared instance to avoid re-entrancy issues.
|
635
|
-
this._visited = null;
|
636
|
-
|
637
|
-
let stopped = false;
|
638
|
-
let skipped = false;
|
639
|
-
let actions: TraversalActions = {
|
640
|
-
skipChildren() {
|
641
|
-
skipped = true;
|
642
|
-
},
|
643
|
-
stop() {
|
644
|
-
stopped = true;
|
645
|
-
},
|
646
|
-
};
|
647
|
-
|
648
|
-
let walk = (nodeId, context: ?TContext) => {
|
649
|
-
if (!this.hasNode(nodeId)) return;
|
650
|
-
visited.add(nodeId);
|
651
|
-
|
652
|
-
skipped = false;
|
653
|
-
let enter = typeof visit === 'function' ? visit : visit.enter;
|
654
|
-
if (enter) {
|
655
|
-
let newContext = enter(nodeId, context, actions);
|
656
|
-
if (typeof newContext !== 'undefined') {
|
657
|
-
// $FlowFixMe[reassign-const]
|
658
|
-
context = newContext;
|
659
|
-
}
|
660
|
-
}
|
661
|
-
|
662
|
-
if (skipped) {
|
663
|
-
return;
|
664
|
-
}
|
665
|
-
|
666
|
-
if (stopped) {
|
667
|
-
return context;
|
668
|
-
}
|
669
|
-
|
670
|
-
for (let child of getChildren(nodeId)) {
|
671
|
-
if (visited.has(child)) {
|
672
|
-
continue;
|
673
|
-
}
|
674
|
-
|
675
|
-
visited.add(child);
|
676
|
-
let result = walk(child, context);
|
677
|
-
if (stopped) {
|
678
|
-
return result;
|
679
|
-
}
|
680
|
-
}
|
681
|
-
|
682
|
-
if (
|
683
|
-
typeof visit !== 'function' &&
|
684
|
-
visit.exit &&
|
685
|
-
// Make sure the graph still has the node: it may have been removed between enter and exit
|
686
|
-
this.hasNode(nodeId)
|
687
|
-
) {
|
688
|
-
let newContext = visit.exit(nodeId, context, actions);
|
689
|
-
if (typeof newContext !== 'undefined') {
|
690
|
-
// $FlowFixMe[reassign-const]
|
691
|
-
context = newContext;
|
692
|
-
}
|
693
|
-
}
|
694
|
-
|
695
|
-
if (skipped) {
|
696
|
-
return;
|
697
|
-
}
|
698
|
-
|
699
|
-
if (stopped) {
|
700
|
-
return context;
|
701
|
-
}
|
702
|
-
};
|
703
|
-
|
704
|
-
let result = walk(traversalStartNode);
|
705
|
-
this._visited = visited;
|
706
|
-
return result;
|
707
|
-
}
|
708
|
-
|
709
605
|
bfs(visit: (nodeId: NodeId) => ?boolean): ?NodeId {
|
710
606
|
let rootNodeId = nullthrows(
|
711
607
|
this.rootNodeId,
|
package/test/Graph.test.js
CHANGED
@@ -4,7 +4,7 @@ import assert from 'assert';
|
|
4
4
|
import sinon from 'sinon';
|
5
5
|
import type {TraversalActions} from '@parcel/types-internal';
|
6
6
|
|
7
|
-
import Graph
|
7
|
+
import Graph from '../src/Graph';
|
8
8
|
import {toNodeId, type NodeId} from '../src/types';
|
9
9
|
|
10
10
|
describe('Graph', () => {
|
@@ -343,38 +343,94 @@ describe('Graph', () => {
|
|
343
343
|
});
|
344
344
|
|
345
345
|
describe('dfs(...)', () => {
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
346
|
+
it(`throws if the graph is empty`, () => {
|
347
|
+
const graph = new Graph();
|
348
|
+
const visit = sinon.stub();
|
349
|
+
const getChildren = sinon.stub();
|
350
|
+
assert.throws(() => {
|
351
|
+
graph.dfs({
|
352
|
+
visit,
|
353
|
+
startNodeId: 0,
|
354
|
+
getChildren,
|
355
|
+
});
|
356
|
+
}, /Does not have node 0/);
|
357
|
+
});
|
358
|
+
|
359
|
+
it(`visits a single node`, () => {
|
360
|
+
const graph = new Graph();
|
361
|
+
graph.addNode('root');
|
362
|
+
const visit = sinon.stub();
|
363
|
+
const getChildren = () => [];
|
364
|
+
graph.dfs({
|
365
|
+
visit,
|
366
|
+
startNodeId: 0,
|
367
|
+
getChildren,
|
368
|
+
});
|
369
|
+
|
370
|
+
assert(visit.calledOnce);
|
371
|
+
});
|
372
|
+
|
373
|
+
it(`visits all connected nodes in DFS order`, () => {
|
374
|
+
const graph = new Graph();
|
375
|
+
graph.addNode('0');
|
376
|
+
graph.addNode('1');
|
377
|
+
graph.addNode('2');
|
378
|
+
graph.addNode('3');
|
379
|
+
graph.addNode('disconnected-1');
|
380
|
+
graph.addNode('disconnected-2');
|
381
|
+
graph.addEdge(0, 1);
|
382
|
+
graph.addEdge(0, 2);
|
383
|
+
graph.addEdge(1, 3);
|
384
|
+
graph.addEdge(2, 3);
|
385
|
+
|
386
|
+
const order = [];
|
387
|
+
const visit = (node: NodeId) => {
|
388
|
+
order.push(node);
|
389
|
+
};
|
390
|
+
const getChildren = (node: NodeId) => graph.getNodeIdsConnectedFrom(node);
|
391
|
+
graph.dfs({
|
392
|
+
visit,
|
393
|
+
startNodeId: 0,
|
394
|
+
getChildren,
|
361
395
|
});
|
362
396
|
|
363
|
-
|
397
|
+
assert.deepEqual(order, [0, 1, 3, 2]);
|
398
|
+
});
|
399
|
+
|
400
|
+
describe(`actions tests`, () => {
|
401
|
+
it(`skips children if skip is called on a node`, () => {
|
364
402
|
const graph = new Graph();
|
365
|
-
graph.addNode('
|
366
|
-
|
367
|
-
|
368
|
-
|
403
|
+
graph.addNode('0');
|
404
|
+
graph.addNode('1');
|
405
|
+
graph.addNode('2');
|
406
|
+
graph.addNode('3');
|
407
|
+
graph.addNode('disconnected-1');
|
408
|
+
graph.addNode('disconnected-2');
|
409
|
+
graph.addEdge(0, 1);
|
410
|
+
graph.addEdge(1, 2);
|
411
|
+
graph.addEdge(0, 3);
|
412
|
+
|
413
|
+
const order = [];
|
414
|
+
const visit = (
|
415
|
+
node: NodeId,
|
416
|
+
context: mixed | null,
|
417
|
+
actions: TraversalActions,
|
418
|
+
) => {
|
419
|
+
if (node === 1) actions.skipChildren();
|
420
|
+
order.push(node);
|
421
|
+
};
|
422
|
+
const getChildren = (node: NodeId) =>
|
423
|
+
graph.getNodeIdsConnectedFrom(node);
|
424
|
+
graph.dfs({
|
369
425
|
visit,
|
370
426
|
startNodeId: 0,
|
371
427
|
getChildren,
|
372
428
|
});
|
373
429
|
|
374
|
-
assert(
|
430
|
+
assert.deepEqual(order, [0, 1, 3]);
|
375
431
|
});
|
376
432
|
|
377
|
-
it(
|
433
|
+
it(`stops the traversal if stop is called`, () => {
|
378
434
|
const graph = new Graph();
|
379
435
|
graph.addNode('0');
|
380
436
|
graph.addNode('1');
|
@@ -383,187 +439,121 @@ describe('Graph', () => {
|
|
383
439
|
graph.addNode('disconnected-1');
|
384
440
|
graph.addNode('disconnected-2');
|
385
441
|
graph.addEdge(0, 1);
|
386
|
-
graph.addEdge(
|
442
|
+
graph.addEdge(1, 2);
|
387
443
|
graph.addEdge(1, 3);
|
444
|
+
graph.addEdge(0, 2);
|
388
445
|
graph.addEdge(2, 3);
|
389
446
|
|
390
447
|
const order = [];
|
391
|
-
const visit = (
|
448
|
+
const visit = (
|
449
|
+
node: NodeId,
|
450
|
+
context: mixed | null,
|
451
|
+
actions: TraversalActions,
|
452
|
+
) => {
|
392
453
|
order.push(node);
|
454
|
+
if (node === 1) {
|
455
|
+
actions.stop();
|
456
|
+
return 'result';
|
457
|
+
}
|
458
|
+
return 'other';
|
393
459
|
};
|
394
460
|
const getChildren = (node: NodeId) =>
|
395
461
|
graph.getNodeIdsConnectedFrom(node);
|
396
|
-
|
462
|
+
const result = graph.dfs({
|
397
463
|
visit,
|
398
464
|
startNodeId: 0,
|
399
465
|
getChildren,
|
400
466
|
});
|
401
467
|
|
402
|
-
assert.deepEqual(order, [0, 1
|
468
|
+
assert.deepEqual(order, [0, 1]);
|
469
|
+
assert.equal(result, 'result');
|
403
470
|
});
|
471
|
+
});
|
404
472
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
const visit = (
|
420
|
-
node: NodeId,
|
421
|
-
context: mixed | null,
|
422
|
-
actions: TraversalActions,
|
423
|
-
) => {
|
424
|
-
if (node === 1) actions.skipChildren();
|
425
|
-
order.push(node);
|
426
|
-
};
|
427
|
-
const getChildren = (node: NodeId) =>
|
428
|
-
graph.getNodeIdsConnectedFrom(node);
|
429
|
-
dfsImpl(graph, {
|
430
|
-
visit,
|
431
|
-
startNodeId: 0,
|
432
|
-
getChildren,
|
433
|
-
});
|
434
|
-
|
435
|
-
assert.deepEqual(order, [0, 1, 3]);
|
436
|
-
});
|
473
|
+
describe(`context tests`, () => {
|
474
|
+
it(`passes the context between visitors`, () => {
|
475
|
+
const graph = new Graph();
|
476
|
+
graph.addNode('0');
|
477
|
+
graph.addNode('1');
|
478
|
+
graph.addNode('2');
|
479
|
+
graph.addNode('3');
|
480
|
+
graph.addNode('disconnected-1');
|
481
|
+
graph.addNode('disconnected-2');
|
482
|
+
graph.addEdge(0, 1);
|
483
|
+
graph.addEdge(1, 2);
|
484
|
+
graph.addEdge(1, 3);
|
485
|
+
graph.addEdge(0, 2);
|
486
|
+
graph.addEdge(2, 3);
|
437
487
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
graph.
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
graph.addEdge(0, 2);
|
450
|
-
graph.addEdge(2, 3);
|
451
|
-
|
452
|
-
const order = [];
|
453
|
-
const visit = (
|
454
|
-
node: NodeId,
|
455
|
-
context: mixed | null,
|
456
|
-
actions: TraversalActions,
|
457
|
-
) => {
|
458
|
-
order.push(node);
|
459
|
-
if (node === 1) {
|
460
|
-
actions.stop();
|
461
|
-
return 'result';
|
462
|
-
}
|
463
|
-
return 'other';
|
464
|
-
};
|
465
|
-
const getChildren = (node: NodeId) =>
|
466
|
-
graph.getNodeIdsConnectedFrom(node);
|
467
|
-
const result = dfsImpl(graph, {
|
468
|
-
visit,
|
469
|
-
startNodeId: 0,
|
470
|
-
getChildren,
|
471
|
-
});
|
472
|
-
|
473
|
-
assert.deepEqual(order, [0, 1]);
|
474
|
-
assert.equal(result, 'result');
|
488
|
+
const contexts = [];
|
489
|
+
const visit = (node: NodeId, context: mixed | null) => {
|
490
|
+
contexts.push([node, context]);
|
491
|
+
return `node-${node}-created-context`;
|
492
|
+
};
|
493
|
+
const getChildren = (node: NodeId) =>
|
494
|
+
graph.getNodeIdsConnectedFrom(node);
|
495
|
+
const result = graph.dfs({
|
496
|
+
visit,
|
497
|
+
startNodeId: 0,
|
498
|
+
getChildren,
|
475
499
|
});
|
476
|
-
});
|
477
500
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
graph.addNode('disconnected-1');
|
486
|
-
graph.addNode('disconnected-2');
|
487
|
-
graph.addEdge(0, 1);
|
488
|
-
graph.addEdge(1, 2);
|
489
|
-
graph.addEdge(1, 3);
|
490
|
-
graph.addEdge(0, 2);
|
491
|
-
graph.addEdge(2, 3);
|
492
|
-
|
493
|
-
const contexts = [];
|
494
|
-
const visit = (node: NodeId, context: mixed | null) => {
|
495
|
-
contexts.push([node, context]);
|
496
|
-
return `node-${node}-created-context`;
|
497
|
-
};
|
498
|
-
const getChildren = (node: NodeId) =>
|
499
|
-
graph.getNodeIdsConnectedFrom(node);
|
500
|
-
const result = dfsImpl(graph, {
|
501
|
-
visit,
|
502
|
-
startNodeId: 0,
|
503
|
-
getChildren,
|
504
|
-
});
|
505
|
-
|
506
|
-
assert.deepEqual(contexts, [
|
507
|
-
[0, undefined],
|
508
|
-
[1, 'node-0-created-context'],
|
509
|
-
[2, 'node-1-created-context'],
|
510
|
-
[3, 'node-2-created-context'],
|
511
|
-
]);
|
512
|
-
assert.equal(result, undefined);
|
513
|
-
});
|
501
|
+
assert.deepEqual(contexts, [
|
502
|
+
[0, undefined],
|
503
|
+
[1, 'node-0-created-context'],
|
504
|
+
[2, 'node-1-created-context'],
|
505
|
+
[3, 'node-2-created-context'],
|
506
|
+
]);
|
507
|
+
assert.equal(result, undefined);
|
514
508
|
});
|
509
|
+
});
|
515
510
|
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
const contexts = [];
|
531
|
-
const visit = (node: NodeId, context: mixed | null) => {
|
532
|
-
contexts.push([node, context]);
|
533
|
-
return `node-${node}-created-context`;
|
534
|
-
};
|
535
|
-
const visitExit = (node: NodeId, context: mixed | null) => {
|
536
|
-
contexts.push(['exit', node, context]);
|
537
|
-
return `node-exit-${node}-created-context`;
|
538
|
-
};
|
539
|
-
const getChildren = (node: NodeId) =>
|
540
|
-
graph.getNodeIdsConnectedFrom(node);
|
541
|
-
const result = dfsImpl(graph, {
|
542
|
-
visit: {
|
543
|
-
enter: visit,
|
544
|
-
exit: visitExit,
|
545
|
-
},
|
546
|
-
startNodeId: 0,
|
547
|
-
getChildren,
|
548
|
-
});
|
549
|
-
|
550
|
-
assert.deepEqual(contexts, [
|
551
|
-
[0, undefined],
|
552
|
-
[1, 'node-0-created-context'],
|
553
|
-
[2, 'node-1-created-context'],
|
554
|
-
['exit', 2, 'node-2-created-context'],
|
555
|
-
[3, 'node-1-created-context'],
|
556
|
-
['exit', 3, 'node-3-created-context'],
|
557
|
-
['exit', 1, 'node-1-created-context'],
|
558
|
-
['exit', 0, 'node-0-created-context'],
|
559
|
-
]);
|
560
|
-
assert.equal(result, undefined);
|
561
|
-
});
|
562
|
-
});
|
563
|
-
}
|
511
|
+
describe(`exit visitor tests`, () => {
|
512
|
+
it(`calls the exit visitor`, () => {
|
513
|
+
const graph = new Graph();
|
514
|
+
graph.addNode('0');
|
515
|
+
graph.addNode('1');
|
516
|
+
graph.addNode('2');
|
517
|
+
graph.addNode('3');
|
518
|
+
graph.addNode('disconnected-1');
|
519
|
+
graph.addNode('disconnected-2');
|
520
|
+
graph.addEdge(0, 1);
|
521
|
+
graph.addEdge(1, 2);
|
522
|
+
graph.addEdge(1, 3);
|
523
|
+
graph.addEdge(0, 2);
|
564
524
|
|
565
|
-
|
525
|
+
const contexts = [];
|
526
|
+
const visit = (node: NodeId, context: mixed | null) => {
|
527
|
+
contexts.push([node, context]);
|
528
|
+
return `node-${node}-created-context`;
|
529
|
+
};
|
530
|
+
const visitExit = (node: NodeId, context: mixed | null) => {
|
531
|
+
contexts.push(['exit', node, context]);
|
532
|
+
return `node-exit-${node}-created-context`;
|
533
|
+
};
|
534
|
+
const getChildren = (node: NodeId) =>
|
535
|
+
graph.getNodeIdsConnectedFrom(node);
|
536
|
+
const result = graph.dfs({
|
537
|
+
visit: {
|
538
|
+
enter: visit,
|
539
|
+
exit: visitExit,
|
540
|
+
},
|
541
|
+
startNodeId: 0,
|
542
|
+
getChildren,
|
543
|
+
});
|
566
544
|
|
567
|
-
|
545
|
+
assert.deepEqual(contexts, [
|
546
|
+
[0, undefined],
|
547
|
+
[1, 'node-0-created-context'],
|
548
|
+
[2, 'node-1-created-context'],
|
549
|
+
['exit', 2, 'node-2-created-context'],
|
550
|
+
[3, 'node-1-created-context'],
|
551
|
+
['exit', 3, 'node-3-created-context'],
|
552
|
+
['exit', 1, 'node-1-created-context'],
|
553
|
+
['exit', 0, 'node-0-created-context'],
|
554
|
+
]);
|
555
|
+
assert.equal(result, undefined);
|
556
|
+
});
|
557
|
+
});
|
568
558
|
});
|
569
559
|
});
|