@@ -4,6 +4,11 @@ import spock.lang.Specification
44
55class TraverserTest extends Specification {
66
7+ /**
8+ * 0
9+ * 1 2
10+ * 3 4 5
11+ */
712 def root = [
813 [number : 0 , children : [
914 [number : 1 , children : [
@@ -16,60 +21,153 @@ class TraverserTest extends Specification {
1621 ]
1722 ]
1823
19- def " test pre-order depth-first traversal" () {
24+ def " test depth-first traversal" () {
2025 given :
21- def initialData = []
26+ def preOrderNodes = []
27+ def postOrderNodes = []
2228 def visitor = [
2329 enter : { TraverserContext context ->
24- context. getInitialData() . add(context . thisNode(). number)
30+ preOrderNodes << context. thisNode(). number
2531 TraversalControl . CONTINUE
2632 },
27- leave : { TraversalControl . CONTINUE }
33+ leave : { TraverserContext context ->
34+ postOrderNodes << context. thisNode(). number
35+ TraversalControl . CONTINUE
36+ }
2837 ] as TraverserVisitor
2938 when :
30- Traverser . depthFirst({ n -> n. children }, initialData ). traverse(root, visitor)
39+ Traverser . depthFirst({ n -> n. children }). traverse(root, visitor)
3140
3241
3342 then :
34- initialData == [0 , 1 , 3 , 2 , 4 , 5 ]
43+ preOrderNodes == [0 , 1 , 3 , 2 , 4 , 5 ]
44+ postOrderNodes == [3 , 1 , 4 , 5 , 2 , 0 ]
3545 }
3646
37- def " test post-order depth-first traversal" () {
47+
48+ def " test breadth-first traversal" () {
3849 given :
39- def initialData = new ArrayList ();
50+ def enterData = []
51+ def leaveData = []
4052 def visitor = [
4153 enter : { TraverserContext context ->
54+ enterData << context. thisNode(). number
55+ println " enter:$enterData "
4256 TraversalControl . CONTINUE
4357 },
4458 leave : { TraverserContext context ->
45- context. getInitialData(). add(context. thisNode(). number)
59+ leaveData << context. thisNode(). number
60+ println " leave:$leaveData "
4661 TraversalControl . CONTINUE
4762 }
4863 ] as TraverserVisitor
4964 when :
65+ Traverser . breadthFirst({ n -> n. children }). traverse(root, visitor)
66+
67+ then :
68+ enterData == [0 , 1 , 2 , 3 , 4 , 5 ]
69+ leaveData == [0 , 1 , 2 , 3 , 4 , 5 ]
70+ }
71+
72+ def " quit traversal immediately" () {
73+ given :
74+ def initialData = new ArrayList ()
75+
76+ def visitor = [
77+ enter : { TraverserContext context ->
78+ context. getInitialData(). add(context. thisNode(). number)
79+ TraversalControl . QUIT
80+ }
81+ ] as TraverserVisitor
82+
83+ when :
84+ Traverser . breadthFirst({ n -> n. children }, initialData). traverse(root, visitor)
85+
86+ then :
87+ initialData == [0 ]
88+
89+
90+ when :
91+ initialData. clear()
5092 Traverser . depthFirst({ n -> n. children }, initialData). traverse(root, visitor)
5193
5294 then :
53- initialData == [3 , 1 , 4 , 5 , 2 , 0 ]
95+ initialData == [0 ]
96+
5497 }
5598
56- def " test breadth-first traversal" () {
99+ def " quit traversal in first leave" () {
100+ given :
101+ def initialData = new ArrayList ()
102+ def leaveCount = 0
103+
104+ def visitor = [
105+ enter : { TraverserContext context ->
106+ context. getInitialData(). add(context. thisNode(). number)
107+ TraversalControl . CONTINUE
108+ },
109+ leave : { TraverserContext context ->
110+ leaveCount++
111+ TraversalControl . QUIT
112+ },
113+
114+ ] as TraverserVisitor
115+
116+ when :
117+ Traverser . depthFirst({ n -> n. children }, initialData). traverse(root, visitor)
118+
119+ then :
120+ initialData == [0 , 1 , 3 ]
121+ leaveCount == 1
122+
123+ }
124+
125+ def " abort subtree traversal depth-first" () {
57126 given :
58127 def initialData = new ArrayList ()
128+
59129 def visitor = [
60130 enter : { TraverserContext context ->
61131 context. getInitialData(). add(context. thisNode(). number)
132+ if ([1 , 2 ]. contains(context. thisNode(). number)) return TraversalControl . ABORT
62133 TraversalControl . CONTINUE
63134 },
64- leave : {
135+ leave : { TraverserContext context ->
65136 TraversalControl . CONTINUE
66- }
137+ },
138+
67139 ] as TraverserVisitor
140+
141+ when :
142+ Traverser . depthFirst({ n -> n. children }, initialData). traverse(root, visitor)
143+
144+ then :
145+ initialData == [0 , 1 , 2 ]
146+
147+ }
148+
149+ def " abort subtree traversal breadth-first" () {
150+ given :
151+ def initialData = new ArrayList ()
152+
153+ def visitor = [
154+ enter : { TraverserContext context ->
155+ context. getInitialData(). add(context. thisNode(). number)
156+ if ([2 ]. contains(context. thisNode(). number)) return TraversalControl . ABORT
157+ TraversalControl . CONTINUE
158+ },
159+ leave : { TraverserContext context ->
160+ TraversalControl . CONTINUE
161+ },
162+
163+ ] as TraverserVisitor
164+
68165 when :
69166 Traverser . breadthFirst({ n -> n. children }, initialData). traverse(root, visitor)
70167
71168 then :
72- initialData == [0 , 1 , 2 , 3 , 4 , 5 ]
169+ initialData == [0 , 1 , 2 , 3 ]
170+
73171 }
74172
75173}
0 commit comments