xref: /plugin/struct/_test/NestedResultTest.php (revision ce44c6393fcd559a7f07942c55824e5b8379912c)
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