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 }