SelectQueryTest   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 1423
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 517
c 1
b 0
f 0
dl 0
loc 1423
rs 9.2
wmc 40

40 Methods

Rating   Name   Duplication   Size   Complexity  
A testSelectGraphSpecified() 0 24 1
A testSelectFilterIsIriNotFound() 0 24 1
A testSelectLimit() 0 42 1
A testSelectFilterStrNotFound() 0 26 1
A testSelectOptional() 0 36 1
A testSelectFilterRelationalSmallerThan2() 0 21 1
A testSelectFilterIsUriFound() 0 31 1
A testSelectFilterIsUriNotFound() 0 24 1
A testSelectFilterIsIriFound() 0 31 1
A testSelectFilterRelationalSmallerThan() 0 29 1
A testSelectFilterLangMatches() 0 34 1
A testSelectFilterRelationalGreaterThan() 0 29 1
A testSelectFilterIsLiteralNotFound() 0 24 1
A testSelectOffsetLimit() 0 42 1
A testSelectUnion() 0 39 1
A testSelectOrderByAsc() 0 46 1
A testSelectNoWhereClause() 0 24 1
A testSelectFilterLang() 0 34 1
A testSelectPrefix() 0 32 1
A testSelectFilterIsLiteralFound() 0 31 1
A testSelectOffset() 0 42 1
A testSelectGroupBy() 0 40 1
A testSelectFilterRelationalNotEqual() 0 29 1
A testSelectOrderByAscWithFromClause() 0 46 1
A testSelectDefaultGraph() 0 24 1
A testSelectFilterRegex() 0 32 1
A testSelectFilterStr() 0 34 1
A testSelectFilterRegexWithModifier() 0 32 1
A testSelectCount() 0 31 1
A testSelectOrderByDesc() 0 46 1
A testSelectOrderByWithoutContent() 0 5 1
A testSelectFilterRelationalEqual() 0 29 1
A testSelectFilterDatatype() 0 32 1
A testSelectFilterBoundVariableBounded() 0 31 1
A testSelectFilterIsBlankNotFound() 0 24 1
A testSelectDistinct() 0 23 1
A testSelectFilterIsBlankFound() 0 31 1
A setUp() 0 5 1
A testSelectLeftJoinUsingOptional() 0 55 1
A testSelectFilterBoundNotBounding() 0 24 1

How to fix   Complexity   

Complex Class

Complex classes like SelectQueryTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SelectQueryTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * This file is part of the sweetrdf/InMemoryStoreSqlite package and licensed under
5
 * the terms of the GPL-2 license.
6
 *
7
 * (c) Konrad Abicht <[email protected]>
8
 * (c) Benjamin Nowack
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Tests\Integration\Store\InMemoryStoreSqlite\Query;
15
16
use Exception;
17
use sweetrdf\InMemoryStoreSqlite\Store\InMemoryStoreSqlite;
18
use Tests\TestCase;
19
20
/**
21
 * Tests for query method - focus on SELECT queries.
22
 *
23
 * Output format is: raw
24
 */
25
class SelectQueryTest extends TestCase
26
{
27
    protected function setUp(): void
28
    {
29
        parent::setUp();
30
31
        $this->subjectUnderTest = InMemoryStoreSqlite::createInstance();
32
    }
33
34
    public function testSelectDefaultGraph()
35
    {
36
        // test data
37
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
38
            <http://s> <http://p1> "baz" .
39
        }');
40
41
        $res = $this->subjectUnderTest->query('SELECT * WHERE {<http://s> <http://p1> ?o.}');
42
        $this->assertEquals(
43
            [
44
                'query_type' => 'select',
45
                'result' => [
46
                    'variables' => [
47
                        'o',
48
                    ],
49
                    'rows' => [
50
                        [
51
                            'o' => 'baz',
52
                            'o type' => 'literal',
53
                        ],
54
                    ],
55
                ],
56
            ],
57
            $res
58
        );
59
    }
60
61
    public function testSelectGraphSpecified()
62
    {
63
        // test data
64
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
65
            <http://s> <http://p1> "baz" .
66
        }');
67
68
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://example.com/> WHERE {<http://s> <http://p1> ?o.}');
69
        $this->assertEquals(
70
            [
71
                'query_type' => 'select',
72
                'result' => [
73
                    'variables' => [
74
                        'o',
75
                    ],
76
                    'rows' => [
77
                        [
78
                            'o' => 'baz',
79
                            'o type' => 'literal',
80
                        ],
81
                    ],
82
                ],
83
            ],
84
            $res
85
        );
86
    }
87
88
    // simulate a LEFT JOIN using OPTIONAL
89
    public function testSelectLeftJoinUsingOptional()
90
    {
91
        // test data
92
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
93
            <http://a> <http://p1> <http://b> .
94
            <http://a> <http://p1> <http://c> .
95
96
            <http://b> <http://p1> <http://d> .
97
            <http://b> <http://p1> <http://e> .
98
99
            <http://c> <http://p1> <http://f> .
100
        }');
101
102
        $res = $this->subjectUnderTest->query('
103
            SELECT * WHERE {
104
                ?s <http://p1> ?o .
105
                OPTIONAL {
106
                    ?o <http://p1> ?o2 .
107
                }
108
            }
109
        ');
110
        $this->assertEquals(
111
            [
112
                [
113
                    's' => 'http://a',
114
                    's type' => 'uri',
115
                    'o' => 'http://b',
116
                    'o type' => 'uri',
117
                ],
118
                [
119
                    's' => 'http://a',
120
                    's type' => 'uri',
121
                    'o' => 'http://c',
122
                    'o type' => 'uri',
123
                ],
124
                [
125
                    's' => 'http://b',
126
                    's type' => 'uri',
127
                    'o' => 'http://d',
128
                    'o type' => 'uri',
129
                ],
130
                [
131
                    's' => 'http://b',
132
                    's type' => 'uri',
133
                    'o' => 'http://e',
134
                    'o type' => 'uri',
135
                ],
136
                [
137
                    's' => 'http://c',
138
                    's type' => 'uri',
139
                    'o' => 'http://f',
140
                    'o type' => 'uri',
141
                ],
142
            ],
143
            $res['result']['rows']
144
        );
145
    }
146
147
    /*
148
     * OPTIONAL, artifical query to extend coverage for store code. (SelectQueryHandler::sameOptional)
149
     */
150
    public function testSelectOptional()
151
    {
152
        // test data
153
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
154
            <http://s1> <http://p1> <http://s2> .
155
        }');
156
157
        $res = $this->subjectUnderTest->query('
158
            SELECT * WHERE {
159
                ?s <http://p1> ?o .
160
                OPTIONAL {
161
                    ?o <http://p1> ?o2 .
162
                }
163
                OPTIONAL {
164
                    ?o <http://p1> ?o2 .
165
                }
166
            }
167
        ');
168
        $this->assertEquals(
169
            [
170
                'query_type' => 'select',
171
                'result' => [
172
                    'variables' => [
173
                        's', 'o', 'o2',
174
                    ],
175
                    'rows' => [
176
                        [
177
                            's' => 'http://s1',
178
                            's type' => 'uri',
179
                            'o' => 'http://s2',
180
                            'o type' => 'uri',
181
                        ],
182
                    ],
183
                ],
184
            ],
185
            $res
186
        );
187
    }
188
189
    public function testSelectNoWhereClause()
190
    {
191
        // test data
192
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
193
            <http://s> <http://p1> "baz" .
194
        }');
195
196
        $res = $this->subjectUnderTest->query('SELECT * FROM <http://example.com/> {<http://s> <http://p1> ?o.}');
197
        $this->assertEquals(
198
            [
199
                'query_type' => 'select',
200
                'result' => [
201
                    'variables' => [
202
                        'o',
203
                    ],
204
                    'rows' => [
205
                        [
206
                            'o' => 'baz',
207
                            'o type' => 'literal',
208
                        ],
209
                    ],
210
                ],
211
            ],
212
            $res
213
        );
214
    }
215
216
    /*
217
     * FILTER
218
     */
219
220
    // bound: is variable set?
221
    public function testSelectFilterBoundNotBounding()
222
    {
223
        // test data
224
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
225
            <http://s> <http://p1> "foo" .
226
        }');
227
228
        $res = $this->subjectUnderTest->query('
229
            SELECT ?s ?o WHERE {
230
                ?s <http://p2> ?o .
231
                FILTER (bound(?o))
232
            }
233
        ');
234
        $this->assertEquals(
235
            [
236
                'query_type' => 'select',
237
                'result' => [
238
                    'variables' => [
239
                        's', 'o',
240
                    ],
241
                    'rows' => [],
242
                ],
243
            ],
244
            $res
245
        );
246
    }
247
248
    // bound: is variable set?
249
    public function testSelectFilterBoundVariableBounded()
250
    {
251
        // test data
252
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
253
            <http://s> <http://p1> "foo" .
254
        }');
255
256
        $res = $this->subjectUnderTest->query('
257
            SELECT ?s ?o WHERE {
258
                ?s <http://p1> ?o .
259
                FILTER (bound(?o))
260
            }
261
        ');
262
        $this->assertEquals(
263
            [
264
                'query_type' => 'select',
265
                'result' => [
266
                    'variables' => [
267
                        's', 'o',
268
                    ],
269
                    'rows' => [
270
                        [
271
                            's' => 'http://s',
272
                            's type' => 'uri',
273
                            'o' => 'foo',
274
                            'o type' => 'literal',
275
                        ],
276
                    ],
277
                ],
278
            ],
279
            $res
280
        );
281
    }
282
283
    // datatype
284
    public function testSelectFilterDatatype()
285
    {
286
        // test data
287
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
288
            <http://s> <http://p1> 3 .
289
        }');
290
291
        $res = $this->subjectUnderTest->query('
292
            SELECT ?s ?o WHERE {
293
                ?s <http://p1> ?o .
294
                FILTER (datatype(?o) = xsd:integer)
295
            }
296
        ');
297
        $this->assertEquals(
298
            [
299
                'query_type' => 'select',
300
                'result' => [
301
                    'variables' => [
302
                        's', 'o',
303
                    ],
304
                    'rows' => [
305
                        [
306
                            's' => 'http://s',
307
                            's type' => 'uri',
308
                            'o' => '3',
309
                            'o type' => 'literal',
310
                            'o datatype' => 'http://www.w3.org/2001/XMLSchema#integer',
311
                        ],
312
                    ],
313
                ],
314
            ],
315
            $res
316
        );
317
    }
318
319
    // isBlank
320
    public function testSelectFilterIsBlankFound()
321
    {
322
        // test data
323
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
324
            <http://s> <http://p1> _:foo .
325
        }');
326
327
        $res = $this->subjectUnderTest->query('
328
            SELECT ?s ?o WHERE {
329
                ?s <http://p1> ?o .
330
                FILTER (isBlank(?o))
331
            }
332
        ');
333
        $this->assertEquals(
334
            [
335
                'query_type' => 'select',
336
                'result' => [
337
                    'variables' => [
338
                        's', 'o',
339
                    ],
340
                    'rows' => [
341
                        [
342
                            's' => 'http://s',
343
                            's type' => 'uri',
344
                            'o' => $res['result']['rows'][0]['o'],
345
                            'o type' => 'bnode',
346
                        ],
347
                    ],
348
                ],
349
            ],
350
            $res
351
        );
352
    }
353
354
    // isBlank
355
    public function testSelectFilterIsBlankNotFound()
356
    {
357
        // test data
358
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
359
            <http://s> <http://p1> <http://foo> .
360
        }');
361
362
        $res = $this->subjectUnderTest->query('
363
            SELECT ?s ?o WHERE {
364
                ?s <http://p1> ?o .
365
                FILTER (isBlank(?o))
366
            }
367
        ');
368
        $this->assertEquals(
369
            [
370
                'query_type' => 'select',
371
                'result' => [
372
                    'variables' => [
373
                        's', 'o',
374
                    ],
375
                    'rows' => [],
376
                ],
377
            ],
378
            $res
379
        );
380
    }
381
382
    // isIri
383
    public function testSelectFilterIsIriFound()
384
    {
385
        // test data
386
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
387
            <http://s> <http://p1> <urn:id> .
388
        }');
389
390
        $res = $this->subjectUnderTest->query('
391
            SELECT ?s ?o WHERE {
392
                ?s <http://p1> ?o .
393
                FILTER (isIri(?o))
394
            }
395
        ');
396
        $this->assertEquals(
397
            [
398
                'query_type' => 'select',
399
                'result' => [
400
                    'variables' => [
401
                        's', 'o',
402
                    ],
403
                    'rows' => [
404
                        [
405
                            's' => 'http://s',
406
                            's type' => 'uri',
407
                            'o' => 'urn:id',
408
                            'o type' => 'uri',
409
                        ],
410
                    ],
411
                ],
412
            ],
413
            $res
414
        );
415
    }
416
417
    // isIri
418
    public function testSelectFilterIsIriNotFound()
419
    {
420
        // test data
421
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
422
            <http://s> <http://p1> "foo" .
423
        }');
424
425
        $res = $this->subjectUnderTest->query('
426
            SELECT ?s ?o WHERE {
427
                ?s <http://p1> ?o .
428
                FILTER (isIri(?o))
429
            }
430
        ');
431
        $this->assertEquals(
432
            [
433
                'query_type' => 'select',
434
                'result' => [
435
                    'variables' => [
436
                        's', 'o',
437
                    ],
438
                    'rows' => [],
439
                ],
440
            ],
441
            $res
442
        );
443
    }
444
445
    // isLiteral
446
    public function testSelectFilterIsLiteralFound()
447
    {
448
        // test data
449
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
450
            <http://s> <http://p1> "foo" .
451
        }');
452
453
        $res = $this->subjectUnderTest->query('
454
            SELECT ?s ?o WHERE {
455
                ?s <http://p1> ?o .
456
                FILTER (isLiteral(?o))
457
            }
458
        ');
459
        $this->assertEquals(
460
            [
461
                'query_type' => 'select',
462
                'result' => [
463
                    'variables' => [
464
                        's', 'o',
465
                    ],
466
                    'rows' => [
467
                        [
468
                            's' => 'http://s',
469
                            's type' => 'uri',
470
                            'o' => 'foo',
471
                            'o type' => 'literal',
472
                        ],
473
                    ],
474
                ],
475
            ],
476
            $res
477
        );
478
    }
479
480
    // isLiteral
481
    public function testSelectFilterIsLiteralNotFound()
482
    {
483
        // test data
484
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
485
            <http://s> <http://p1> <http://foo> .
486
        }');
487
488
        $res = $this->subjectUnderTest->query('
489
            SELECT ?s ?o WHERE {
490
                ?s <http://p1> ?o .
491
                FILTER (isLiteral(?o))
492
            }
493
        ');
494
        $this->assertEquals(
495
            [
496
                'query_type' => 'select',
497
                'result' => [
498
                    'variables' => [
499
                        's', 'o',
500
                    ],
501
                    'rows' => [],
502
                ],
503
            ],
504
            $res
505
        );
506
    }
507
508
    // isUri
509
    public function testSelectFilterIsUriFound()
510
    {
511
        // test data
512
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
513
            <http://s> <http://p1> <urn:id> .
514
        }');
515
516
        $res = $this->subjectUnderTest->query('
517
            SELECT ?s ?o WHERE {
518
                ?s <http://p1> ?o .
519
                FILTER (isUri(?o))
520
            }
521
        ');
522
        $this->assertEquals(
523
            [
524
                'query_type' => 'select',
525
                'result' => [
526
                    'variables' => [
527
                        's', 'o',
528
                    ],
529
                    'rows' => [
530
                        [
531
                            's' => 'http://s',
532
                            's type' => 'uri',
533
                            'o' => 'urn:id',
534
                            'o type' => 'uri',
535
                        ],
536
                    ],
537
                ],
538
            ],
539
            $res
540
        );
541
    }
542
543
    // isUri
544
    public function testSelectFilterIsUriNotFound()
545
    {
546
        // test data
547
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
548
            <http://s> <http://p1> "foo" .
549
        }');
550
551
        $res = $this->subjectUnderTest->query('
552
            SELECT ?s ?o WHERE {
553
                ?s <http://p1> ?o .
554
                FILTER (isUri(?o))
555
            }
556
        ');
557
        $this->assertEquals(
558
            [
559
                'query_type' => 'select',
560
                'result' => [
561
                    'variables' => [
562
                        's', 'o',
563
                    ],
564
                    'rows' => [],
565
                ],
566
            ],
567
            $res
568
        );
569
    }
570
571
    // lang: test behavior when using a language
572
    public function testSelectFilterLang()
573
    {
574
        // test data
575
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
576
            <http://s> <http://p1> "foo" .
577
            <http://s> <http://p1> "in de"@de .
578
            <http://s> <http://p1> "in en"@en .
579
        }');
580
581
        $res = $this->subjectUnderTest->query('
582
            SELECT ?s ?o WHERE {
583
                ?s <http://p1> ?o .
584
                FILTER (lang(?o) = "en")
585
            }
586
        ');
587
        $this->assertEquals(
588
            [
589
                'query_type' => 'select',
590
                'result' => [
591
                    'variables' => [
592
                        's', 'o',
593
                    ],
594
                    'rows' => [
595
                        [
596
                            's' => 'http://s',
597
                            's type' => 'uri',
598
                            'o' => 'in en',
599
                            'o type' => 'literal',
600
                            'o lang' => 'en',
601
                        ],
602
                    ],
603
                ],
604
            ],
605
            $res
606
        );
607
    }
608
609
    // langMatches
610
    public function testSelectFilterLangMatches()
611
    {
612
        // test data
613
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
614
            <http://s> <http://p1> "foo" .
615
            <http://s> <http://p1> "in de"@de .
616
            <http://s> <http://p1> "in en"@en .
617
        }');
618
619
        $res = $this->subjectUnderTest->query('
620
            SELECT ?s ?o WHERE {
621
                ?s <http://p1> ?o .
622
                FILTER langMatches (lang(?o), "en")
623
            }
624
        ');
625
        $this->assertEquals(
626
            [
627
                'query_type' => 'select',
628
                'result' => [
629
                    'variables' => [
630
                        's', 'o',
631
                    ],
632
                    'rows' => [
633
                        [
634
                            's' => 'http://s',
635
                            's type' => 'uri',
636
                            'o' => 'in en',
637
                            'o type' => 'literal',
638
                            'o lang' => 'en',
639
                        ],
640
                    ],
641
                ],
642
            ],
643
            $res
644
        );
645
    }
646
647
    // regex
648
    public function testSelectFilterRegex()
649
    {
650
        // test data
651
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
652
            <http://s> <http://p1> "Alice".
653
            <http://s2> <http://p1> "Bob" .
654
        }');
655
656
        $res = $this->subjectUnderTest->query('
657
            SELECT ?s ?o WHERE {
658
                ?s <http://p1> ?o .
659
                FILTER regex (?o, "^Ali")
660
            }
661
        ');
662
        $this->assertEquals(
663
            [
664
                'query_type' => 'select',
665
                'result' => [
666
                    'variables' => [
667
                        's', 'o',
668
                    ],
669
                    'rows' => [
670
                        [
671
                            's' => 'http://s',
672
                            's type' => 'uri',
673
                            'o' => 'Alice',
674
                            'o type' => 'literal',
675
                        ],
676
                    ],
677
                ],
678
            ],
679
            $res
680
        );
681
    }
682
683
    // regex
684
    public function testSelectFilterRegexWithModifier()
685
    {
686
        // test data
687
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
688
            <http://s> <http://p1> "Alice".
689
            <http://s2> <http://p1> "Bob" .
690
        }');
691
692
        $res = $this->subjectUnderTest->query('
693
            SELECT ?s ?o WHERE {
694
                ?s <http://p1> ?o .
695
                FILTER regex (?o, "^ali", "i")
696
            }
697
        ');
698
        $this->assertEquals(
699
            [
700
                'query_type' => 'select',
701
                'result' => [
702
                    'variables' => [
703
                        's', 'o',
704
                    ],
705
                    'rows' => [
706
                        [
707
                            's' => 'http://s',
708
                            's type' => 'uri',
709
                            'o' => 'Alice',
710
                            'o type' => 'literal',
711
                        ],
712
                    ],
713
                ],
714
            ],
715
            $res
716
        );
717
    }
718
719
    // str
720
    public function testSelectFilterStr()
721
    {
722
        // test data
723
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
724
            <http://s> <http://p1> "foo" .
725
            <http://s> <http://p1> "in de"@de .
726
            <http://s> <http://p1> "in en"@en .
727
        }');
728
729
        $res = $this->subjectUnderTest->query('
730
            SELECT ?s ?o WHERE {
731
                ?s <http://p1> ?o .
732
                FILTER (str(?o) = "in en")
733
            }
734
        ');
735
        $this->assertEquals(
736
            [
737
                'query_type' => 'select',
738
                'result' => [
739
                    'variables' => [
740
                        's', 'o',
741
                    ],
742
                    'rows' => [
743
                        [
744
                            's' => 'http://s',
745
                            's type' => 'uri',
746
                            'o' => 'in en',
747
                            'o type' => 'literal',
748
                            'o lang' => 'en',
749
                        ],
750
                    ],
751
                ],
752
            ],
753
            $res
754
        );
755
    }
756
757
    // str
758
    public function testSelectFilterStrNotFound()
759
    {
760
        // test data
761
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
762
            <http://s> <http://p1> "foo" .
763
            <http://s> <http://p1> "in de"@de .
764
            <http://s> <http://p1> "in en"@en .
765
        }');
766
767
        $res = $this->subjectUnderTest->query('
768
            SELECT ?s ?o WHERE {
769
                ?s <http://p1> ?o .
770
                FILTER (str(?o) = "in it")
771
            }
772
        ');
773
        $this->assertEquals(
774
            [
775
                'query_type' => 'select',
776
                'result' => [
777
                    'variables' => [
778
                        's', 'o',
779
                    ],
780
                    'rows' => [],
781
                ],
782
            ],
783
            $res
784
        );
785
    }
786
787
    // >
788
    public function testSelectFilterRelationalGreaterThan()
789
    {
790
        // test data
791
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
792
            <http://container1> <http://weight> "150" .
793
            <http://container2> <http://weight> "50" .
794
        }');
795
796
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
797
            ?c <http://weight> ?w .
798
799
            FILTER (?w > 100)
800
        }');
801
        $this->assertEquals(
802
            [
803
                'query_type' => 'select',
804
                'result' => [
805
                    'variables' => [
806
                        'c',
807
                    ],
808
                    'rows' => [
809
                        [
810
                            'c' => 'http://container1',
811
                            'c type' => 'uri',
812
                        ],
813
                    ],
814
                ],
815
            ],
816
            $res
817
        );
818
    }
819
820
    // <
821
    public function testSelectFilterRelationalSmallerThan()
822
    {
823
        // test data
824
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
825
            <http://container1> <http://weight> "150" .
826
            <http://container2> <http://weight> "50" .
827
        }');
828
829
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
830
            ?c <http://weight> ?w .
831
832
            FILTER (?w < 100)
833
        }');
834
        $this->assertEquals(
835
            [
836
                'query_type' => 'select',
837
                'result' => [
838
                    'variables' => [
839
                        'c',
840
                    ],
841
                    'rows' => [
842
                        [
843
                            'c' => 'http://container2',
844
                            'c type' => 'uri',
845
                        ],
846
                    ],
847
                ],
848
            ],
849
            $res
850
        );
851
    }
852
853
    // <
854
    public function testSelectFilterRelationalSmallerThan2()
855
    {
856
        // test data
857
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
858
            <http://container1> <http://weight> "150" .
859
            <http://container2> <http://weight> "50" .
860
        }');
861
862
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
863
            ?c <http://weight> ?w .
864
865
            FILTER (?w < 100 && ?w > 10)
866
        }');
867
        $this->assertEquals(
868
            [
869
                [
870
                    'c' => 'http://container2',
871
                    'c type' => 'uri',
872
                ],
873
            ],
874
            $res['result']['rows']
875
        );
876
    }
877
878
    // =
879
    public function testSelectFilterRelationalEqual()
880
    {
881
        // test data
882
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
883
            <http://container1> <http://weight> "150" .
884
            <http://container2> <http://weight> "50" .
885
        }');
886
887
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
888
            ?c <http://weight> ?w .
889
890
            FILTER (?w = 150)
891
        }');
892
        $this->assertEquals(
893
            [
894
                'query_type' => 'select',
895
                'result' => [
896
                    'variables' => [
897
                        'c',
898
                    ],
899
                    'rows' => [
900
                        [
901
                            'c' => 'http://container1',
902
                            'c type' => 'uri',
903
                        ],
904
                    ],
905
                ],
906
            ],
907
            $res
908
        );
909
    }
910
911
    // !=
912
    public function testSelectFilterRelationalNotEqual()
913
    {
914
        // test data
915
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
916
            <http://container1> <http://weight> "150" .
917
            <http://container2> <http://weight> "50" .
918
        }');
919
920
        $res = $this->subjectUnderTest->query('SELECT ?c WHERE {
921
            ?c <http://weight> ?w .
922
923
            FILTER (?w != 150)
924
        }');
925
        $this->assertEquals(
926
            [
927
                'query_type' => 'select',
928
                'result' => [
929
                    'variables' => [
930
                        'c',
931
                    ],
932
                    'rows' => [
933
                        [
934
                            'c' => 'http://container2',
935
                            'c type' => 'uri',
936
                        ],
937
                    ],
938
                ],
939
            ],
940
            $res
941
        );
942
    }
943
944
    /*
945
     * SELECT COUNT
946
     */
947
948
    public function testSelectCount()
949
    {
950
        // test data
951
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
952
            <http://person1> <http://name> "baz" .
953
            <http://person2> <http://name> "baz" .
954
            <http://person3> <http://name> "baz" .
955
        }');
956
957
        $res = $this->subjectUnderTest->query('
958
            SELECT COUNT(?s) AS ?count WHERE {
959
                ?s <http://name> "baz" .
960
            }
961
            ORDER BY DESC(?count)
962
        ');
963
        $this->assertEquals(
964
            [
965
                'query_type' => 'select',
966
                'result' => [
967
                    'variables' => [
968
                        'count',
969
                    ],
970
                    'rows' => [
971
                        [
972
                            'count' => '3',
973
                            'count type' => 'literal',
974
                        ],
975
                    ],
976
                ],
977
            ],
978
            $res
979
        );
980
    }
981
982
    /*
983
     * GROUP BY
984
     */
985
986
    public function testSelectGroupBy()
987
    {
988
        $query = 'SELECT ?who COUNT(?person) as ?persons WHERE {
989
                ?who <http://knows> ?person .
990
            }
991
            GROUP BY ?who
992
        ';
993
994
        // test data
995
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
996
            <http://person1> <http://knows> <http://person2>, <http://person3> .
997
            <http://person2> <http://knows> <http://person3> .
998
        }');
999
1000
        $res = $this->subjectUnderTest->query($query);
1001
        $this->assertEquals(
1002
            [
1003
                'query_type' => 'select',
1004
                'result' => [
1005
                    'variables' => [
1006
                        'who',
1007
                        'persons',
1008
                    ],
1009
                    'rows' => [
1010
                        [
1011
                            'who' => 'http://person1',
1012
                            'who type' => 'uri',
1013
                            'persons' => '2',
1014
                            'persons type' => 'literal',
1015
                        ],
1016
                        [
1017
                            'who' => 'http://person2',
1018
                            'who type' => 'uri',
1019
                            'persons' => '1',
1020
                            'persons type' => 'literal',
1021
                        ],
1022
                    ],
1023
                ],
1024
            ],
1025
            $res
1026
        );
1027
    }
1028
1029
    /*
1030
     * OFFSET and LIMIT
1031
     */
1032
1033
    public function testSelectOffset()
1034
    {
1035
        // test data
1036
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1037
            <http://person1> <http://id> "1" .
1038
            <http://person3> <http://id> "3" .
1039
            <http://person2> <http://id> "2" .
1040
        }');
1041
1042
        $res = $this->subjectUnderTest->query('
1043
            SELECT * WHERE { ?s ?p ?o . }
1044
            OFFSET 1
1045
        ');
1046
1047
        $this->assertEquals(
1048
            [
1049
                'query_type' => 'select',
1050
                'result' => [
1051
                    'variables' => [
1052
                        's', 'p', 'o',
1053
                    ],
1054
                    'rows' => [
1055
                        [
1056
                            's' => 'http://person3',
1057
                            's type' => 'uri',
1058
                            'p' => 'http://id',
1059
                            'p type' => 'uri',
1060
                            'o' => '3',
1061
                            'o type' => 'literal',
1062
                        ],
1063
                        [
1064
                            's' => 'http://person2',
1065
                            's type' => 'uri',
1066
                            'p' => 'http://id',
1067
                            'p type' => 'uri',
1068
                            'o' => '2',
1069
                            'o type' => 'literal',
1070
                        ],
1071
                    ],
1072
                ],
1073
            ],
1074
            $res
1075
        );
1076
    }
1077
1078
    public function testSelectOffsetLimit()
1079
    {
1080
        // test data
1081
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1082
            <http://person1> <http://id> "1" .
1083
            <http://person3> <http://id> "3" .
1084
            <http://person2> <http://id> "2" .
1085
        }');
1086
1087
        $res = $this->subjectUnderTest->query('
1088
            SELECT * WHERE { ?s ?p ?o . }
1089
            OFFSET 1 LIMIT 2
1090
        ');
1091
1092
        $this->assertEquals(
1093
            [
1094
                'query_type' => 'select',
1095
                'result' => [
1096
                    'variables' => [
1097
                        's', 'p', 'o',
1098
                    ],
1099
                    'rows' => [
1100
                        [
1101
                            's' => 'http://person3',
1102
                            's type' => 'uri',
1103
                            'p' => 'http://id',
1104
                            'p type' => 'uri',
1105
                            'o' => '3',
1106
                            'o type' => 'literal',
1107
                        ],
1108
                        [
1109
                            's' => 'http://person2',
1110
                            's type' => 'uri',
1111
                            'p' => 'http://id',
1112
                            'p type' => 'uri',
1113
                            'o' => '2',
1114
                            'o type' => 'literal',
1115
                        ],
1116
                    ],
1117
                ],
1118
            ],
1119
            $res
1120
        );
1121
    }
1122
1123
    public function testSelectLimit()
1124
    {
1125
        // test data
1126
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1127
            <http://person1> <http://id> "1" .
1128
            <http://person3> <http://id> "3" .
1129
            <http://person2> <http://id> "2" .
1130
        }');
1131
1132
        $res = $this->subjectUnderTest->query('
1133
            SELECT * WHERE { ?s ?p ?o . }
1134
            LIMIT 2
1135
        ');
1136
1137
        $this->assertEquals(
1138
            [
1139
                'query_type' => 'select',
1140
                'result' => [
1141
                    'variables' => [
1142
                        's', 'p', 'o',
1143
                    ],
1144
                    'rows' => [
1145
                        [
1146
                            's' => 'http://person1',
1147
                            's type' => 'uri',
1148
                            'p' => 'http://id',
1149
                            'p type' => 'uri',
1150
                            'o' => '1',
1151
                            'o type' => 'literal',
1152
                        ],
1153
                        [
1154
                            's' => 'http://person3',
1155
                            's type' => 'uri',
1156
                            'p' => 'http://id',
1157
                            'p type' => 'uri',
1158
                            'o' => '3',
1159
                            'o type' => 'literal',
1160
                        ],
1161
                    ],
1162
                ],
1163
            ],
1164
            $res
1165
        );
1166
    }
1167
1168
    /*
1169
     * ORDER BY
1170
     */
1171
1172
    public function testSelectOrderByAsc()
1173
    {
1174
        // test data
1175
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1176
            <http://person1> <http://id> "1" .
1177
            <http://person3> <http://id> "3" .
1178
            <http://person2> <http://id> "2" .
1179
        }');
1180
1181
        $res = $this->subjectUnderTest->query('
1182
            SELECT * WHERE {
1183
                ?s <http://id> ?id .
1184
            }
1185
            ORDER BY ASC(?id)
1186
        ');
1187
        $this->assertEquals(
1188
            [
1189
                'query_type' => 'select',
1190
                'result' => [
1191
                    'variables' => [
1192
                        's',
1193
                        'id',
1194
                    ],
1195
                    'rows' => [
1196
                        [
1197
                            's' => 'http://person1',
1198
                            's type' => 'uri',
1199
                            'id' => '1',
1200
                            'id type' => 'literal',
1201
                        ],
1202
                        [
1203
                            's' => 'http://person2',
1204
                            's type' => 'uri',
1205
                            'id' => '2',
1206
                            'id type' => 'literal',
1207
                        ],
1208
                        [
1209
                            's' => 'http://person3',
1210
                            's type' => 'uri',
1211
                            'id' => '3',
1212
                            'id type' => 'literal',
1213
                        ],
1214
                    ],
1215
                ],
1216
            ],
1217
            $res
1218
        );
1219
    }
1220
1221
    public function testSelectOrderByDesc()
1222
    {
1223
        // test data
1224
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1225
            <http://person1> <http://id> "1" .
1226
            <http://person3> <http://id> "3" .
1227
            <http://person2> <http://id> "2" .
1228
        }');
1229
1230
        $res = $this->subjectUnderTest->query('
1231
            SELECT * WHERE {
1232
                ?s <http://id> ?id .
1233
            }
1234
            ORDER BY DESC(?id)
1235
        ');
1236
        $this->assertEquals(
1237
            [
1238
                'query_type' => 'select',
1239
                'result' => [
1240
                    'variables' => [
1241
                        's',
1242
                        'id',
1243
                    ],
1244
                    'rows' => [
1245
                        [
1246
                            's' => 'http://person3',
1247
                            's type' => 'uri',
1248
                            'id' => '3',
1249
                            'id type' => 'literal',
1250
                        ],
1251
                        [
1252
                            's' => 'http://person2',
1253
                            's type' => 'uri',
1254
                            'id' => '2',
1255
                            'id type' => 'literal',
1256
                        ],
1257
                        [
1258
                            's' => 'http://person1',
1259
                            's type' => 'uri',
1260
                            'id' => '1',
1261
                            'id type' => 'literal',
1262
                        ],
1263
                    ],
1264
                ],
1265
            ],
1266
            $res
1267
        );
1268
    }
1269
1270
    public function testSelectOrderByWithoutContent()
1271
    {
1272
        $this->expectException(Exception::class);
1273
1274
        $this->subjectUnderTest->query('
1275
            SELECT * WHERE {
1276
                ?s <http://id> ?id .
1277
            }
1278
            ORDER BY
1279
        ');
1280
    }
1281
1282
    /*
1283
     * PREFIX
1284
     */
1285
1286
    public function testSelectPrefix()
1287
    {
1288
        // test data
1289
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1290
            <http://person1> <http://example.com/kennt> <http://person2> .
1291
        }');
1292
1293
        $res = $this->subjectUnderTest->query('
1294
            PREFIX ex: <http://example.com/>
1295
            SELECT * WHERE {
1296
                ?s ex:kennt ?o
1297
            }
1298
        ');
1299
1300
        $this->assertEquals(
1301
            [
1302
                'query_type' => 'select',
1303
                'result' => [
1304
                    'variables' => [
1305
                        's', 'o',
1306
                    ],
1307
                    'rows' => [
1308
                        [
1309
                            's' => 'http://person1',
1310
                            's type' => 'uri',
1311
                            'o' => 'http://person2',
1312
                            'o type' => 'uri',
1313
                        ],
1314
                    ],
1315
                ],
1316
            ],
1317
            $res
1318
        );
1319
    }
1320
1321
    /*
1322
     * UNION
1323
     */
1324
1325
    public function testSelectUnion()
1326
    {
1327
        // test data
1328
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1329
            <http://person1> <http://id> "1" .
1330
            <http://person3> <http://id> "3" .
1331
            <http://person2> <http://id> "2" .
1332
        }');
1333
1334
        $res = $this->subjectUnderTest->query('
1335
            SELECT * WHERE {
1336
                {
1337
                    ?p <http://id> "1" .
1338
                } UNION {
1339
                    ?p <http://id> "3" .
1340
                }
1341
            }
1342
        ');
1343
1344
        $this->assertEquals(
1345
            [
1346
                'query_type' => 'select',
1347
                'result' => [
1348
                    'variables' => [
1349
                        'p',
1350
                    ],
1351
                    'rows' => [
1352
                        [
1353
                            'p' => 'http://person1',
1354
                            'p type' => 'uri',
1355
                        ],
1356
                        [
1357
                            'p' => 'http://person3',
1358
                            'p type' => 'uri',
1359
                        ],
1360
                    ],
1361
                ],
1362
            ],
1363
            $res
1364
        );
1365
    }
1366
1367
    /*
1368
     * Tests using certain queries with SELECT FROM WHERE and not just SELECT WHERE
1369
     */
1370
1371
    public function testSelectOrderByAscWithFromClause()
1372
    {
1373
        // test data
1374
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1375
            <http://person1> <http://id> "1" .
1376
            <http://person3> <http://id> "3" .
1377
            <http://person2> <http://id> "2" .
1378
        }');
1379
1380
        $res = $this->subjectUnderTest->query('
1381
            SELECT * FROM <http://example.com/> WHERE {
1382
                ?s <http://id> ?id .
1383
            }
1384
            ORDER BY ASC(?id)
1385
        ');
1386
        $this->assertEquals(
1387
            [
1388
                'query_type' => 'select',
1389
                'result' => [
1390
                    'variables' => [
1391
                        's',
1392
                        'id',
1393
                    ],
1394
                    'rows' => [
1395
                        [
1396
                            's' => 'http://person1',
1397
                            's type' => 'uri',
1398
                            'id' => '1',
1399
                            'id type' => 'literal',
1400
                        ],
1401
                        [
1402
                            's' => 'http://person2',
1403
                            's type' => 'uri',
1404
                            'id' => '2',
1405
                            'id type' => 'literal',
1406
                        ],
1407
                        [
1408
                            's' => 'http://person3',
1409
                            's type' => 'uri',
1410
                            'id' => '3',
1411
                            'id type' => 'literal',
1412
                        ],
1413
                    ],
1414
                ],
1415
            ],
1416
            $res
1417
        );
1418
    }
1419
1420
    /**
1421
     * Select Distinct
1422
     *
1423
     * @see https://www.w3.org/TR/rdf-sparql-query/#modDistinct
1424
     */
1425
    public function testSelectDistinct()
1426
    {
1427
        // test data
1428
        $this->subjectUnderTest->query('INSERT INTO <http://example.com/> {
1429
            <http://person1> <http://example.com/kennt> "Test" .
1430
            <http://person2> <http://example.com/kennt> "Test" .
1431
            <http://person3> <http://example.com/kennt> "Test" .
1432
            <http://person4> <http://example.com/kennt> "Test2" .
1433
        }');
1434
1435
        $res = $this->subjectUnderTest->query('
1436
            PREFIX ex: <http://example.com/>
1437
            SELECT DISTINCT ?name WHERE {
1438
                ?s ex:kennt ?name
1439
            }
1440
        ');
1441
1442
        $this->assertEquals(
1443
            [
1444
                ['name' => 'Test', 'name type' => 'literal'],
1445
                ['name' => 'Test2', 'name type' => 'literal'],
1446
            ],
1447
            $res['result']['rows']
1448
        );
1449
    }
1450
}
1451