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', 'xps'], 30 ['laptop', 'dell', 'inspiron'], 31 ['laptop', 'dell', '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 $multiMultiItems = [ 50 [['metal', 'wood'], ['green', 'yellow'], 'car', 'audi', 'a80'], 51 [['metal', 'wood', 'plastic'], ['yellow', 'blue'], 'car', 'audi', 'a4'], 52 [['plastic', 'metal'], ['red', 'blue'], 'laptop', 'apple', 'pro 16'], 53 [['metal', 'plastic'], ['black', 'red'], 'laptop', 'apple', 'air'], 54 ]; 55 56 57 /** 58 * Create a result set from a given flat array 59 * @param array $rows 60 * @return array 61 */ 62 protected function makeResult($rows) 63 { 64 $result = []; 65 66 foreach ($rows as $row) { 67 $resultRow = []; 68 foreach ($row as $cell) { 69 $resultRow[] = new Value( 70 new Column( 71 10, 72 new Text(null, '', is_array($cell)), 73 0, 74 true, 75 'test' 76 ), 77 $cell 78 ); 79 } 80 $result[] = $resultRow; 81 } 82 83 return $result; 84 } 85 86 /** 87 * Don't nest at all 88 */ 89 public function testSimpleZeroLevel() 90 { 91 $result = $this->makeResult($this->simpleItems); 92 $nestedResult = new NestedResult($result); 93 $root = $nestedResult->getRoot(0); 94 95 $this->assertCount(0, $root->getChildren(), 'no children expected'); 96 $this->assertCount(12, $root->getResultRows(), '12 result rows expected'); 97 } 98 99 100 /** 101 * Nest by the first level, no multi values 102 */ 103 public function testSimpleOneLevel() 104 { 105 $result = $this->makeResult($this->simpleItems); 106 $nestedResult = new NestedResult($result); 107 $root = $nestedResult->getRoot(1); 108 $tree = $root->getChildren(); 109 110 $this->assertCount(2, $tree, '2 root nodes expected'); 111 $this->assertEquals('car', $tree[0]->getValueObject()->getValue()); 112 $this->assertEquals('laptop', $tree[1]->getValueObject()->getValue()); 113 114 $this->assertCount(0, $tree[0]->getChildren(), 'no children expected'); 115 $this->assertCount(0, $tree[1]->getChildren(), 'no children expected'); 116 117 $this->assertCount(6, $tree[0]->getResultRows(), 'result rows'); 118 $this->assertCount(6, $tree[1]->getResultRows(), 'result rows'); 119 120 $this->assertEquals('a80', $tree[0]->getResultRows()[0][1]->getValue(), 'Audi 80 expected'); 121 $this->assertEquals('pro 16', $tree[1]->getResultRows()[0][1]->getValue(), 'Mac Pro 16 expected'); 122 } 123 124 125 /** 126 * Nest by two levels, no multi values 127 */ 128 public function testSimpleTwoLevels() 129 { 130 $result = $this->makeResult($this->simpleItems); 131 $nestedResult = new NestedResult($result); 132 $root = $nestedResult->getRoot(2); 133 $tree = $root->getChildren(); 134 135 $this->assertCount(2, $tree, '2 root nodes expected'); 136 $this->assertEquals('car', $tree[0]->getValueObject()->getValue()); 137 $this->assertEquals('laptop', $tree[1]->getValueObject()->getValue()); 138 139 $this->assertCount(2, $tree[0]->getChildren(), '2 second level nodes expected'); 140 $this->assertCount(2, $tree[1]->getChildren(), '2 second level nodes expected'); 141 142 $this->assertCount(3, $tree[0]->getChildren()[0]->getResultRows(), 'result rows'); 143 $this->assertCount(3, $tree[0]->getChildren()[1]->getResultRows(), 'result rows'); 144 $this->assertCount(3, $tree[1]->getChildren()[0]->getResultRows(), 'result rows'); 145 $this->assertCount(3, $tree[1]->getChildren()[1]->getResultRows(), 'result rows'); 146 147 148 $this->assertEquals('a80', $tree[0]->getChildren()[0]->getResultRows()[0][0]->getValue(), 'Audi 80 expected'); 149 $this->assertEquals('pro 16', $tree[1]->getChildren()[0]->getResultRows()[0][0]->getValue(), 'Mac Pro 16 expected'); 150 } 151 152 /** 153 * Nest by three levels, the first one being multi-value 154 */ 155 public function testMultiThreeLevels() 156 { 157 $result = $this->makeResult($this->multiItems); 158 $nestedResult = new NestedResult($result); 159 $root = $nestedResult->getRoot(3); 160 $tree = $root->getChildren(); // nest: color, type, brand -> model 161 162 $this->assertCount(6, $tree, '6 root nodes of colors expected'); 163 164 // Values on the first level will be multi-values, thus returning arrays 165 $this->assertEquals('black', $tree[0]->getValueObject()->getValue()[0]); 166 $this->assertEquals('blue', $tree[1]->getValueObject()->getValue()[0]); 167 $this->assertEquals('gray', $tree[2]->getValueObject()->getValue()[0]); 168 $this->assertEquals('green', $tree[3]->getValueObject()->getValue()[0]); 169 $this->assertEquals('red', $tree[4]->getValueObject()->getValue()[0]); 170 $this->assertEquals('yellow', $tree[5]->getValueObject()->getValue()[0]); 171 172 // Results should now show up under multiple top-level nodes 173 $this->assertEquals('a80', 174 $tree[3] // green 175 ->getChildren()[0] // car 176 ->getChildren()[0] // audi 177 ->getResultRows()[0][0] // a80 178 ->getValue(), 179 'green car audi a80 expected' 180 ); 181 $this->assertEquals('a80', 182 $tree[5] // yellow 183 ->getChildren()[0] // car 184 ->getChildren()[0] // audi 185 ->getResultRows()[0][0] // a80 186 ->getValue(), 187 'yellow car audi a80 expected' 188 ); 189 } 190 191 /** 192 * Nest by two multi value levels 193 */ 194 public function testMultiMultiTwoLevels() 195 { 196 $result = $this->makeResult($this->multiMultiItems); 197 $nestedResult = new NestedResult($result); 198 $root = $nestedResult->getRoot(2); 199 $tree = $root->getChildren(); // nest: material, color, * 200 201 $this->assertCount(3, $tree, '3 root nodes of material expected'); 202 $this->assertCount(1, $tree[0]->getChildren()[0]->getResultRows(), '1 metal black row expected'); 203 } 204 205 /** 206 * Nest by two multi value levels with indexing 207 */ 208 public function testMultiMultiTwoLevelsIndex() 209 { 210 $result = $this->makeResult($this->multiMultiItems); 211 $nestedResult = new NestedResult($result); 212 $root = $nestedResult->getRoot(2, 1); 213 $tree = $root->getChildren(); // nest: index, material, color, * 214 215 $this->assertCount(3, $tree, '3 root index nodes expected'); 216 $this->assertEquals('M', $tree[0]->getValueObject()->getValue(), 'M expected'); 217 $this->assertCount(1, $tree[0]->getChildren(), '1 metal sub node under M expected'); 218 } 219 220 /** 221 * Index a flat result with no multi values 222 */ 223 public function testSimpleIndex() 224 { 225 $result = $this->makeResult($this->simpleItems); 226 $nestedResult = new NestedResult($result); 227 $root = $nestedResult->getRoot(0, 2); 228 $tree = $root->getChildren(); 229 230 $this->assertCount(2, $tree, '2 root index nodes expected'); 231 $this->assertEquals('CA', $tree[0]->getValueObject()->getValue(), 'CA(r) index expected'); 232 $this->assertEquals('LA', $tree[1]->getValueObject()->getValue(), 'LA(ptop) index expected'); 233 234 $this->assertCount(6, $tree[0]->getResultRows(), '6 rows under CA expected'); 235 } 236 237 238 /** 239 * Index a flat result with multi values 240 */ 241 public function testMultiIndex() 242 { 243 $result = $this->makeResult($this->multiItems); 244 $nestedResult = new NestedResult($result); 245 $root = $nestedResult->getRoot(0, 2); 246 $tree = $root->getChildren(); 247 248 $this->assertCount(4, $tree, '4 root index nodes expected'); 249 $this->assertEquals('BL', $tree[0]->getValueObject()->getValue(), 'BL(ack|blue) index expected'); 250 251 $this->assertCount(4, $tree[0]->getResultRows(), '4 rows under BL expected'); 252 } 253} 254