1 module test2;
2 
3 import std.algorithm : equal;
4 import std.stdio;
5 
6 import auxil.model;
7 
8 import test_data;
9 
10 struct Positioner
11 {
12 	string indentation;
13 
14 	void nextLine()
15 	{
16 		write("\n", indentation);
17 	}
18 
19 	void put(Args...)(Args args)
20 	{
21 		write(indentation, args);
22 	}
23 
24 	void indent()
25 	{
26 		indentation ~= "  ";
27 	}
28 
29 	void unindent()
30 	{
31 		if (indentation.length)
32 			indentation = indentation[0..$-2];
33 	}
34 }
35 
36 struct MyVisitor
37 {
38 	import auxil.model : TreePath;
39 
40 	enum treePathNGEnabled = true;
41 	enum treePathEnabled = false;
42 	enum sizeEnabled = false;
43 
44 	enum State { seeking, first, rest, finishing, }
45 	State state;
46 	TreePath tree_path;
47 	Positioner p;
48 
49 	TreePath[] log;
50 
51 	TreePath path;
52 	private bool _complete;
53 
54 	bool complete() @trusted @nogc
55 	{
56 		return _complete;
57 	}
58 
59 	void enterTree(alias order, Data, Model)(auto ref const(Data) data, ref Model model)
60 	{
61 		p.put("Enter Tree: ", Data.stringof);
62 		p.nextLine;
63 	}
64 
65 	auto enterNode(alias order, Data, Model)(ref const(Data) data, ref Model model)
66 	{
67 		log ~= tree_path;
68 		p.put("Enter Node: ", Data.stringof, " ", tree_path);
69 		p.indent;
70 		p.nextLine;
71 		{
72 			_complete = !path.value.empty && tree_path.value[] == path.value[];
73 		}
74 
75 		return false;
76 	}
77 
78 	void leaveNode(alias order, Data, Model)(ref const(Data) data, ref Model model)
79 	{
80 		p.put("Leave Node: ", Data.stringof);
81 		p.unindent;
82 		p.nextLine;
83 	}
84 
85 	void processLeaf(alias order, Data, Model)(ref const(Data) data, ref Model model)
86 	{
87 
88 		log ~= tree_path;
89 		p.put("Process Leaf: ", Data.stringof, " ", data, " ", tree_path);
90 		p.nextLine;
91 		{
92 			_complete = !path.value.empty && tree_path.value[] == path.value[];
93 		}
94 	}
95 }
96 
97 // The tree of one node containing leaves only
98 void testTree1()
99 {
100 	auto model = makeModel(m.a.b);
101 	
102 	MyVisitor visitor;
103 	model.visitForward(m.a.b, visitor);
104 	writeln("\n---");
105 	writeln(visitor.log);
106 	assert(visitor.log.equal([
107 		[],  // B
108 		[0], // B.i
109 		[1], // B.f
110 	]));
111 }
112 
113 // The tree of one node containing single node that contains leaves only
114 void testTree2()
115 {
116 	auto model = makeModel(m.a);
117 	
118 	MyVisitor visitor;
119 	model.visitForward(m.a, visitor);
120 	writeln("\n---");
121 	writeln(visitor.log);
122 	// as A contains only single member 
123 	// N.B. in previous edition this member B was substituted
124 	// instead of A (like A didn't exist)
125 	assert(visitor.log.equal([
126 		[],     // a
127 		[0],    // b
128 		[0, 0], // b.i
129 		[0, 1], // b.f
130 	]));
131 }
132 
133 // The tree of one node containing several node(s)/list(s)
134 void testTree3()
135 {
136 	auto model = makeModel(m.a2);
137 	
138 	MyVisitor visitor;
139 	model.visitForward(m.a2, visitor);
140 	writeln("\n---");
141 	writeln(visitor.log);
142 	assert(visitor.log.equal([
143 		[],     // a2
144 		[0],    // a2.d
145 		[1],    // a2.b
146 		[1, 0], // a2.b.i
147 		[1, 1], // a2.b.f
148 	]));
149 }
150 
151 // traversal in back direction
152 void testTree4()
153 {
154 	auto model = makeModel(m.a2);
155 	
156 	MyVisitor visitor;
157 	model.visitBackward(m.a2, visitor);
158 	writeln("\n---");
159 	writeln(visitor.log);
160 	assert(visitor.log.equal([
161 		[],     // a2
162 		[1],    // a2.b
163 		[1, 1], // a2.b.f
164 		[1, 0], // a2.b.i
165 		[0],    // a2.d
166 	]));
167 }
168 
169 // traversal to the specific tree path in forward direction
170 void testTree5()
171 {
172 	auto model = makeModel(m.a2);
173 	
174 	MyVisitor visitor;
175 	visitor.path.value = [1, 0];
176 	model.visitForward(m.a2, visitor);
177 	writeln("\n---");
178 	writeln(visitor.log);
179 	assert(visitor.log.equal([
180 		[],     // a2
181 				// a2.d skipped
182 		[1],    // a2.b
183 		[1, 0], // a2.b.i
184 	]));
185 }
186 
187 // traversal to the specific tree path in backward direction
188 void testTree6()
189 {
190 	auto model = makeModel(m.a2);
191 	
192 	MyVisitor visitor;
193 	visitor.path.value = [1, 0];
194 	model.visitBackward(m.a2, visitor);
195 	writeln("\n---");
196 	writeln(visitor.log);
197 	assert(visitor.log.equal([
198 		[],     // a2
199 		[1],    // a2.b
200 				// a2.b.f skipped
201 		[1, 0], // a2.b.i
202 	]));
203 }