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 }