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