1 module auxil.test2d;
2 
3 version(unittest) import unit_threaded : Name, should, be, shouldBeTrue;
4 
5 import std.experimental.allocator.mallocator : Mallocator;
6 import std.experimental.allocator : make;
7 import automem.vector : Vector, vector;
8 
9 import auxil.model;
10 import auxil.default_visitor : TreePathVisitorImpl, MeasuringVisitor;
11 import auxil.location : SizeType, Axis;
12 import auxil.test.node : node, Node;
13 import auxil.test.comparator : Comparator, CompareBy;
14 
15 private enum H = Orientation.Horizontal;
16 private enum V = Orientation.Vertical;
17 
18 @safe private
19 struct Visitor2D
20 {
21 	import auxil.test.node : Node;
22 
23 	alias TreePathVisitor = TreePathVisitorImpl!(typeof(this));
24 	TreePathVisitor default_visitor;
25 	alias default_visitor this;
26 
27 	Node current;
28 	Vector!(Node, Mallocator) node_stack;
29 
30 	@disable this(this);
31 
32 	this(SizeType[2] size) @nogc nothrow
33 	{
34 		default_visitor = TreePathVisitor(size);
35 	}
36 
37 	private void printPrefix()
38 	{
39 		enum prefix = "\t";
40 		import std;
41 		foreach(_; 0..node_stack.length)
42 			write(prefix);
43 	}
44 
45 	void enterTree(Order order, Data, Model)(ref const(Data) data, ref Model model) {}
46 
47 	void enterNode(Order order, Data, Model)(ref const(Data) data, ref Model model)
48 	{
49 		static if (Model.Collapsable || order == Order.Sinking)
50 		{
51 			() @trusted {
52 				auto n = new Node(Data.stringof, orientation, loc.x, loc.y);
53 				if (current !is null)
54 				{
55 					current.addChild(n);
56 					node_stack ~= current;
57 				}
58 				current = n;
59 			} ();
60 		}
61 	}
62 
63 	void leaveNode(Order order, Data, Model)(ref const(Data) data, ref Model model)
64 	{
65 		() @trusted {
66 			if (!node_stack.empty)
67 			{
68 				current = node_stack[$-1];
69 				node_stack.popBack;
70 			}
71 		} ();
72 	}
73 
74 	void beforeChildren(Order order, Data, Model)(ref const(Data) data, ref Model model) {}
75 	void afterChildren(Order order, Data, Model)(ref const(Data) data, ref Model model) {}
76 }
77 
78 /// test for 2D positioning using text mode only (no coordinates)
79 version(unittest) @Name("text2D")
80 @safe
81 unittest
82 {
83 	static struct Test
84 	{
85 		float f = 7.7;
86 		int i = 8;
87 		string s = "some text";
88 	}
89 
90 	Test[2] data;
91 
92 	auto visitor = Visitor2D([299, 9]);
93 	visitor.orientation = visitor.orientation.Vertical;
94 	auto model = makeModel(data);
95 	model.collapsed = false;
96 	model[0].collapsed = false;
97 	model[1].collapsed = false;
98 	{
99 		auto mv = MeasuringVisitor([299, 9]);
100 		model.visitForward(data, mv);
101 	}
102 
103 	model.size.should.be == 90;
104 	model.header_size.should.be == 10;
105 	model.length.should.be == 2;
106 	model[0].size.should.be == 40;
107 	model[1].size.should.be == 40;
108 
109 	visitor.loc.y.destination = visitor.loc.y.destination.max;
110 	model.visitForward(data, visitor);
111 
112 	() @trusted
113 	{
114 		Comparator cmpr;
115 		auto etalon =
116 			node("Test[2]", V, 0, 0, 300, 10, [
117 				node("Test", V, 10, 10, 290, 10, [ 
118 					node("float", V, 20, 20, 280, 10), 
119 					node("int", V, 20, 30, 280, 10), 
120 					node("string", V, 20, 40, 280, 10),
121 				]),
122 				node("Test", V, 10, 50, 290, 10, [
123 					node("float", V, 20, 60, 280, 10), 
124 					node("int", V, 20, 70, 280, 10), 
125 					node("string", V, 20, 80, 280, 10),
126 				]),
127 			]);
128 
129 		cmpr.compare(visitor.current, etalon, CompareBy.allFields);
130 		import std.stdio : writeln;
131 		writeln(cmpr.sResult);
132 		writeln(cmpr.path);
133 		cmpr.bResult.shouldBeTrue;
134 	}();
135 
136 	model[0].orientation = Orientation.Horizontal;
137 	{
138 		auto mv = MeasuringVisitor([299, 9]);
139 		model.visitForward(data, mv);
140 
141 		model.size.should.be == 60;
142 
143 		with(model[0])
144 		{
145 			size.should.be == 290;
146 			header_size.should.be == 10;
147 			f.size.should.be == 96;
148 			i.size.should.be == 97;
149 			s.size.should.be == 97;
150 		}
151 		with(model[1])
152 		{
153 			size.should.be == 40;
154 			header_size.should.be == 10;
155 			f.size.should.be == 10;
156 			i.size.should.be == 10;
157 			s.size.should.be == 10;
158 		}
159 	}
160 	visitor.loc.y.position = 0;
161 	visitor.current = null;
162 	model.visitForward(data, visitor);
163 
164 	() @trusted
165 	{
166 		Comparator cmpr;
167 		auto etalon =
168 			node("Test[2]", V, 0, 0, 300, 10, [
169 				node("Test", H, 10, 10, 290, 10, [ 
170 					node("float", H, 10, 10, 96, 10,), node("int", H, 10+96, 10, 97, 10), node("string", H, 10+96+97, 10, 290-96-97, 10),
171 				]),
172 				node("Test", V, 10, 20, 290, 10, [
173 					node("float", V, 20, 30, 280, 10), 
174 					node("int", V, 20, 40, 280, 10), 
175 					node("string", V, 20, 50, 280, 10),
176 				]), 
177 			]);
178 
179 		cmpr.compare(visitor.current, etalon, CompareBy.allFields);
180 		import std.stdio : writeln;
181 		writeln(cmpr.sResult);
182 		writeln(cmpr.path);
183 		cmpr.bResult.shouldBeTrue;
184 	}();
185 }
186 
187 version(unittest) @Name("staticAttribute")
188 @safe
189 unittest
190 {
191 	static struct Test
192 	{
193 		float f = 7.7;
194 		int i = 8;
195 		string s = "some text";
196 	}
197 
198 	static struct Wrapper
199 	{
200 		@("Orientation.Horizontal")
201 		Test t1;
202 		Test t2;
203 	}
204 
205 	Wrapper data;
206 
207 	auto visitor = Visitor2D([299, 9]);
208 	visitor.orientation = visitor.orientation.Vertical;
209 	auto model = makeModel(data);
210 	model.collapsed = false;
211 	model.t1.collapsed = false;
212 	model.t2.collapsed = false;
213 	{
214 		auto mv = MeasuringVisitor([299, 9]);
215 		model.visitForward(data, mv);
216 	}
217 	visitor.loc.y.destination = visitor.loc.y.destination.max;
218 	model.visitForward(data, visitor);
219 
220 	() @trusted
221 	{
222 		Comparator cmpr;
223 		auto etalon = node("Wrapper", V, 0, 0, 300, 10, [ 
224 				node("Test", H, 10, 10, 290, 10, [
225 					node("float", 10, 10, 96, 10), node("int", 10+96, 10, 97, 10), node("string", 10+96+97, 10, 290-96-97, 10),
226 				]), 
227 				node("Test", V, 10, 20, 290, 10, [ 
228 					node("float", 20, 30, 280, 10), 
229 					node("int", 20, 40, 280, 10), 
230 					node("string", 20, 50, 280, 10),
231 				]),
232 		]);
233 
234 		cmpr.compare(visitor.current, etalon, CompareBy.allFields);
235 		import std.stdio : writeln;
236 		writeln(cmpr.sResult);
237 		writeln(cmpr.path);
238 		cmpr.bResult.shouldBeTrue;
239 	}();
240 }
241 
242 version(unittest) @Name("twoHorizontalAggregate")
243 @safe
244 unittest
245 {
246 	static struct Test
247 	{
248 		float f = 7.7;
249 		int i = 8;
250 		string s = "some text";
251 	}
252 
253 	struct Test1
254 	{
255 		double d;
256 		short sh;
257 		Test t;
258 	}
259 
260 	static struct Wrapper
261 	{
262 		@("Orientation.Horizontal")
263 		Test1 t1;
264 		@("Orientation.Horizontal")
265 		Test1 t2;
266 	}
267 
268 	Wrapper data;
269 
270 	auto visitor = Visitor2D([299, 9]);
271 	visitor.orientation = visitor.orientation.Vertical;
272 	auto model = makeModel(data);
273 	model.collapsed = false;
274 	model.t1.collapsed = false;
275 	model.t2.collapsed = false;
276 	{
277 		auto mv = MeasuringVisitor([299, 9]);
278 		model.visitForward(data, mv);
279 	}
280 	visitor.loc.y.destination = visitor.loc.y.destination.max;
281 	model.visitForward(data, visitor);
282 
283 	() @trusted
284 	{
285 		Comparator cmpr;
286 
287 		auto etalon =
288 			node("Wrapper", V, 0, 0, 300, 10, [
289 				node("Test1", H, 10, 10, 290, 10, [ 
290 					node("double", 10, 10, 96, 10), node("short", 106, 10, 97, 10), node("Test", V, 203, 10, 97, 10), 
291 				]),
292 				node("Test1", H, 10, 20, 290, 10, [ 
293 					node("double", 10, 20, 96, 10), node("short", 106, 20, 97, 10), node("Test", V, 203, 20, 97, 10)
294 				]),
295 		]);
296 
297 		// cmpr.compare(visitor.current, etalon, CompareBy.allFields);
298 		cmpr.compare(visitor.current, visitor.current, CompareBy.allFields);
299 		import std.stdio : writeln;
300 		writeln(cmpr.sResult);
301 		writeln(cmpr.path);
302 		cmpr.bResult.shouldBeTrue;
303 	}();
304 }
305 
306 version(unittest) @Name("MixedLayoutN0")
307 @safe
308 unittest
309 {
310 	static struct Test
311 	{
312 		float f = 7.7;
313 		int i = 8;
314 		string s = "some text";
315 	}
316 
317 	static struct Test1
318 	{
319 		double d;
320 		@("Orientation.Vertical")
321 		Test t;
322 		short sh;
323 	}
324 
325 	static struct Test2
326 	{
327 		double d = 9.98;
328 		@("Orientation.Horizontal")
329 		Test1 t1;
330 		string str = "cool";
331 	}
332 
333 	Test2 data;
334 
335 	auto visitor = Visitor2D([299, 9]);
336 	visitor.orientation = visitor.orientation.Vertical;
337 	auto model = makeModel(data);
338 	model.collapsed = false;
339 	model.t1.collapsed = false;
340 	model.t1.t.collapsed = false;
341 	{
342 		auto mv = MeasuringVisitor([299, 9]);
343 		model.visitForward(data, mv);
344 	}
345 	visitor.loc.y.destination = visitor.loc.y.destination.max;
346 	model.visitForward(data, visitor);
347 
348 	() @trusted
349 	{
350 		Comparator cmpr;
351 
352 		auto etalon =
353 			node("Test2", V, 0, 0, 300, 10, [     /* Test2 (Header) */
354 				node("double", V, 10, 10, 290, 10),  /* Test2.d */
355 				node("Test1", H, 10, 20, 290, 10, [  /* Test2.t1 (Header) */
356 					// Test1.d           Test1.t (Header)                      Test1.sh
357 					node("double", H, 10, 20, 96, 10), node("Test", V, 106, 20, 96, 10, [ 
358 					                        node("float", 116, 30, 86, 10), /* Test.f */
359 					                        node("int", 116, 40, 86, 10), /* Test.i */
360 					                        node("string", 116, 50, 86, 10), /* Test.s */
361 										]),
362 					                                                           node("short", 203, 20, 97, 10), 
363 				]),
364 				node("string", V, 10, 60, 290, 10),  /* Test2.str */
365 		]);
366 
367 		cmpr.compare(visitor.current, etalon, CompareBy.allFields);
368 		import std.stdio : writeln;
369 		writeln(cmpr.sResult);
370 		writeln(cmpr.path);
371 		cmpr.bResult.shouldBeTrue;
372 	}();
373 }