Skip to content

Commit 4c31bcd

Browse files
authored
Merge pull request #646 from cosmocode/structfilter
New syntax component: filter
2 parents ae522a2 + 5834bfb commit 4c31bcd

24 files changed

+783
-254
lines changed

_test/AggregationFilterTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\struct\test;
4+
5+
6+
class AggregationFilterTest extends StructTest
7+
{
8+
protected $items = [
9+
[['green', 'yellow'], 'car', 'audi', 'a80'],
10+
[[], 'car', 'audi', 'a4'],
11+
[['red', 'black'], 'car', 'bmw', 'i3'],
12+
[['green', 'blue'], 'laptop', 'apple', 'pro 16'],
13+
[['blue', 'gray'], 'car', 'bmw', 'mini'],
14+
[['red', 'black'], 'car', 'bmw', 'z1'],
15+
[['red', 'blue'], 'laptop', 'apple', 'air'],
16+
[['black', 'red'], 'laptop', 'apple', 'm1'],
17+
[[], 'laptop', 'dell', 'xps'],
18+
[['black', 'green'], '', 'audi', 'quattro'],
19+
[['blue', 'yellow'], '', 'dell', 'inspiron'],
20+
[['gray', 'yellow'], 'laptop', 'dell', 'latitude'],
21+
];
22+
23+
public function testGetAllColumnValues()
24+
{
25+
$result = $this->createAggregationResult($this->items);
26+
$filter = new mock\AggregationFilter();
27+
$values = $filter->getAllColumnValues($result);
28+
29+
$this->assertCount(4, $values);
30+
31+
// we expect value => displayValue pairs, sorted by displayValue
32+
$this->assertSame(
33+
[
34+
'black' => 'black',
35+
'blue' => 'blue',
36+
'gray' => 'gray',
37+
'green' => 'green',
38+
'red' => 'red',
39+
'yellow' => 'yellow'
40+
],
41+
$values[0]['values']
42+
);
43+
44+
$this->assertEquals(
45+
'Label 1',
46+
$values[0]['label']
47+
);
48+
49+
$this->assertSame(
50+
[
51+
'car' => 'car',
52+
'laptop' => 'laptop'
53+
],
54+
$values[1]['values']
55+
);
56+
57+
$this->assertEquals(
58+
'Label 2',
59+
$values[1]['label']
60+
);
61+
}
62+
}

_test/AggregationResultsTest.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ public function setUp(): void
3232
$assignments = mock\Assignments::getInstance();
3333
$assignments->clear(true);
3434

35+
// different values for each entry
36+
$second = [
37+
['green', 'red'],
38+
['green', 'blue'],
39+
['blue', 'yellow']
40+
];
41+
3542
for ($i = 0; $i < 3; $i++) {
3643
// assign a schema
3744
$assignments->assignPageSchema("test$i", 'schema1');
@@ -42,7 +49,7 @@ public function setUp(): void
4249
// save serial data
4350
$data = [
4451
'first' => "foo$i",
45-
'second' => ["bar$i", "baz$i"],
52+
'second' => $second[$i],
4653
'third' => "foobar$i",
4754
'fourth' => "barfoo$i",
4855
];
@@ -65,7 +72,7 @@ public function test_pid()
6572
$this->assertEquals('test1', $result[0][0]->getValue());
6673
// skip %rowid% column and test saved values
6774
$this->assertEquals('foo1', $result[0][2]->getValue());
68-
$this->assertEquals(['bar1', 'baz1'], $result[0][3]->getValue());
75+
$this->assertEquals(['green', 'blue'], $result[0][3]->getValue());
6976
$this->assertEquals('foobar1', $result[0][4]->getValue());
7077
$this->assertEquals('barfoo1', $result[0][5]->getValue());
7178
}
@@ -86,6 +93,22 @@ public function test_filter_text()
8693
$this->assertCount(0, $result);
8794
}
8895

96+
/** @noinspection PhpUnreachableStatementInspection */
97+
public function test_filter_multi()
98+
{
99+
$schema = 'schema1';
100+
$result = $this->fetchPagesResult($schema, '');
101+
$this->assertCount(3, $result);
102+
103+
$result = $this->fetchPagesResult($schema, '', ['second', '=', 'green', 'AND']);
104+
$this->assertCount(2, $result);
105+
106+
$this->markTestIncomplete('negative filters currently do not work on multi fields. See #512');
107+
108+
$result = $this->fetchPagesResult($schema, '', ['second', '!~', 'green', 'AND']);
109+
$this->assertCount(1, $result);
110+
}
111+
89112
/**
90113
* Test filtering on a page field, with 'usetitles' set to true and false
91114
*/

_test/NestedResultTest.php

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -68,56 +68,25 @@ class NestedResultTest extends StructTest
6868
[['metal', 'plastic'], ['black', 'red'], 'laptop', 'apple', 'air'],
6969
];
7070

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-
10171
/**
10272
* Don't nest at all
10373
*/
10474
public function testSimpleZeroLevel()
10575
{
106-
$result = $this->makeResult($this->simpleItems);
76+
$result = $this->createAggregationResult($this->simpleItems);
10777
$nestedResult = new NestedResult($result);
10878
$root = $nestedResult->getRoot(0);
10979

11080
$this->assertCount(0, $root->getChildren(true), 'no children expected');
11181
$this->assertCount(12, $root->getResultRows(), '12 result rows expected');
11282
}
11383

114-
11584
/**
11685
* Nest by the first level, no multi values
11786
*/
11887
public function testSimpleOneLevel()
11988
{
120-
$result = $this->makeResult($this->simpleItems);
89+
$result = $this->createAggregationResult($this->simpleItems);
12190
$nestedResult = new NestedResult($result);
12291
$root = $nestedResult->getRoot(1);
12392
$tree = $root->getChildren(true);
@@ -142,7 +111,7 @@ public function testSimpleOneLevel()
142111
*/
143112
public function testSimpleTwoLevels()
144113
{
145-
$result = $this->makeResult($this->simpleItems);
114+
$result = $this->createAggregationResult($this->simpleItems);
146115
$nestedResult = new NestedResult($result);
147116
$root = $nestedResult->getRoot(2);
148117
$tree = $root->getChildren(true);
@@ -170,7 +139,7 @@ public function testSimpleTwoLevels()
170139
*/
171140
public function testMultiThreeLevels()
172141
{
173-
$result = $this->makeResult($this->multiItems);
142+
$result = $this->createAggregationResult($this->multiItems);
174143
$nestedResult = new NestedResult($result);
175144
$root = $nestedResult->getRoot(3);
176145
$tree = $root->getChildren(true); // nest: color, type, brand -> model
@@ -206,7 +175,7 @@ public function testMultiThreeLevels()
206175

207176
public function testMultiHoles()
208177
{
209-
$result = $this->makeResult($this->multiHoleItems);
178+
$result = $this->createAggregationResult($this->multiHoleItems);
210179
$nestedResult = new NestedResult($result);
211180
$root = $nestedResult->getRoot(3);
212181
$tree = $root->getChildren(true); // nest: color, type, brand -> model
@@ -220,7 +189,7 @@ public function testMultiHoles()
220189
*/
221190
public function testMultiMultiTwoLevels()
222191
{
223-
$result = $this->makeResult($this->multiMultiItems);
192+
$result = $this->createAggregationResult($this->multiMultiItems);
224193
$nestedResult = new NestedResult($result);
225194
$root = $nestedResult->getRoot(2);
226195
$tree = $root->getChildren(true); // nest: material, color, *
@@ -234,7 +203,7 @@ public function testMultiMultiTwoLevels()
234203
*/
235204
public function testMultiMultiTwoLevelsIndex()
236205
{
237-
$result = $this->makeResult($this->multiMultiItems);
206+
$result = $this->createAggregationResult($this->multiMultiItems);
238207
$nestedResult = new NestedResult($result);
239208
$root = $nestedResult->getRoot(2, 1);
240209
$tree = $root->getChildren(true); // nest: index, material, color, *
@@ -249,7 +218,7 @@ public function testMultiMultiTwoLevelsIndex()
249218
*/
250219
public function testSimpleIndex()
251220
{
252-
$result = $this->makeResult($this->simpleItems);
221+
$result = $this->createAggregationResult($this->simpleItems);
253222
$nestedResult = new NestedResult($result);
254223
$root = $nestedResult->getRoot(0, 2);
255224
$tree = $root->getChildren(true);
@@ -267,7 +236,7 @@ public function testSimpleIndex()
267236
*/
268237
public function testMultiIndex()
269238
{
270-
$result = $this->makeResult($this->multiItems);
239+
$result = $this->createAggregationResult($this->multiItems);
271240
$nestedResult = new NestedResult($result);
272241
$root = $nestedResult->getRoot(0, 2);
273242
$tree = $root->getChildren(true);

_test/SearchConfigParameterTest.php

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,44 +88,54 @@ public function test_constructor()
8888
];
8989

9090
// init with no parameters
91-
$expect = $data;
9291
$params = [];
9392
$searchConfig = new meta\SearchConfig($data);
9493
$dynamic = $searchConfig->getDynamicParameters();
95-
$this->assertEquals($expect, $searchConfig->getConf());
96-
$this->assertEquals($params, $dynamic->getURLParameters());
94+
$this->assertEquals($data, $searchConfig->getConf(), 'config as is');
95+
$this->assertEquals($params, $dynamic->getURLParameters(), 'no dynamic parameters');
9796

9897
// init with sort
9998
$INPUT->set(meta\SearchConfigParameters::$PARAM_SORT, '^alias2.athird');
100-
$expect['sort'] = [['schema2.athird', false]];
10199
$params[meta\SearchConfigParameters::$PARAM_SORT] = '^schema2.athird';
102100
$searchConfig = new meta\SearchConfig($data);
103101
$dynamic = $searchConfig->getDynamicParameters();
104-
$this->assertEquals($expect, $searchConfig->getConf());
105102
$this->assertEquals($params, $dynamic->getURLParameters());
103+
$sorts = $searchConfig->getSorts();
104+
$this->assertArrayHasKey('schema2.athird', $sorts);
105+
$this->assertInstanceOf(meta\Column::class, $sorts['schema2.athird'][0]);
106+
$this->assertEquals('schema2.athird', $sorts['schema2.athird'][0]->getFullQualifiedLabel());
107+
$this->assertFalse($sorts['schema2.athird'][1], 'DESC sorting');
108+
$this->assertTrue($sorts['schema2.athird'][2], 'case-insensitive sorting');
106109

107110
// init with offset
108111
$INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 25);
109-
$expect['offset'] = 25;
110112
$params[meta\SearchConfigParameters::$PARAM_OFFSET] = 25;
111113
$searchConfig = new meta\SearchConfig($data);
112114
$dynamic = $searchConfig->getDynamicParameters();
113-
$this->assertEquals($expect, $searchConfig->getConf());
114115
$this->assertEquals($params, $dynamic->getURLParameters());
116+
$this->assertEquals(25, $searchConfig->getOffset(), 'offset set');
115117

116118
// init with filters
117119
$_REQUEST[meta\SearchConfigParameters::$PARAM_FILTER]['alias1.first*~'] = 'test';
118120
$_REQUEST[meta\SearchConfigParameters::$PARAM_FILTER]['afirst='] = 'test2';
119-
$expect['filter'] = [
120-
['schema1.first', '*~', 'test', 'AND'],
121-
['schema2.afirst', '=', 'test2', 'AND']
122-
];
123121
$params[meta\SearchConfigParameters::$PARAM_FILTER . '[schema1.first*~]'] = 'test';
124122
$params[meta\SearchConfigParameters::$PARAM_FILTER . '[schema2.afirst=]'] = 'test2';
125123
$searchConfig = new meta\SearchConfig($data);
126124
$dynamic = $searchConfig->getDynamicParameters();
127-
$this->assertEquals($expect, $searchConfig->getConf());
128125
$this->assertEquals($params, $dynamic->getURLParameters());
126+
$filters = $this->getInaccessibleProperty($searchConfig, 'dynamicFilter');
127+
128+
$this->assertInstanceOf(meta\Column::class, $filters[0][0]);
129+
$this->assertEquals('schema1.first', $filters[0][0]->getFullQualifiedLabel(), 'full qualified column name');
130+
$this->assertEquals('%test%', $filters[0][1], 'value with like placeholders');
131+
$this->assertEquals('LIKE', $filters[0][2], 'comparator');
132+
$this->assertEquals('AND', $filters[0][3], 'boolean operator');
133+
134+
$this->assertInstanceOf(meta\Column::class, $filters[1][0]);
135+
$this->assertEquals('schema2.afirst', $filters[1][0]->getFullQualifiedLabel(), 'full qualified column name');
136+
$this->assertEquals('test2', $filters[1][1], 'value with no placeholders');
137+
$this->assertEquals('=', $filters[1][2], 'comparator');
138+
$this->assertEquals('AND', $filters[1][3], 'boolean operator');
129139
}
130140

131141
public function test_filter()
@@ -198,23 +208,17 @@ public function test_sort()
198208
$dynamic = $searchConfig->getDynamicParameters();
199209

200210
$dynamic->setSort('%pageid%');
201-
$conf = $dynamic->updateConfig($data);
202211
$param = $dynamic->getURLParameters();
203-
$this->assertEquals([['%pageid%', true]], $conf['sort']);
204212
$this->assertArrayHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
205213
$this->assertEquals('%pageid%', $param[meta\SearchConfigParameters::$PARAM_SORT]);
206214

207215
$dynamic->setSort('%pageid%', false);
208-
$conf = $dynamic->updateConfig($data);
209216
$param = $dynamic->getURLParameters();
210-
$this->assertEquals([['%pageid%', false]], $conf['sort']);
211217
$this->assertArrayHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
212218
$this->assertEquals('^%pageid%', $param[meta\SearchConfigParameters::$PARAM_SORT]);
213219

214220
$dynamic->removeSort();
215-
$conf = $dynamic->updateConfig($data);
216221
$param = $dynamic->getURLParameters();
217-
$this->assertArrayNotHasKey('sort', $conf);
218222
$this->assertArrayNotHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
219223
}
220224

@@ -245,8 +249,6 @@ public function test_pagination()
245249
$aggregationTable->render();
246250
$aggregationTable->finishScope();
247251

248-
$rev = time();
249-
250252
$doc = new Document();
251253
$doc->html($R->doc);
252254
$table = $doc->find('div.structaggregation');

_test/StructTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
namespace dokuwiki\plugin\struct\test;
44

55
use dokuwiki\plugin\struct\meta\AccessTable;
6+
use dokuwiki\plugin\struct\meta\Column;
67
use dokuwiki\plugin\struct\meta\SchemaImporter;
8+
use dokuwiki\plugin\struct\meta\Value;
79
use dokuwiki\plugin\struct\test\mock\Assignments;
10+
use dokuwiki\plugin\struct\types\Text;
811

912
/**
1013
* Base class for all struct tests
@@ -110,4 +113,37 @@ protected function cleanWS($string)
110113
{
111114
return preg_replace('/\s+/s', '', $string);
112115
}
116+
117+
/**
118+
* Create an Aggregation result set from a given flat array
119+
*
120+
* The result will contain simple Text columns
121+
*
122+
* @param array $rows
123+
* @return array
124+
*/
125+
protected function createAggregationResult($rows)
126+
{
127+
$result = [];
128+
129+
foreach ($rows as $row) {
130+
$resultRow = [];
131+
foreach ($row as $num => $cell) {
132+
$colRef = $num + 1;
133+
$resultRow[] = new Value(
134+
new Column(
135+
10,
136+
new Text(['label' => ['en' => "Label $colRef"]], "field$colRef", is_array($cell)),
137+
$colRef,
138+
true,
139+
'test'
140+
),
141+
$cell
142+
);
143+
}
144+
$result[] = $resultRow;
145+
}
146+
147+
return $result;
148+
}
113149
}

0 commit comments

Comments
 (0)