1 module auxil.test2; 2 3 version(unittest) 4 import unit_threaded : should, be, Name; 5 import taggedalgebraic : TaggedAlgebraic; 6 7 import auxil.model; 8 import auxil.test; 9 10 struct Test 11 { 12 ushort us; 13 long l; 14 } 15 16 struct Test2 17 { 18 size_t st; 19 string s; 20 Test t; 21 float[] fa; 22 } 23 24 union Payload 25 { 26 int i; 27 float f; 28 double d; 29 string str; 30 Test t; 31 Test2 t2; 32 } 33 34 alias Data = TaggedAlgebraic!Payload; 35 36 Data[] data; 37 RelativeMeasurer v; 38 typeof(makeModel(data)) model; 39 40 void setup() 41 { 42 data = [ 43 Data(1), 44 Data(2.0), 45 Data(3.0f), 46 Data(Test(100, -1001)), 47 Data(Test2(1_000_000, "test2", Test(200, -11), [11, 12, 123])), 48 Data("text"), 49 ]; 50 51 v = RelativeMeasurer(); 52 model = makeModel(data); 53 model.collapsed = false; 54 setPropertyByTreePath!"collapsed"(data, model, [3], false); 55 setPropertyByTreePath!"collapsed"(data, model, [4], false); 56 setPropertyByTreePath!"collapsed"(data, model, [4, 2], false); 57 setPropertyByTreePath!"collapsed"(data, model, [4, 3], false); 58 59 // measure size 60 { 61 auto mv = MeasuringVisitor(9); 62 model.visitForward(data, mv); 63 } 64 } 65 66 version(unittest) 67 @Name("Test1") 68 unittest 69 { 70 setup; 71 72 v.position = 0; 73 v.destination = v.destination.max; 74 model.visitForward(data, v); 75 model.size.should.be == 180; 76 v.output.should.be == [ 77 TreePosition([ ], 0), 78 TreePosition([0], 10), 79 TreePosition([1], 20), 80 TreePosition([2], 30), 81 TreePosition([3], 40), 82 TreePosition([3, 0], 50), 83 TreePosition([3, 1], 60), 84 TreePosition([4], 70), 85 TreePosition([4, 0], 80), 86 TreePosition([4, 1], 90), 87 TreePosition([4, 2], 100), 88 TreePosition([4, 2, 0], 110), 89 TreePosition([4, 2, 1], 120), 90 TreePosition([4, 3], 130), 91 TreePosition([4, 3, 0], 140), 92 TreePosition([4, 3, 1], 150), 93 TreePosition([4, 3, 2], 160), 94 TreePosition([5], 170), 95 ]; 96 v.position.should.be == 170; 97 98 v.position = 0; 99 v.path.value = [4,2,1]; 100 model.visitForward(data, v); 101 v.output.should.be == [ 102 TreePosition([4, 2, 1], 0), 103 TreePosition([4, 3], 10), 104 TreePosition([4, 3, 0], 20), 105 TreePosition([4, 3, 1], 30), 106 TreePosition([4, 3, 2], 40), 107 TreePosition([5], 50) 108 ]; 109 } 110 111 version(unittest) 112 @Name("Test2") 113 unittest 114 { 115 setup; 116 117 // default 118 { 119 v.path.clear; 120 v.position = 0; 121 v.destination = v.destination.max; 122 model.visitForward(data, v); 123 124 v.position.should.be == 170; 125 v.path.value[].should.be == (int[]).init; 126 } 127 128 // next position is between two elements 129 { 130 v.path.clear; 131 v.position = 0; 132 v.destination = 15; 133 model.visitForward(data, v); 134 135 v.position.should.be == 10; 136 v.destination.should.be == 15; 137 v.path.value[].should.be == [0]; 138 } 139 140 // next position is equal to start of an element 141 { 142 v.path.clear; 143 v.position = 0; 144 v.destination = 30; 145 model.visitForward(data, v); 146 147 v.position.should.be == 30; 148 v.destination.should.be == 30; 149 v.path.value[].should.be == [2]; 150 } 151 152 // start path is not null 153 { 154 v.path.value = [3, 0]; 155 v.position = 0; 156 v.destination = 55; 157 model.visitForward(data, v); 158 159 v.position.should.be == 50; 160 v.destination.should.be == 55; 161 v.path.value[].should.be == [4, 2]; 162 } 163 164 // reverse order, start path is not null 165 { 166 v.path.value = [4, 1]; 167 v.position = 90; 168 v.destination = 41; 169 170 model.visitBackward(data, v); 171 172 v.position.should.be == 40; 173 v.destination.should.be == 41; 174 v.path.value[].should.be == [3]; 175 176 // bubble to the next element 177 v.destination = 19; 178 179 model.visitBackward(data, v); 180 181 v.path.value[].should.be == [0]; 182 v.position.should.be == 10; 183 v.destination.should.be == 19; 184 v.output.should.be == [ 185 TreePosition([3], 40), 186 TreePosition([2], 30), 187 TreePosition([1], 20), 188 TreePosition([0], 10), 189 ]; 190 } 191 } 192 193 version(unittest) 194 @Name("ScrollingTest") 195 unittest 196 { 197 setup; 198 199 v.path.clear; 200 v.position = 0; 201 202 // the element height is 10 px 203 204 // scroll 7 px forward 205 visit(model, data, v, 7); 206 // current element is the root one 207 v.path.value[].should.be == (int[]).init; 208 // position of the current element is 0 px 209 v.position.should.be == 0; 210 // the window starts from 7th px 211 v.destination.should.be == 7; 212 213 // scroll the next 7th px forward 214 visit(model, data, v, 14); 215 // the current element is the first child element 216 v.path.value[].should.be == [0]; 217 // position of the current element is 10 px 218 v.position.should.be == 10; 219 // the window starts from 14th px 220 v.destination.should.be == 14; 221 222 // scroll the next 7th px forward 223 visit(model, data, v, 21); 224 // the current element is the second child element 225 v.path.value[].should.be == [1]; 226 // position of the current element is 20 px 227 v.position.should.be == 20; 228 // the window starts from 21th px 229 v.destination.should.be == 21; 230 231 // scroll the next 7th px forward 232 visit(model, data, v, 28); 233 // the current element is the second child element 234 v.path.value[].should.be == [1]; 235 // position of the current element is 20 px 236 v.position.should.be == 20; 237 // the window starts from 28th px 238 v.destination.should.be == 28; 239 240 // scroll the next 7th px forward 241 visit(model, data, v, 35); 242 // the current element is the third child element 243 v.path.value[].should.be == [2]; 244 // position of the current element is 30 px 245 v.position.should.be == 30; 246 // the window starts from 35th px 247 v.destination.should.be == 35; 248 249 // scroll 7th px backward 250 visit(model, data, v, 27); 251 // the current element is the second child element 252 v.path.value[].should.be == [1]; 253 // position of the current element is 20 px 254 v.position.should.be == 20; 255 // the window starts from 27th px 256 v.destination.should.be == 27; 257 258 // scroll the next 9th px backward 259 visit(model, data, v, 18); 260 // the current element is the first child element 261 v.path.value[].should.be == [0]; 262 // position of the current element is 10 px 263 v.position.should.be == 10; 264 // the window starts from 18th px 265 v.destination.should.be == 18; 266 267 // scroll the next 6th px backward 268 visit(model, data, v, 12); 269 // the current element is the first child element 270 v.path.value[].should.be == [0]; 271 // position of the current element is 10 px 272 v.position.should.be == 10; 273 // the window starts from 12th px 274 v.destination.should.be == 12; 275 276 // scroll the next 5th px backward 277 visit(model, data, v, 7); 278 // the current element is the root element 279 v.path.value[].should.be == (int[]).init; 280 // position of the current element is 0 px 281 v.position.should.be == 0; 282 // the window starts from 7th px 283 v.destination.should.be == 7; 284 285 // scroll 76 px forward 286 visit(model, data, v, 83); 287 // // the current element is the second child element 288 // v.path.value[].should.be == [4, 0]; 289 // // position of the current element is 20 px 290 // v.position.should.be == 80; 291 // the window starts from 27th px 292 v.destination.should.be == 83; 293 294 visit(model, data, v, 81); 295 v.path.value[].should.be == [4, 0]; 296 v.position.should.be == 80; 297 v.destination.should.be == 81; 298 299 visit(model, data, v, 80); 300 v.path.value[].should.be == [4, 0]; 301 v.position.should.be == 80; 302 v.destination.should.be == 80; 303 304 visit(model, data, v, 79); 305 v.path.value[].should.be == [4]; 306 v.position.should.be == 70; 307 v.destination.should.be == 79; 308 309 visit(model, data, v, 133); 310 v.path.value[].should.be == [4, 3]; 311 v.position.should.be == 130; 312 v.destination.should.be == 133; 313 314 visit(model, data, v, 0); 315 v.path.value[].should.be == (int[]).init; 316 v.position.should.be == 0; 317 v.destination.should.be == 0; 318 }