1<?php 2 3namespace dokuwiki\plugin\struct\test; 4 5use dokuwiki\plugin\struct\meta\Column; 6use dokuwiki\plugin\struct\meta\NestedResult; 7use dokuwiki\plugin\struct\meta\Value; 8use dokuwiki\plugin\struct\types\Text; 9 10/** 11 * Tests for the NestedResult class 12 * 13 * @group plugin_struct 14 * @group plugins 15 * 16 */ 17class NestedResultTest extends StructTest 18{ 19 protected $simpleItems = [ 20 ['car', 'audi', 'a80'], 21 ['car', 'audi', 'a4'], 22 ['car', 'audi', 'quattro'], 23 ['car', 'bmw', 'i3'], 24 ['car', 'bmw', 'mini'], 25 ['car', 'bmw', 'z1'], 26 ['laptop', 'apple', 'pro 16'], 27 ['laptop', 'apple', 'air'], 28 ['laptop', 'apple', 'm1'], 29 ['laptop', 'dell', 'inspiron'], 30 ['laptop', 'dell', 'latitude'], 31 ['laptop', 'bmw', 'latitude'], 32 ]; 33 34 protected $multiItems = [ 35 [['green', 'yellow'], 'car', 'audi', 'a80'], 36 [['yellow', 'blue'], 'car', 'audi', 'a4'], 37 [['black', 'green'], 'car', 'audi', 'quattro'], 38 [['red', 'black'], 'car', 'bmw', 'i3'], 39 [['blue', 'gray'], 'car', 'bmw', 'mini'], 40 [['red', 'black'], 'car', 'bmw', 'z1'], 41 [['green', 'blue'], 'laptop', 'apple', 'pro 16'], 42 [['red', 'blue'], 'laptop', 'apple', 'air'], 43 [['black', 'red'], 'laptop', 'apple', 'm1'], 44 [['gray', 'green'], 'laptop', 'dell', 'xps'], 45 [['blue', 'yellow'], 'laptop', 'dell', 'inspiron'], 46 [['gray', 'yellow'], 'laptop', 'dell', 'latitude'], 47 ]; 48 49 protected $multiHoleItems = [ 50 [['green', 'yellow'], 'car', 'audi', 'a80'], 51 [[], 'car', 'audi', 'a4'], 52 [['black', 'green'], '', 'audi', 'quattro'], 53 [['red', 'black'], 'car', 'bmw', 'i3'], 54 [['blue', 'gray'], 'car', 'bmw', 'mini'], 55 [['red', 'black'], 'car', 'bmw', 'z1'], 56 [['green', 'blue'], 'laptop', 'apple', 'pro 16'], 57 [['red', 'blue'], 'laptop', 'apple', 'air'], 58 [['black', 'red'], 'laptop', 'apple', 'm1'], 59 [[], 'laptop', 'dell', 'xps'], 60 [['blue', 'yellow'], '', 'dell', 'inspiron'], 61 [['gray', 'yellow'], 'laptop', 'dell', 'latitude'], 62 ]; 63 64 protected $multiMultiItems = [ 65 [['metal', 'wood'], ['green', 'yellow'], 'car', 'audi', 'a80'], 66 [['metal', 'wood', 'plastic'], ['yellow', 'blue'], 'car', 'audi', 'a4'], 67 [['plastic', 'metal'], ['red', 'blue'], 'laptop', 'apple', 'pro 16'], 68 [['metal', 'plastic'], ['black', 'red'], 'laptop', 'apple', 'air'], 69 ]; 70 71 /** 72 * Don't nest at all 73 */ 74 public function testSimpleZeroLevel() 75 { 76 $result = $this->createAggregationResult($this->simpleItems); 77 $nestedResult = new NestedResult($result); 78 $root = $nestedResult->getRoot(0); 79 80 $this->assertCount(0, $root->getChildren(true), 'no children expected'); 81 $this->assertCount(12, $root->getResultRows(), '12 result rows expected'); 82 } 83 84 /** 85 * Nest by the first level, no multi values 86 */ 87 public function testSimpleOneLevel() 88 { 89 $result = $this->createAggregationResult($this->simpleItems); 90 $nestedResult = new NestedResult($result); 91 $root = $nestedResult->getRoot(1); 92 $tree = $root->getChildren(true); 93 94 $this->assertCount(2, $tree, '2 root nodes expected'); 95 $this->assertEquals('car', $tree[0]->getValueObject()->getValue()); 96 $this->assertEquals('laptop', $tree[1]->getValueObject()->getValue()); 97 98 $this->assertCount(0, $tree[0]->getChildren(true), 'no children expected'); 99 $this->assertCount(0, $tree[1]->getChildren(true), 'no children expected'); 100 101 $this->assertCount(6, $tree[0]->getResultRows(), 'result rows'); 102 $this->assertCount(6, $tree[1]->getResultRows(), 'result rows'); 103 104 $this->assertEquals('a80', $tree[0]->getResultRows()[0][1]->getValue(), 'Audi 80 expected'); 105 $this->assertEquals('pro 16', $tree[1]->getResultRows()[0][1]->getValue(), 'Mac Pro 16 expected'); 106 } 107 108 109 /** 110 * Nest by two levels, no multi values 111 */ 112 public function testSimpleTwoLevels() 113 { 114 $result = $this->createAggregationResult($this->simpleItems); 115 $nestedResult = new NestedResult($result); 116 $root = $nestedResult->getRoot(2); 117 $tree = $root->getChildren(true); 118 119 $this->assertCount(2, $tree, '2 root nodes expected'); 120 $this->assertEquals('car', $tree[0]->getValueObject()->getValue()); 121 $this->assertEquals('laptop', $tree[1]->getValueObject()->getValue()); 122 123 $this->assertCount(2, $tree[0]->getChildren(true), '2 car brands expected'); 124 $this->assertCount(3, $tree[1]->getChildren(true), '3 laptop brands expected'); 125 126 $this->assertCount(3, $tree[0]->getChildren(true)[0]->getResultRows(), '3 audis expected'); 127 $this->assertCount(3, $tree[0]->getChildren(true)[1]->getResultRows(), '3 bmw expected'); 128 $this->assertCount(3, $tree[1]->getChildren(true)[0]->getResultRows(), '3 apple expected'); 129 $this->assertCount(1, $tree[1]->getChildren(true)[1]->getResultRows(), '1 bmw expected'); 130 $this->assertCount(2, $tree[1]->getChildren(true)[2]->getResultRows(), '2 dell expected'); 131 132 133 $this->assertEquals('a80', $tree[0]->getChildren(true)[0]->getResultRows()[0][0]->getValue(), 'Audi 80 expected'); 134 $this->assertEquals('pro 16', $tree[1]->getChildren(true)[0]->getResultRows()[0][0]->getValue(), 'Mac Pro 16 expected'); 135 } 136 137 /** 138 * Nest by three levels, the first one being multi-value 139 */ 140 public function testMultiThreeLevels() 141 { 142 $result = $this->createAggregationResult($this->multiItems); 143 $nestedResult = new NestedResult($result); 144 $root = $nestedResult->getRoot(3); 145 $tree = $root->getChildren(true); // nest: color, type, brand -> model 146 147 $this->assertCount(6, $tree, '6 root nodes of colors expected'); 148 149 // Values on the first level will be multi-values, thus returning arrays 150 $this->assertEquals('black', $tree[0]->getValueObject()->getValue()[0]); 151 $this->assertEquals('blue', $tree[1]->getValueObject()->getValue()[0]); 152 $this->assertEquals('gray', $tree[2]->getValueObject()->getValue()[0]); 153 $this->assertEquals('green', $tree[3]->getValueObject()->getValue()[0]); 154 $this->assertEquals('red', $tree[4]->getValueObject()->getValue()[0]); 155 $this->assertEquals('yellow', $tree[5]->getValueObject()->getValue()[0]); 156 157 // Results should now show up under multiple top-level nodes 158 $this->assertEquals('a80', 159 $tree[3] // green 160 ->getChildren(true)[0] // car 161 ->getChildren(true)[0] // audi 162 ->getResultRows()[0][0] // a80 163 ->getValue(), 164 'green car audi a80 expected' 165 ); 166 $this->assertEquals('a80', 167 $tree[5] // yellow 168 ->getChildren(true)[0] // car 169 ->getChildren(true)[0] // audi 170 ->getResultRows()[0][0] // a80 171 ->getValue(), 172 'yellow car audi a80 expected' 173 ); 174 } 175 176 public function testMultiHoles() 177 { 178 $result = $this->createAggregationResult($this->multiHoleItems); 179 $nestedResult = new NestedResult($result); 180 $root = $nestedResult->getRoot(3); 181 $tree = $root->getChildren(true); // nest: color, type, brand -> model 182 $this->assertCount(7, $tree, '6 root nodes of colors + 1 n/a expected'); // should have one n/a node 183 $this->assertCount(2, $tree[6]->getChildren(true), 'top n/a node should have car, laptop'); 184 $this->assertCount(3, $tree[0]->getChildren(true), 'black should have car,laptop,n/a'); 185 } 186 187 /** 188 * Nest by two multi value levels 189 */ 190 public function testMultiMultiTwoLevels() 191 { 192 $result = $this->createAggregationResult($this->multiMultiItems); 193 $nestedResult = new NestedResult($result); 194 $root = $nestedResult->getRoot(2); 195 $tree = $root->getChildren(true); // nest: material, color, * 196 197 $this->assertCount(3, $tree, '3 root nodes of material expected'); 198 $this->assertCount(1, $tree[0]->getChildren(true)[0]->getResultRows(), '1 metal black row expected'); 199 } 200 201 /** 202 * Nest by two multi value levels with indexing 203 */ 204 public function testMultiMultiTwoLevelsIndex() 205 { 206 $result = $this->createAggregationResult($this->multiMultiItems); 207 $nestedResult = new NestedResult($result); 208 $root = $nestedResult->getRoot(2, 1); 209 $tree = $root->getChildren(true); // nest: index, material, color, * 210 211 $this->assertCount(3, $tree, '3 root index nodes expected'); 212 $this->assertEquals('M', $tree[0]->getValueObject()->getValue(), 'M expected'); 213 $this->assertCount(1, $tree[0]->getChildren(true), '1 metal sub node under M expected'); 214 } 215 216 /** 217 * Index a flat result with no multi values 218 */ 219 public function testSimpleIndex() 220 { 221 $result = $this->createAggregationResult($this->simpleItems); 222 $nestedResult = new NestedResult($result); 223 $root = $nestedResult->getRoot(0, 2); 224 $tree = $root->getChildren(true); 225 226 $this->assertCount(2, $tree, '2 root index nodes expected'); 227 $this->assertEquals('CA', $tree[0]->getValueObject()->getValue(), 'CA(r) index expected'); 228 $this->assertEquals('LA', $tree[1]->getValueObject()->getValue(), 'LA(ptop) index expected'); 229 230 $this->assertCount(6, $tree[0]->getResultRows(), '6 rows under CA expected'); 231 } 232 233 234 /** 235 * Index a flat result with multi values 236 */ 237 public function testMultiIndex() 238 { 239 $result = $this->createAggregationResult($this->multiItems); 240 $nestedResult = new NestedResult($result); 241 $root = $nestedResult->getRoot(0, 2); 242 $tree = $root->getChildren(true); 243 244 $this->assertCount(4, $tree, '4 root index nodes expected'); 245 $this->assertEquals('BL', $tree[0]->getValueObject()->getValue(), 'BL(ack|blue) index expected'); 246 247 $this->assertCount(4, $tree[0]->getResultRows(), '4 rows under BL expected'); 248 } 249} 250