File Coverage

blib/lib/Test/RDF/Trine/Store.pm
Criterion Covered Total %
statement 556 562 98.9
branch 22 38 57.8
condition 2 4 50.0
subroutine 36 36 100.0
pod 21 21 100.0
total 637 661 96.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Test::RDF::Trine::Store - A collection of functions to test RDF::Trine::Stores
4              
5             =head1 VERSION
6              
7             This document describes RDF::Trine version 1.017
8              
9             =head1 SYNOPSIS
10              
11             For example, to test a Memory store, do something like:
12              
13             use Test::RDF::Trine::Store qw(all_store_tests number_of_tests);
14             use Test::More tests => 1 + Test::RDF::Trine::Store::number_of_tests;
15              
16             use RDF::Trine qw(iri variable store literal);
17             use RDF::Trine::Store;
18              
19             my $data = Test::RDF::Trine::Store::create_data;
20              
21             my $store = RDF::Trine::Store::Memory->temporary_store();
22             isa_ok( $store, 'RDF::Trine::Store::Memory' );
23             Test::RDF::Trine::Store::all_store_tests($store, $data);
24              
25              
26              
27             =head1 DESCRIPTION
28              
29             This module packages a few functions that you can call to test a
30             L<RDF::Trine::Store>, also if it is outside of the main RDF-Trine
31             distribution.
32              
33             There are different functions that will test different parts of the
34             functionality, but you should run them all at some point, thus for the
35             most part, you would just like to run the C<all_store_tests> function
36             for quad stores and C<all_triple_store_tests> for triple stores
37             (i.e. stores that doesn't support named graphs).
38              
39             All the below functions are exported.
40              
41              
42             =cut
43              
44             package Test::RDF::Trine::Store;
45              
46 7     7   28583 use Test::More;
  7         78850  
  7         51  
47 7     7   4285 use Test::Exception;
  7         16136  
  7         28  
48              
49 7     7   1289 use strict;
  7         15  
  7         104  
50 7     7   30 use warnings;
  7         15  
  7         138  
51 7     7   32 no warnings 'redefine';
  7         11  
  7         181  
52              
53 7     7   1357 use RDF::Trine qw(iri variable store literal statement);
  7         23  
  7         426  
54 7     7   47 use RDF::Trine::Node;
  7         16  
  7         236  
55 7     7   39 use RDF::Trine::Statement;
  7         18  
  7         132  
56 7     7   35 use RDF::Trine::Store::DBI;
  7         16  
  7         184  
57 7     7   42 use RDF::Trine::Namespace qw(xsd);
  7         18  
  7         55  
58              
59             our ($VERSION);
60             BEGIN {
61 7     7   452 $VERSION = '1.017';
62             }
63              
64 7     7   51 use Log::Log4perl;
  7         19  
  7         47  
65              
66             Log::Log4perl->easy_init if $ENV{TEST_VERBOSE};
67              
68             our @EXPORT = qw(number_of_tests number_of_triple_tests create_data all_store_tests all_triple_store_tests add_quads add_triples contexts_tests add_statement_tests_simple count_statements_tests_simple count_statements_tests_quads count_statements_tests_triples get_statements_tests_triples get_pattern_tests get_statements_tests_quads remove_statement_tests);
69              
70              
71              
72             =head1 FUNCTIONS
73              
74             =over 4
75              
76             =item C<< number_of_tests >>
77              
78             Returns the number of tests run with C<all_store_tests>.
79              
80             =cut
81              
82             sub number_of_tests {
83 4     4 1 162 return 231; # Remember to update whenever adding tests
84             }
85              
86             =item C<< number_of_triple_tests >>
87              
88             Returns the number of tests run with C<all_triple_store_tests>.
89              
90             =cut
91              
92             sub number_of_triple_tests {
93 1     1 1 64 return 71; # Remember to update whenever adding tests
94             }
95              
96              
97             =item C<< create_data >>
98              
99             Returns a hashref with generated test data nodes to be used by other
100             tests.
101              
102             =cut
103              
104              
105             sub create_data {
106 4     4 1 62 my $ex = RDF::Trine::Namespace->new('http://example.com/');
107 4         59 my @names = ('a' .. 'z');
108 4         12 my @triples;
109             my @quads;
110 4         38 my $nil = RDF::Trine::Node::Nil->new();
111 4         20 foreach my $i (@names[0..2]) {
112 12         70 my $w = $ex->$i();
113 12         33 foreach my $j (@names[0..2]) {
114 36         143 my $x = $ex->$j();
115 36         86 foreach my $k (@names[0..2]) {
116 108         388 my $y = $ex->$k();
117 108         332 my $triple = RDF::Trine::Statement->new($w,$x,$y);
118 108         199 push(@triples, $triple);
119 108         204 foreach my $l (@names[0..2]) {
120 324         1197 my $z = $ex->$l();
121 324         896 my $quad = RDF::Trine::Statement::Quad->new($w,$x,$y,$z);
122 324         674 push(@quads, $quad);
123             }
124             }
125             }
126             }
127 4         35 return { ex => $ex, names => \@names, triples => \@triples, quads => \@quads, nil => $nil };
128             }
129              
130             =item C<< all_store_tests ($store, $data, $todo, $args) >>
131              
132             Will run all available tests for the given store, given the data from
133             C<create_data>. You may also set a third argument to some true value
134             to mark all tests as TODO in case the store is in development.
135              
136             Finally, an C<$args> hashref can be passed. Valid keys are
137             C<update_sleep> (see the function with the same name below) and
138             C<suppress_dupe_tests> if the store should skip duplicate detection,
139             C<quads_unsupported> if the store is a triple store.
140              
141             =cut
142              
143             sub all_store_tests {
144 3     3 1 1716 my ($store, $data, $todo, $args) = @_;
145 3   50     28 $args ||= {};
146            
147 3         9 my $ex = $data->{ex};
148 3         8 my @names = @{$data->{names}};
  3         32  
149 3         8 my @triples = @{$data->{triples}};
  3         24  
150 3         9 my @quads = @{$data->{quads}};
  3         36  
151 3         9 my $nil = $data->{nil};
152              
153 3         22 note "## Testing store " . ref($store);
154 3         324 isa_ok( $store, 'RDF::Trine::Store' );
155              
156             TODO: {
157 3 50       1140 local $TODO = ($todo) ? ref($store) . ' functionality is being worked on' : undef;
  3         14  
158            
159             throws_ok {
160 3     3   161 my $st = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $ex->c, $ex->d);
161 3         26 $store->add_statement( $st, $ex->e );
162 3         32 } 'RDF::Trine::Error::MethodInvocationError', 'add_statement throws when called with quad and context';
163            
164            
165             throws_ok {
166 3     3   123 my $st = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $ex->c, $ex->d);
167 3         18 $store->remove_statement( $st, $ex->e );
168 3         1262 } 'RDF::Trine::Error::MethodInvocationError', 'remove_statement throws when called with quad and context';
169            
170 3         1122 add_statement_tests_simple( $store, $args, $ex );
171 3         15 update_sleep($args);
172            
173 3         17 bulk_add_statement_tests_simple( $store, $args, $ex );
174 3         15 update_sleep($args);
175            
176 3         15 literals_tests_simple( $store, $args, $ex );
177 3         17 blank_node_tests_quads( $store, $args, $ex );
178 3         22 count_statements_tests_simple( $store, $args, $ex );
179            
180 3         1408 add_quads( $store, $args, @quads );
181 3         333 update_sleep($args);
182            
183 3         18 count_statements_tests_quads( $store, $args, $ex );
184            
185 3         1481 add_triples( $store, $args, @triples );
186 3         250 update_sleep($args);
187            
188 3         17 count_statements_tests_triples( $store, $args, $ex, $nil );
189 3         1459 contexts_tests( $store, $args );
190 3         2264 get_statements_tests_triples( $store, $args, $ex );
191 3         441 get_pattern_tests( $store, $args, $ex );
192 3         1331 get_statements_tests_quads( $store, $args, $ex, $nil );
193            
194 3         422 remove_statement_tests( $store, $args, $ex, @names );
195 3         1935 update_sleep($args);
196             }
197             }
198              
199             =item C<< all_triple_store_tests ($store, $data, $todo, $args) >>
200              
201             Will run tests for the given B<triple> store, i.e. a store that only
202             accepts triples, given the data from C<create_data>. You may also set
203             a third argument to some true value to mark all tests as TODO in case
204             the store is in development.
205              
206             For C<$args>, see above.
207              
208             =cut
209              
210             sub all_triple_store_tests {
211 1     1 1 516 my ($store, $data, $todo, $args) = @_;
212 1   50     8 $args ||= {};
213 1         3 $args->{quads_unsupported} = 1;
214 1         3 my $ex = $data->{ex};
215 1         2 my @names = @{$data->{names}};
  1         7  
216 1         4 my @triples = @{$data->{triples}};
  1         4  
217 1         3 my @quads = @{$data->{quads}};
  1         8  
218 1         3 my $nil = $data->{nil};
219              
220 1         7 note "## Testing store " . ref($store);
221 1         77 isa_ok( $store, 'RDF::Trine::Store' );
222              
223             TODO: {
224 1 50       344 local $TODO = ($todo) ? ref($store) . ' functionality is being worked on' : undef;
  1         4  
225            
226             lives_ok {
227 1     1   43 $store->get_contexts;
228 1         9 } 'get_context lives';
229            
230             # add_statement_tests_simple( $store, $args, $ex );
231             # update_sleep($args);
232             #
233             # bulk_add_statement_tests_simple( $store, $args, $ex );
234             # update_sleep($args);
235            
236 1         311 literals_tests_simple( $store, $args, $ex );
237 1         5 blank_node_tests_triples( $store, $args, $ex );
238             # count_statements_tests_simple( $store, $args, $ex );
239            
240 1         8 add_triples( $store, $args, @triples );
241 1         7 update_sleep($args);
242            
243             # count_statements_tests_triples( $store, $args, $ex, $nil );
244 1         6 get_statements_tests_triples( $store, $args, $ex );
245 1         6 get_pattern_tests( $store, $args, $ex );
246             }
247             }
248              
249             =item C<< add_quads($store, $args, @quads) >>
250              
251             Helper function to add an array of quads to the given store.
252              
253             =cut
254              
255              
256             sub add_quads {
257 3     3 1 36 my ($store, $args, @quads) = @_;
258 3         10 foreach my $q (@quads) {
259 243         23835 $store->add_statement( $q );
260             }
261             }
262              
263              
264             =item C<< add_triples($store, $args, @triples) >>
265              
266             Helper function to add an array of triples to the given store.
267              
268             =cut
269              
270             sub add_triples {
271 4     4 1 26 my ($store, $args, @triples) = @_;
272 4         18 foreach my $t (@triples) {
273 108         6755 $store->add_statement( $t );
274             }
275             }
276              
277             =item C<< contexts_tests( $store, $args ) >>
278              
279             Testing contexts (aka. "graphs")
280              
281             =cut
282              
283              
284             sub contexts_tests {
285 3     3 1 18 note "contexts tests";
286 3         518 my $store = shift;
287 3         11 my $args = shift;
288 3         33 my $iter = $store->get_contexts();
289 3         19 isa_ok( $iter, 'RDF::Trine::Iterator' );
290 3         1545 my %seen;
291 3         22 while (my $c = $iter->next) {
292 9         32 isa_ok( $c, 'RDF::Trine::Node' );
293 9         4072 $seen{ $c->as_string }++;
294             }
295 3         14 my $expect = {
296             '<http://example.com/a>' => 1,
297             '<http://example.com/b>' => 1,
298             '<http://example.com/c>' => 1,
299             };
300 3         19 is_deeply( \%seen, $expect, 'expected contexts' );
301             }
302              
303              
304             =item C<< add_statement_tests_simple( $store, $args, $data->{ex} ) >>
305              
306             Tests to check add_statement.
307              
308             =cut
309              
310              
311             sub add_statement_tests_simple {
312 3     3 1 20 note "simple add_statement tests";
313 3         659 my ($store, $args, $ex) = @_;
314            
315 3         31 my $triple = RDF::Trine::Statement->new($ex->a, $ex->b, $ex->c);
316 3         35 my $quad = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $ex->c, $ex->d);
317 3         39 my $etag_before = $store->etag;
318 3         21 update_sleep($args);
319 3         26 $store->add_statement( $triple, $ex->d );
320 3         316 update_sleep($args);
321             SKIP: {
322 3 100       9 skip 'It is OK to not support etag', 1 unless defined($etag_before);
  3         25  
323 1         7 isnt($etag_before, $store->etag, 'Etag has changed');
324             }
325              
326 3         1422 is( $store->size, 1, 'store has 1 statement after (triple+context) add' );
327            
328             TODO: {
329 3 50       1359 local $TODO = 'Duplicate detection is unsupported' if $args->{suppress_dupe_tests};
  3         15  
330 3         20 $store->add_statement( $quad );
331 3         19 update_sleep($args);
332 3         16 is( $store->size, 1, 'store has 1 statement after duplicate (quad) add' );
333             }
334            
335 3         1392 $etag_before = $store->etag;
336 3         33 $store->remove_statement( $triple, $ex->d );
337 3         333 update_sleep($args);
338             SKIP: {
339 3 100       6 skip 'It is OK to not support etag', 1 unless defined($etag_before);
  3         24  
340 1         4 isnt($etag_before, $store->etag, 'Etag has changed');
341             }
342              
343 3         1028 is( $store->size, 0, 'store has 0 statements after (triple+context) remove' );
344            
345 3         1388 my $quad2 = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $ex->c, iri('graph'));
346 3         23 $store->add_statement( $quad2 );
347 3         298 update_sleep($args);
348            
349 3         17 is( $store->size, 1, 'store has 1 statement after (quad) add' );
350            
351 3         1465 my $count = $store->count_statements( undef, undef, undef, iri('graph') );
352 3         26 is( $count, 1, 'expected count of specific-context statements' );
353            
354 3         1407 $store->remove_statement( $quad2 );
355 3         333 update_sleep($args);
356            
357 3         19 is( $store->size, 0, 'expected zero size after remove statement' );
358             }
359              
360              
361             =item C<< bulk_add_statement_tests_simple( $store, $args, $data->{ex} ) >>
362              
363             Tests to check add_statement.
364              
365             =cut
366              
367              
368             sub bulk_add_statement_tests_simple {
369 3     3 1 16 note "bulk add_statement tests";
370 3         403 my ($store, $args, $ex) = @_;
371              
372 3 50       49 $store->_begin_bulk_ops if ($store->can('_begin_bulk_ops'));
373 3         32 my $triple = RDF::Trine::Statement->new($ex->a, $ex->b, $ex->c);
374 3         20 my $quad = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $ex->c, $ex->d);
375 3         19 $store->add_statement( $triple, $ex->d );
376 3 50       350 $store->_end_bulk_ops if ($store->can('_end_bulk_ops'));
377            
378 3         17 update_sleep($args);
379            
380 3         19 is( $store->size, 1, 'store has 1 statement after (triple+context) add' ) ;
381            
382 3 50       1554 $store->_begin_bulk_ops if ($store->can('_begin_bulk_ops'));
383              
384             TODO: {
385 3 50       8 local $TODO = 'Duplicate detection is unsupported' if $args->{suppress_dupe_tests};
  3         15  
386 3         17 $store->add_statement( $quad );
387 3         20 update_sleep($args);
388 3         20 is( $store->size, 1, 'store has 1 statement after duplicate (quad) add' ) ;
389             }
390              
391 3 50       1518 $store->_end_bulk_ops if ($store->can('_end_bulk_ops'));
392            
393 3 50       33 $store->_begin_bulk_ops if ($store->can('_begin_bulk_ops'));
394 3         31 $store->remove_statement( $triple, $ex->d );
395 3         363 is( $store->size, 0, 'store has 0 statements after (triple+context) remove' );
396            
397 3         1561 my $quad2 = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $ex->c, iri('graph'));
398 3         21 $store->add_statement( $quad2 );
399 3 50       294 $store->_end_bulk_ops if ($store->can('_end_bulk_ops'));
400 3         18 update_sleep($args);
401            
402 3         18 is( $store->size, 1, 'store has 1 statement after (quad) add' );
403            
404 3         1499 my $count = $store->count_statements( undef, undef, undef, iri('graph') );
405 3         25 is( $count, 1, 'expected count of specific-context statements' );
406            
407 3         1243 $store->remove_statement( $quad2 );
408 3         328 update_sleep($args);
409            
410 3         19 is( $store->size, 0, 'expected zero size after remove statement' );
411             }
412              
413              
414             =item C<< literals_tests_simple( $store, $args, $data->{ex}) >>
415              
416             Tests to check literals support.
417              
418             =cut
419              
420             sub literals_tests_simple {
421 4     4 1 21 note "simple tests with literals";
422 4         466 my ($store, $args, $ex) = @_;
423            
424 4         51 my $litplain = RDF::Trine::Node::Literal->new('dahut');
425 4         17 my $litlang1 = RDF::Trine::Node::Literal->new('dahu', 'fr' );
426 4         17 my $litlang2 = RDF::Trine::Node::Literal->new('dahut', 'en' );
427 4         17 my $litutf8 = RDF::Trine::Node::Literal->new('blÃ¥bærsyltetøy', 'nb' );
428 4         68 my $litstring = RDF::Trine::Node::Literal->new('dahut', undef, $xsd->string);
429 4         18 my $litint = RDF::Trine::Node::Literal->new(42, undef, $xsd->integer);
430 4         15 my $triple = RDF::Trine::Statement->new($ex->a, $ex->b, $litplain);
431 4         24 my $quad = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $litplain, $ex->d);
432 4         24 $store->add_statement( $triple, $ex->d );
433 4         303 is( $store->size, 1, 'store has 1 statement after (triple+context) add' );
434             TODO: {
435 4 50       1796 local $TODO = 'Duplicate detection is unsupported' if $args->{suppress_dupe_tests};
  4         25  
436 4         26 $store->add_statement( $quad );
437 4         30 is( $store->size, 1, 'store has 1 statement after duplicate (quad) add' );
438             }
439 4         2151 $store->remove_statement( $triple, $ex->d );
440 4         352 is( $store->size, 0, 'store has 0 statements after (triple+context) remove' );
441              
442 4         1871 $store->add_statement( $quad );
443 4         336 my $quad2 = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $litlang2, $ex->d);
444 4         22 $store->add_statement( $quad2 );
445 4         318 is( $store->size, 2, 'store has 2 statements after (quad) add' );
446            
447             {
448 4         21 my $count = $store->count_statements( undef, undef, $litplain, undef );
449 4         31 is( $count, 1, 'expected 1 plain literal' );
450             }
451              
452             {
453 4         1838 my $iter = $store->get_statements( undef, undef, $litplain, undef );
  4         43  
454 4         32 isa_ok( $iter, 'RDF::Trine::Iterator' );
455 4         2233 my $st = $iter->next;
456 4         19 isa_ok( $st, 'RDF::Trine::Statement' );
457 4         1742 my $obj = $st->object;
458 4         19 isa_ok($obj, 'RDF::Trine::Node::Literal');
459 4         1801 is($obj->literal_value, 'dahut', 'expected triple get_statements bound object value' );
460             }
461              
462             {
463 4         1944 my $count = $store->count_statements( undef, undef, $litlang2, undef );
  4         25  
464 4         29 is( $count, 1, 'expected 1 language literal' );
465             }
466              
467             {
468 4         759 my $count = $store->count_statements( undef, undef, $litlang1, undef );
  4         1770  
  4         25  
469 4         22 is( $count, 0, 'expected 0 language literal' );
470             }
471              
472 4         1719 my $quad3 = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $litlang1, $ex->d);
473 4         25 $store->add_statement( $quad3 );
474 4         334 is( $store->size, 3, 'store has 3 statements after integer literal add' );
475              
476             {
477 4         2040 my $iter = $store->get_statements( undef, undef, $litlang1, undef );
  4         27  
478 4         22 my $st = $iter->next;
479 4         21 is($st->object->literal_value, 'dahu', 'expected triple get_statements bound object value' );
480 4         1690 is($st->object->literal_value_language, 'fr', 'expected triple get_statements bound object language' );
481 4         1560 is($st->object->literal_datatype, undef, 'expected triple get_statements bound object datatype is undef' );
482             }
483              
484              
485 4         866 my $triple2 = RDF::Trine::Statement->new($ex->a, $ex->b, $litstring);
486 4         26 $store->add_statement( $triple2 );
487 4         246 is( $store->size, 4, 'store has 4 statements after (triple) add' );
488              
489             {
490 4         25 my $count = $store->count_statements( undef, undef, $litplain, undef );
491 4         30 is( $count, 1, 'expected 1 plain literal' );
492             }
493             {
494 4         1884 my $count = $store->count_statements( undef, undef, $litstring, undef );
  4         25  
495 4         31 is( $count, 1, 'expected 1 string literal' );
496             }
497              
498             {
499 4         1685 my $iter = $store->get_statements( undef, undef, $litstring, undef );
  4         1773  
  4         25  
500 4         25 my $st = $iter->next;
501 4         22 is($st->object->literal_value, 'dahut', 'expected triple get_statements bound object value' );
502 4         1892 is($st->object->literal_value_language, undef, 'expected triple get_statements bound object language is undef' );
503 4         1550 is($st->object->literal_datatype, $xsd->string->value, 'expected triple get_statements bound object datatype is string' );
504             }
505              
506             SKIP: {
507 4 100       733 skip 'Quad-only test', 1 if $args->{quads_unsupported};
  4         25  
508 3         27 my $count = $store->count_statements( undef, undef, $litstring, $ex->d );
509 3         50 is( $count, 0, 'expected 0 string literal with context' );
510             }
511              
512 4         1756 $store->remove_statement($quad);
513 4         336 is( $store->size, 3, 'store has 3 statements after plain literal remove' );
514              
515 4         2369 my $quad4 = RDF::Trine::Statement::Quad->new($ex->a, $ex->b, $litint, $ex->d);
516 4         29 $store->add_statement( $quad4 );
517 4         307 is( $store->size, 4, 'store has 4 statements after integer literal add' );
518              
519             {
520 4         42 my $count = $store->count_statements( $ex->a, $ex->b, undef, undef);
521 4         73 is( $count, 4, 'expected 4 triples with all literals' );
522             }
523              
524             {
525 4         2014 my $count = $store->count_statements( $ex->a, $ex->b, $litint, undef );
  4         39  
526 4         61 is( $count, 1, 'expected 1 triple with integer literal' );
527             }
528              
529             {
530 4         1833 my $count = $store->count_statements( $ex->a, undef, $litlang1, undef );
  4         1975  
  4         38  
531 4         62 is( $count, 1, 'expected 1 triple with language literal' );
532             }
533              
534              
535 4         1967 $store->remove_statement($triple2);
536 4         274 is( $store->size, 3, 'store has 3 statements after string literal remove' );
537              
538 4         2030 $store->remove_statements(undef, undef, $litlang2, undef );
539 4         152 is( $store->size, 2, 'expected 2 statements after language remove statements' );
540              
541 4         1911 my $triple3 = RDF::Trine::Statement->new($ex->a, $ex->b, $litutf8);
542 4         28 $store->add_statement( $triple3 );
543 4         251 is( $store->size, 3, 'store has 3 statements after addition of literal with utf8 chars' );
544              
545             {
546 4         2105 my $iter = $store->get_statements( undef, undef, $litutf8, undef );
  4         26  
547 4         112 my $st = $iter->next;
548 4         30 isa_ok( $st, 'RDF::Trine::Statement' );
549 4         2280 is($st->object->literal_value, 'blÃ¥bærsyltetøy', 'expected triple get_statements bound object value with utf8 chars' );
550 4         1616 $store->remove_statement($st);
551 4         331 is( $store->size, 2, 'store has 2 statements after removal of literal with utf8 chars' );
552             }
553              
554              
555 4         882 $store->remove_statements($ex->a, $ex->b, undef, undef );
556 4         240 is( $store->size, 0, 'expected zero size after remove statements' );
557             }
558              
559              
560             =item C<< blank_node_tests_quads( $store, $args, $data->{ex} ) >>
561              
562             Tests to check blank node support for quads.
563              
564             =cut
565              
566              
567             sub blank_node_tests_quads {
568 3     3 1 20 note "quad tests with blank nodes";
569 3         517 my ($store, $args, $ex) = @_;
570            
571 3         31 my $blankfoo = RDF::Trine::Node::Blank->new('foo');
572 3         13 my $blankbar = RDF::Trine::Node::Blank->new('bar');
573 3         32 my $triple = RDF::Trine::Statement->new($blankfoo, $ex->b, $ex->c);
574 3         20 my $quad = RDF::Trine::Statement::Quad->new($blankfoo, $ex->b, $ex->c, $ex->d);
575 3         22 $store->add_statement( $triple, $ex->d );
576 3         298 is( $store->size, 1, 'store has 1 statement after (triple+context) add' );
577             TODO: {
578 3 50       1744 local $TODO = 'Duplicate detection is unsupported' if $args->{suppress_dupe_tests};
  3         19  
579 3         19 $store->add_statement( $quad );
580 3         23 is( $store->size, 1, 'store has 1 statement after duplicate (quad) add' );
581             }
582 3         1803 $store->remove_statement( $triple, $ex->d );
583 3         321 is( $store->size, 0, 'store has 0 statements after (triple+context) remove' );
584            
585 3         1714 my $quad2 = RDF::Trine::Statement::Quad->new($blankbar, $ex->b, $ex->c, $ex->d);
586 3         22 $store->add_statement( $quad2 );
587 3         301 is( $store->size, 1, 'store has 1 statement after (quad) add' );
588 3         1733 $store->add_statement( $quad );
589 3         307 is( $store->size, 2, 'store has 2 statements after (quad) add' );
590              
591 3         1675 my $triple2 = RDF::Trine::Statement->new($ex->a, $ex->b, $blankfoo);
592 3         21 $store->add_statement( $triple2 );
593 3         255 is( $store->size, 3, 'store has 3 statements after (quad) add' );
594              
595             {
596 3         39 my $count = $store->count_statements( undef, undef, undef, $ex->d );
597 3         26 is( $count, 2, 'expected count of specific-context statements' );
598             }
599              
600             {
601 3         1967 my $count = $store->count_statements( undef, undef, $blankfoo, $ex->d );
  3         31  
602 3         49 is( $count, 0, 'expected zero of specific-context statements' );
603             }
604              
605             {
606 3         1562 my $count = $store->count_statements( undef, undef, $blankfoo, undef );
  3         19  
607 3         28 is( $count, 1, 'expected one object blank node' );
608             }
609              
610             {
611 3         1537 my $count = $store->count_statements( $blankbar, undef, $blankfoo, undef );
  3         19  
612 3         53 is( $count, 0, 'expected zero subject-object blank node' );
613             }
614              
615             {
616 3         1521 my $count = $store->count_statements( $blankbar, undef, undef, undef );
  3         18  
617 3         29 is( $count, 1, 'expected one subject blank node' );
618             }
619              
620             {
621 3         1604 my $count = $store->count_statements( $blankfoo, undef, undef, $ex->d );
  3         42  
622 3         63 is( $count, 1, 'expected one subject-context blank node' );
623             }
624              
625             {
626 3         1835 my $count = $store->count_statements( $blankfoo, $ex->b, undef, undef );
  3         1944  
  3         36  
627 3         54 is( $count, 1, 'expected one subject-predicate blank node' );
628             }
629              
630 3         1476 $store->remove_statements( undef, undef, $blankfoo, undef );
631 3         182 is( $store->size, 2, 'expected two triples after remove statements' );
632            
633 3         1593 $store->remove_statement( $quad2 );
634 3         367 is( $store->size, 1, 'expected single triples after remove statement' );
635 3         1859 $store->remove_statement( $quad );
636 3         370 is( $store->size, 0, 'expected zero size after remove statement' );
637             }
638              
639             =item C<< blank_node_tests_triples( $store, $args, $data->{ex} ) >>
640              
641             Tests to check blank node support for triples.
642              
643             =cut
644              
645              
646             sub blank_node_tests_triples {
647 1     1 1 6 note "triple tests with blank nodes";
648 1         166 my ($store, $args, $ex) = @_;
649            
650 1         14 my $blankfoo = RDF::Trine::Node::Blank->new('foo');
651 1         4 my $blankbar = RDF::Trine::Node::Blank->new('bar');
652 1         9 my $triple = RDF::Trine::Statement->new($blankfoo, $ex->b, $ex->c);
653 1         6 my $triple2 = RDF::Trine::Statement->new($ex->c, $ex->d, $blankbar);
654 1         5 $store->add_statement( $triple );
655 1         6 is( $store->size, 1, 'store has 1 statement after (triple) add' );
656             TODO: {
657 1 50       418 local $TODO = 'Duplicate detection is unsupported' if $args->{suppress_dupe_tests};
  1         6  
658 1         5 $store->add_statement( $triple );
659 1         6 is( $store->size, 1, 'store has 1 statement after duplicate (triple) add' );
660             }
661 1         407 $store->remove_statement( $triple );
662 1         5 is( $store->size, 0, 'store has 0 statements after (triple) remove' );
663            
664 1         408 $store->add_statement( $triple2 );
665 1         5 is( $store->size, 1, 'store has 1 statement after (triple) add' );
666 1         408 $store->add_statement( $triple );
667 1         5 is( $store->size, 2, 'store has 2 statements after (triple) add' );
668              
669 1         421 my $triple3 = RDF::Trine::Statement->new($ex->a, $ex->b, $blankfoo);
670 1         6 $store->add_statement( $triple3 );
671 1         5 is( $store->size, 3, 'store has 3 statements after (triple) add' );
672              
673             {
674 1         6 my $count = $store->count_statements( undef, undef, $blankfoo, undef );
675 1         5 is( $count, 1, 'expected one object blank node' );
676             }
677              
678             {
679 1         404 my $count = $store->count_statements( $blankbar, undef, $blankfoo, undef );
  1         6  
680 1         5 is( $count, 0, 'expected zero subject-object blank node' );
681             }
682              
683             {
684 1         401 my $count = $store->count_statements( $blankfoo, undef, undef, $ex->d );
  1         9  
685 1         4 is( $count, 0, 'expected zero subject-context blank node' );
686             }
687              
688             {
689 1         399 my $count = $store->count_statements( $blankfoo, $ex->b, undef, undef );
  1         396  
  1         8  
690 1         4 is( $count, 1, 'expected one subject-predicate blank node' );
691             }
692              
693 1         404 $store->remove_statements( undef, undef, $blankfoo, undef );
694 1         5 is( $store->size, 2, 'expected two triples after remove statements' );
695 1         415 $store->remove_statement( $triple2 );
696 1         5 is( $store->size, 1, 'expected single triples after remove statement' );
697 1         435 $store->remove_statement( $triple );
698 1         5 is( $store->size, 0, 'expected zero size after remove statement' );
699             }
700              
701              
702             =item C<< count_statements_tests_simple( $store, $args, $data->{ex} ) >>
703              
704             Tests to check that counts are correct.
705              
706             =cut
707              
708             sub count_statements_tests_simple {
709 3     3 1 19 note " simple count_statements tests";
710 3         516 my ($store, $args, $ex) = @_;
711            
712             {
713 3         9 is( $store->size, 0, 'expected zero size before add statement' );
  3         17  
714 3         1331 my $st = RDF::Trine::Statement::Quad->new( $ex->a, $ex->b, $ex->c, $ex->d );
715 3         22 $store->add_statement( $st );
716              
717 3         302 is( $store->size, 1, 'size' );
718 3         1573 is( $store->count_statements(), 1, 'count_statements()' );
719 3         1597 is( $store->count_statements(undef, undef, undef), 1, 'count_statements(fff) with undefs' );
720 3         1734 is( $store->count_statements(undef, undef, undef, undef), 1, 'count_statements(ffff) with undefs' );
721             SKIP: {
722 3 50       1442 skip 'Quad-only test', 2 if $args->{quads_unsupported};
  3         19  
723 3         11 is( $store->count_statements(map {variable($_)} qw(s p o)), 1, 'count_statements(fff) with variables' );
  9         34  
724 3         1538 is( $store->count_statements(map {variable($_)} qw(s p o g)), 1, 'count_statements(ffff) with variables' );
  12         43  
725             }
726              
727             # 1-bound
728 3         1487 is( $store->count_statements($ex->a, undef, undef, undef), 1, 'count_statements(bfff)' );
729 3         1544 is( $store->count_statements(undef, $ex->b, undef, undef), 1, 'count_statements(fbff)' );
730 3         1524 is( $store->count_statements(undef, undef, $ex->c, undef), 1, 'count_statements(ffbf)' );
731 3         1263 is( $store->count_statements(undef, undef, undef, $ex->d), 1, 'count_statements(fffb)' );
732            
733             # 2-bound
734             # local($::debug) = 1;
735 3         1312 is( $store->count_statements($ex->a, $ex->b, undef, undef), 1, 'count_statements(bbff)' );
736 3         1428 is( $store->count_statements(undef, $ex->b, $ex->c, undef), 1, 'count_statements(fbbf)' );
737 3         1318 is( $store->count_statements(undef, undef, $ex->c, $ex->d), 1, 'count_statements(ffbb)' );
738 3         1290 is( $store->count_statements($ex->a, undef, undef, $ex->d), 1, 'count_statements(bffb)' );
739            
740 3         1327 $store->remove_statement( $st );
741 3         309 is( $store->size, 0, 'size' );
742             }
743            
744 3         49 is( $store->count_statements( $ex->z, undef, undef, undef ), 0, 'count_statements(bfff) empty result set' );
745 3         1496 is( $store->count_statements( $ex->z, undef, undef, $ex->x ), 0, 'count_statements(bffb) empty result set' );
746            
747             }
748              
749              
750             =item C<< count_statements_tests_quads( $store, $args, $data->{ex} ) >>
751              
752             Count statement tests for quads.
753              
754              
755             =cut
756              
757              
758             sub count_statements_tests_quads {
759 3     3 1 36 note " quad count_statements tests";
760 3         1035 my ($store, $args, $ex) = @_;
761             {
762 3         11 is( $store->count_statements, 27, 'count_statements()' );
  3         21  
763 3         1816 is( $store->count_statements(undef, undef, undef), 27, 'count_statements( fff )' );
764 3         1579 is( $store->count_statements(undef, undef, undef, undef), 81, 'count_statements( ffff )' );
765            
766 3         1429 is( $store->count_statements( $ex->a, undef, undef ), 9, 'count_statements( bff )' );
767 3         1528 is( $store->count_statements( $ex->a, undef, undef, undef ), 27, 'count_statements( bfff )' );
768 3         1506 is( $store->count_statements( $ex->a, undef, undef, $ex->a ), 9, 'count_statements( bffb )' );
769             }
770             }
771              
772              
773             =item C<< count_statements_tests_triples( $store, $args, $data->{ex}, $data->{nil} ) >>
774              
775             More tests for counts, with triples.
776              
777              
778             =cut
779              
780              
781             sub count_statements_tests_triples {
782 3     3 1 19 note " triple count_statements tests";
783 3         950 my ($store, $args, $ex, $nil) = @_;
784            
785             {
786 3         11 is( $store->count_statements, 27, 'count_statements() after triples added' );
  3         19  
787 3         1785 is( $store->count_statements(undef, undef, undef), 27, 'count_statements( fff ) after triples added' );
788 3         1528 is( $store->count_statements( $ex->a, undef, undef ), 9, 'count_statements( bff )' );
789 3         1414 is( $store->count_statements( $ex->a, undef, undef, $nil ), 9, 'count_statements( bffb )' );
790             SKIP: {
791 3 50       1490 skip 'Quad-only test', 2 if $args->{quads_unsupported};
  3         21  
792 3         21 is( $store->count_statements(undef, undef, undef, undef), 108, 'count_statements( ffff ) after triples added' );
793 3         1500 is( $store->count_statements( $ex->a, undef, undef, undef ), 27+9, 'count_statements( bfff )' );
794             }
795              
796             }
797             }
798              
799              
800             =item C<< get_statements_tests_triples( $store, $args, $data->{ex} ) >>
801              
802             Tests for getting statements using triples.
803              
804             =cut
805              
806              
807             sub get_statements_tests_triples {
808 4     4 1 24 note " triple get_statements tests";
809 4         787 my ($store, $args, $ex) = @_;
810            
811             {
812 4         25 my $iter = $store->get_statements( undef, undef, undef );
813 4         25 isa_ok( $iter, 'RDF::Trine::Iterator' );
814 4         2169 my $count = 0;
815 4         25 while (my $st = $iter->next()) {
816 108         278 $count++;
817             }
818 4         26 is( $count, 27, 'get_statements( fff ) expected result count' );
819 4         1971 is( $iter->next, undef, 'triple iterator end-of-stream' );
820             }
821            
822             {
823 4         12 my $iter = $store->get_statements( $ex->a, variable('p'), variable('o') );
  4         51  
824 4         25 isa_ok( $iter, 'RDF::Trine::Iterator' );
825 4         2195 my $count = 0;
826 4         45 while (my $st = $iter->next()) {
827 36         100 ok( $st->subject->equal( $ex->a ), 'expected triple get_statements bound subject' );
828 36         14673 $count++;
829             }
830 4         22 is( $count, 9, 'get_statements( bff ) expected result count' );
831             }
832            
833             {
834 4         1775 my $iter = $store->get_statements( $ex->d, undef, undef );
  4         455  
  4         36  
835 4         28 isa_ok( $iter, 'RDF::Trine::Iterator' );
836 4         2200 my $count = 0;
837 4         24 while (my $st = $iter->next()) {
838 0         0 $count++;
839             }
840 4         22 is( $count, 0, 'get_statements( bff ) expected empty results' );
841             }
842             }
843              
844              
845             =item C<< get_statements_tests_quads( $store, $args, $data->{ex}, $data->{nil} ) >>
846              
847             Tests for getting statements using quads.
848              
849             =cut
850              
851             sub get_statements_tests_quads {
852 3     3 1 18 note " quad get_statements tests";
853 3         498 my ($store, $args, $ex, $nil) = @_;
854            
855             {
856 3         21 my $iter = $store->get_statements( undef, undef, undef, undef );
857 3         20 isa_ok( $iter, 'RDF::Trine::Iterator' );
858 3         1605 my $count = 0;
859 3         17 while (my $st = $iter->next()) {
860 324         813 $count++;
861             }
862 3         25 is( $count, 108, 'get_statements( ffff ) expected result count' );
863 3         1792 is( $iter->next, undef, 'quad iterator end-of-stream' );
864             }
865            
866             {
867 3         9 my $iter = $store->get_statements( $ex->a, , variable('p'), variable('o'), variable('g') );
  3         40  
868 3         21 isa_ok( $iter, 'RDF::Trine::Iterator' );
869 3         1736 my $count = 0;
870 3         18 while (my $st = $iter->next()) {
871 108         349 ok( $st->subject->equal( $ex->a ), 'expected triple get_statements bound subject' );
872 108         45039 $count++;
873             }
874 3         18 is( $count, 27+9, 'get_statements( bfff ) expected result count' );
875             }
876            
877             {
878 3         1451 my $iter = $store->get_statements( $ex->d, undef, undef, undef );
  3         26  
879 3         22 isa_ok( $iter, 'RDF::Trine::Iterator' );
880 3         1687 my $count = 0;
881 3         17 while (my $st = $iter->next()) {
882 0         0 $count++;
883             }
884 3         16 is( $count, 0, 'get_statements( bfff ) expected empty results' );
885             }
886            
887             {
888 3         415 my $iter = $store->get_statements( undef, undef, undef, $nil );
  3         18  
889 3         21 isa_ok( $iter, 'RDF::Trine::Iterator' );
890 3         1491 my $count = 0;
891 3         38 while (my $st = $iter->next()) {
892 81         221 $count++;
893             }
894 3         18 is( $count, 27, 'get_statements( fffb ) expected result count 1' );
895             }
896            
897             {
898 3         413 my $iter = $store->get_statements( undef, undef, undef, $ex->a );
  3         35  
899 3         18 isa_ok( $iter, 'RDF::Trine::Iterator' );
900 3         1640 my $count = 0;
901 3         27 while (my $st = $iter->next()) {
902 81         241 ok( $st->context->equal( $ex->a ), 'expected triple get_statements bound context' );
903 81         33489 $count++;
904             }
905 3         17 is( $count, 27, 'get_statements( fffb ) expected result count 2' );
906             }
907            
908             {
909 3         1514 my $iter = $store->get_statements( $ex->a, $ex->b, undef, undef );
  3         30  
910 3         18 isa_ok( $iter, 'RDF::Trine::Iterator' );
911 3         1814 my $count = 0;
912 3         20 while (my $st = $iter->next()) {
913 36         120 ok( $st->subject->equal( $ex->a ), 'expected triple get_statements bound subject' );
914 36         15395 ok( $st->predicate->equal( $ex->b ), 'expected triple get_statements bound predicate' );
915 36         15455 $count++;
916             }
917 3         19 is( $count, 9+3, 'get_statements( bbff ) expected result count' );
918             }
919            
920             {
921 3         420 my $iter = $store->get_statements( $ex->a, $ex->z, undef, undef );
  3         456  
  3         25  
922 3         20 isa_ok( $iter, 'RDF::Trine::Iterator' );
923 3         1801 my $count = 0;
924 3         19 while (my $st = $iter->next()) {
925 0         0 $count++;
926             }
927 3         17 is( $count, 0, 'get_statements( bbff ) expected empty result' );
928             }
929            
930             }
931              
932              
933             =item C<< get_pattern_tests( $store, $args, $data->{ex} ) >>
934              
935             Tests for getting statements using with get_pattern.
936              
937             =cut
938              
939              
940             sub get_pattern_tests {
941 4     4 1 26 note " get_pattern tests";
942 4         700 my ($store, $args, $ex) = @_;
943 4         51 my $model = RDF::Trine::Model->new($store);
944 4         35 my $nil = RDF::Trine::Node::Nil->new();
945             {
946 4         34 my $iter = $model->get_pattern( RDF::Trine::Pattern->new(
947             statement(
948             $ex->a, $ex->b, variable('o1'), $nil,
949             ),
950             statement(
951             $ex->a, $ex->c, variable('o2'), $nil,
952             ),
953             )
954             );
955 4         35 isa_ok( $iter, 'RDF::Trine::Iterator::Bindings' );
956 4         2497 my $count = 0;
957 4         29 while (my $st = $iter->next()) {
958 36         116 $count++;
959             }
960 4         13 my $expected = 9;
961 4         27 is( $count, $expected, 'get_pattern( bbf, bbf ) expected result count' );
962 4         1802 is( $iter->next, undef, 'pattern iterator end-of-stream' );
963             }
964             {
965 4         11 my $iter = $model->get_pattern( RDF::Trine::Pattern->new(
  4         1729  
  4         45  
966             statement(
967             $ex->a, $ex->b, variable('o1'), $nil,
968             ),
969             statement(
970             $ex->a, $ex->c, literal('DAAAAHUUUT'), $nil,
971             ),
972             )
973             );
974 4         28 isa_ok( $iter, 'RDF::Trine::Iterator::Bindings' );
975 4         2453 my $count = 0;
976 4         21 while (my $st = $iter->next()) {
977 0         0 $count++;
978             }
979 4         22 is( $count, 0, 'get_pattern( bbf, bbu ) expected result count' );
980 4         1695 is( $iter->next, undef, 'pattern iterator end-of-stream' );
981             }
982             }
983              
984              
985              
986              
987             =item C<< remove_statement_tests( $store, $args, $data->{ex}, @{$data->{names}} ); >>
988              
989             Tests for removing statements.
990              
991              
992             =cut
993              
994              
995             sub remove_statement_tests {
996 3     3 1 19 note " remove_statement tests";
997 3         534 my ($store, $args, $ex, @names) = @_;
998 3         26 is( $store->count_statements( undef, undef, undef, undef ), 108, 'store size before quad removal' );
999 3         1414 foreach my $i (@names[0..2]) {
1000 9         94 my $w = $ex->$i();
1001 9         42 foreach my $j (@names[0..2]) {
1002 27         216 my $x = $ex->$j();
1003 27         112 foreach my $k (@names[0..2]) {
1004 81         666 my $y = $ex->$k();
1005 81         297 foreach my $l (@names[0..2]) {
1006 243         1976 my $z = $ex->$l();
1007 243         1274 my $quad = RDF::Trine::Statement::Quad->new($w,$x,$y,$z);
1008 243         999 $store->remove_statement( $quad );
1009             }
1010             }
1011             }
1012             }
1013 3         21 update_sleep($args);
1014            
1015 3         20 is( $store->count_statements( undef, undef, undef, undef ), 27, 'quad count after quad removal' );
1016 3         2175 is( $store->count_statements( undef, undef, undef ), 27, 'triple count after quad removal' );
1017            
1018 3         1527 $store->remove_statements( $ex->a, undef, undef, undef );
1019 3         223 update_sleep($args);
1020            
1021 3         16 is( $store->count_statements( undef, undef, undef ), 18, 'triple count after remove_statements( bfff )' );
1022            
1023 3         1723 foreach my $i (@names[0..2]) {
1024 9         93 my $w = $ex->$i();
1025 9         45 foreach my $j (@names[0..2]) {
1026 27         219 my $x = $ex->$j();
1027 27         99 foreach my $k (@names[0..2]) {
1028 81         585 my $y = $ex->$k();
1029 81         380 my $triple = RDF::Trine::Statement->new($w,$x,$y);
1030 81         313 $store->remove_statement( $triple );
1031             }
1032             }
1033             }
1034 3         20 update_sleep($args);
1035            
1036 3         20 is( $store->count_statements( undef, undef, undef, undef ), 0, 'quad count after triple removal' );
1037             }
1038              
1039              
1040             =item C<< update_sleep ( \%args ) >>
1041              
1042             If C<< $args{ update_sleep } >> is defined, sleeps for that many seconds.
1043             This function is called after update operations to aid in testing stores that
1044             perform updates asynchronously.
1045              
1046             =cut
1047              
1048             sub update_sleep {
1049 55     55 1 135 my $args = shift;
1050 55 50       315 if (defined($args->{ update_sleep })) {
1051 0           note ' sleeping ' . $args->{ update_sleep }. ' secs after store update';
1052 0           sleep($args->{ update_sleep });
1053             }
1054             }
1055              
1056             1;
1057             __END__
1058              
1059             =back
1060              
1061             =head1 BUGS
1062              
1063             Please report any bugs or feature requests to through the GitHub web interface
1064             at L<https://github.com/kasei/perlrdf/issues>.
1065              
1066             =head1 AUTHOR
1067              
1068             Gregory Todd Williams <gwilliams@cpan.org> and Kjetil Kjernsmo <kjetilk@cpan.org>
1069              
1070             =cut