File Coverage

blib/lib/Test/Proto/Role/Value.pm
Criterion Covered Total %
statement 198 206 96.1
branch 49 56 87.5
condition 0 3 0.0
subroutine 76 79 96.2
pod 41 41 100.0
total 364 385 94.5


line stmt bran cond sub pod time code
1             package Test::Proto::Role::Value;
2 13     13   11283 use 5.008;
  13         48  
  13         556  
3 13     13   70 use strict;
  13         34  
  13         386  
4 13     13   72 use warnings;
  13         27  
  13         318  
5 13     13   70 use Test::Proto::Common;
  13         24  
  13         1209  
6 13     13   82 use Scalar::Util qw(weaken isweak);
  13         33  
  13         793  
7 13     13   71 use Moo::Role;
  13         34  
  13         98  
8              
9             =head1 NAME
10              
11             Test::Proto::Role::Value - Role containing test case methods for any perl value
12              
13             =head1 SYNOPSIS
14              
15             package MyProtoClass;
16             use Moo;
17             with 'Test::Proto::Role::Value';
18              
19             This Moo Role provides methods to L for common test case methods like C, C, etc. which can potentially be used on any perl value/object.
20              
21             =head1 METHODS
22              
23             =head3 eq, ne, gt, lt, ge, le
24              
25             p->eq('green')->ok('green'); # passes
26             p->lt('green')->ok('grape'); # passes
27              
28             Performs the relevant string comparison on the subject, comparing against the text supplied.
29              
30             =cut
31              
32             sub eq {
33 1589     1589 1 9269 my ( $self, $expected, $reason ) = @_;
34 1589         9193 $self->add_test( 'eq', { expected => $expected }, $reason );
35             }
36              
37             sub ne {
38 28     28 1 256 my ( $self, $expected, $reason ) = @_;
39 28         182 $self->add_test( 'ne', { expected => $expected }, $reason );
40             }
41              
42             sub gt {
43 3     3 1 21 my ( $self, $expected, $reason ) = @_;
44 3         14 $self->add_test( 'gt', { expected => $expected }, $reason );
45             }
46              
47             sub lt {
48 4     4 1 30 my ( $self, $expected, $reason ) = @_;
49 4         19 $self->add_test( 'lt', { expected => $expected }, $reason );
50             }
51              
52             sub ge {
53 3     3 1 22 my ( $self, $expected, $reason ) = @_;
54 3         106 $self->add_test( 'ge', { expected => $expected }, $reason );
55             }
56              
57             sub le {
58 3     3 1 25 my ( $self, $expected, $reason ) = @_;
59 3         16 $self->add_test( 'le', { expected => $expected }, $reason );
60             }
61              
62             =head3 num_eq, num_ne, num_gt, num_lt, num_ge, num_le
63              
64             p->num_eq(0)->ok(0); # passes
65             p->num_lt(256)->ok(255); # passes
66              
67             Performs the relevant string comparison on the subject, comparing against the number supplied.
68              
69             =cut
70              
71             sub num_eq {
72 386     386 1 1036 my ( $self, $expected, $reason ) = @_;
73 386         2177 $self->add_test( 'num_eq', { expected => $expected }, $reason );
74             }
75              
76             sub num_ne {
77 2     2 1 15 my ( $self, $expected, $reason ) = @_;
78 2         10 $self->add_test( 'num_ne', { expected => $expected }, $reason );
79             }
80              
81             sub num_gt {
82 14     14 1 136 my ( $self, $expected, $reason ) = @_;
83 14         93 $self->add_test( 'num_gt', { expected => $expected }, $reason );
84             }
85              
86             sub num_lt {
87 9     9 1 75 my ( $self, $expected, $reason ) = @_;
88 9         55 $self->add_test( 'num_lt', { expected => $expected }, $reason );
89             }
90              
91             sub num_ge {
92 3     3 1 23 my ( $self, $expected, $reason ) = @_;
93 3         13 $self->add_test( 'num_ge', { expected => $expected }, $reason );
94             }
95              
96             sub num_le {
97 3     3 1 22 my ( $self, $expected, $reason ) = @_;
98 3         15 $self->add_test( 'num_le', { expected => $expected }, $reason );
99             }
100              
101             =head3 true, false
102              
103             p->true->ok("Strings are true"); # passes
104             p->false->ok($undefined); # fails
105              
106             Tests if the subject returns true or false in boolean context.
107              
108             =cut
109              
110             sub true {
111 3     3 1 27 my ( $self, $expected, $reason ) = @_;
112 3         19 $self->add_test( 'true', { expected => 'true' }, $reason );
113             }
114              
115             define_test 'true' => sub {
116 3     3   5 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
117 3 100       64 if ( $self->subject ) {
118 2         8 return $self->pass;
119             }
120             else {
121 1         5 return $self->fail;
122             }
123             };
124              
125             sub false {
126 3     3 1 23 my ( $self, $expected, $reason ) = @_;
127 3         18 $self->add_test( 'false', { expected => 'false' }, $reason );
128             }
129              
130             define_test 'false' => sub {
131 3     3   6 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
132 3 100       78 if ( $self->subject ) {
133 1         5 return $self->fail;
134             }
135             else {
136 2         10 return $self->pass;
137             }
138             };
139              
140             =head3 defined, undefined
141              
142             Tests if the subject is defined/undefined.
143              
144             p->defined->ok("Pretty much anything"); # passes
145              
146             Note that directly supplying undef into the protoype (as opposed to a variable containing undef, a function which returns undef, etc.) will exhibit different behaviour: it will attempt to use C<$_> instead. This is experimental behaviour.
147              
148             $_ = 3;
149             $undef = undef;
150             p->undefined->ok(undef); # fails
151             p->undefined->ok($undef); # passes
152              
153             =cut
154              
155             sub defined {
156 2     2 1 15 my ( $self, $expected, $reason ) = @_;
157 2         11 $self->add_test( 'defined', { expected => 'defined' }, $reason );
158             }
159              
160             define_test 'defined' => sub {
161 2     2   3 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
162 2 100       42 if ( defined $self->subject ) {
163 1         4 return $self->pass;
164             }
165             else {
166 1         6 return $self->fail;
167             }
168             };
169              
170             sub undefined {
171 6     6 1 141 my ( $self, $expected, $reason ) = @_;
172 6         42 $self->add_test( 'undefined', { expected => 'undefined' }, $reason );
173             }
174              
175             define_test 'undefined' => sub {
176 6     6   16 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
177 6 100       154 if ( defined $self->subject ) {
178 1         6 return $self->fail;
179             }
180             else {
181 5         29 return $self->pass;
182             }
183             };
184              
185             =head3 like, unlike
186              
187             p->like(qr/^a$/)->ok('a');
188             p->unlike(qr/^a$/)->ok('b');
189              
190             The test subject is validated against the regular expression. Like tests for a match; unlike tests for nonmatching.
191              
192             =cut
193              
194             sub like {
195 27     27 1 219 my ( $self, $expected, $reason ) = @_;
196 27         155 $self->add_test( 'like', { expected => $expected }, $reason );
197             }
198              
199             define_test 'like' => sub {
200 29     29   60 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
201 29         72 my $re = $data->{expected};
202 29 100       772 if ( $self->subject =~ m/$re/ ) {
203 19         104 return $self->pass;
204             }
205             else {
206 10         43 return $self->fail;
207             }
208             };
209              
210             sub unlike {
211 2     2 1 19 my ( $self, $expected, $reason ) = @_;
212 2         12 $self->add_test( 'unlike', { expected => $expected }, $reason );
213             }
214              
215             define_test 'unlike' => sub {
216 2     2   4 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
217 2         6 my $re = $data->{expected};
218 2 100       56 if ( $self->subject !~ m/$re/ ) {
219 1         5 return $self->pass;
220             }
221             else {
222 1         6 return $self->fail;
223             }
224             };
225              
226             =head3 try
227              
228             p->try( sub { 'a' eq lc shift; } )->ok('A');
229              
230             Used to execute arbitrary code. Passes if the return value is true.
231              
232             =cut
233              
234             sub try {
235 35     35 1 357 my ( $self, $expected, $reason ) = @_;
236 35         282 $self->add_test( 'try', { expected => $expected }, $reason );
237             }
238              
239             define_test 'try' => sub {
240 49     49   106 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
241 49 100       1275 if ( $data->{expected}->( $self->subject ) ) {
242 18         196 return $self->pass;
243             }
244             else {
245 31         277 return $self->fail;
246             }
247             };
248              
249             =head3 ref
250              
251             p->ref(undef)->ok('b');
252             p->ref('less')->ok(less);
253             p->ref(qr/[a-z]+/)->ok(less);
254              
255             Tests the result of the 'ref'. Any prototype will do here.
256              
257             =cut
258              
259             sub ref {
260 1036     1036 1 2525 my ( $self, $expected, $reason ) = @_;
261 1036         5417 $self->add_test( 'ref', { expected => $expected }, $reason );
262             }
263              
264             define_test 'ref' => sub {
265 1030     1030   2386 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
266 1030         4798 return upgrade( $data->{expected} )->validate( CORE::ref( $self->subject ), $self );
267             };
268              
269             =head3 is_a
270              
271             p->is_a('')->ok('b');
272             p->is_a('ARRAY')->ok([]);
273             p->is_a('less')->ok(less);
274              
275             A test which bundles C and C together.
276              
277             If the subject is not a reference, C or C<''> in the first argument passes.
278              
279             If the subject is a reference to a builtin type like HASH, the C of that type passes.
280              
281             If the subject is a blessed reference, then C is used.
282              
283             =cut
284              
285             sub is_a {
286 4     4 1 25 my ( $self, $expected, $reason ) = @_;
287 4         25 $self->add_test( 'is_a', { expected => $expected }, $reason );
288             }
289              
290             define_test is_a => sub {
291 3     3   8 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
292 3 100 0     91 if ( ( CORE::ref $self->subject ) =~ /^(SCALAR|ARRAY|HASH|CODE|REF|GLOB|LVALUE|FORMAT|IO|VSTRING|Regexp)$/ ) {
    50          
    0          
293 2 100       14 if ( $1 eq $data->{expected} ) {
294 1         6 return $self->pass;
295             }
296             }
297             elsif ( Scalar::Util::blessed $self->subject ) {
298 1 50       29 if ( $self->subject->isa( $data->{expected} ) ) {
299 1         4 return $self->pass;
300             }
301             }
302             elsif ( ( !defined $data->{expected} ) or $data->{expected} eq '' ) {
303 0         0 return $self->pass;
304             }
305 1         7 return $self->fail;
306             };
307              
308             =head3 blessed
309              
310             p->blessed->ok($object); # passes
311             p->blessed('Correct::Class')->ok($object); # passes
312             p->blessed->ok([]); # fails
313              
314             Compares the prototype to the result of running C from L on the test subject.
315              
316             =cut
317              
318             sub blessed {
319 17     17 1 135 my ( $self, $expected, $reason ) = @_;
320 17 100       412 $expected = Test::Proto::Base->new()->ne('') unless defined $expected;
321 17         115 $self->add_test( 'blessed', { expected => $expected }, $reason );
322             }
323              
324             define_test blessed => sub {
325 13     13   31 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
326 13         83 return upgrade( $data->{expected} )->validate( Scalar::Util::blessed( $self->subject ), $self );
327             };
328              
329             =head3 array
330              
331             p->array->ok([1..10]); # passes
332             p->array->ok($object); # fails, even if $object overloads @{}
333              
334             Passes if the subject is an unblessed array.
335              
336             =cut
337              
338             sub array {
339 111     111 1 971 my $self = shift;
340 111         2837 $self->ref( Test::Proto::Base->new->eq('ARRAY'), @_ );
341             }
342              
343             =head3 hash
344              
345             p->hash->ok({a=>'1'}); # passes
346             p->hash->ok($object); # fails, even if $object overloads @{}
347              
348             Passes if the subject is an unblessed hash.
349              
350             =cut
351              
352             sub hash {
353 6     6 1 46 my $self = shift;
354 6         143 $self->ref( Test::Proto::Base->new->eq('HASH'), @_ );
355             }
356              
357             =head3 scalar
358              
359             p->scalar->ok('a'); # passes
360             p->scalar->ok(\''); # fails
361              
362             Passes if the subject is an unblessed scalar.
363              
364             =cut
365              
366             sub scalar {
367 915     915 1 7389 my $self = shift;
368 915         22567 $self->ref( Test::Proto::Base->new->eq(''), @_ );
369             }
370              
371             =head3 scalar_ref
372              
373             p->scalar_ref->ok(\'a'); # passes
374             p->scalar_ref->ok('a'); # fails
375              
376             Passes if the subject is an unblessed scalar ref.
377              
378             =cut
379              
380             sub scalar_ref {
381 2     2 1 17 my $self = shift;
382 2         51 $self->ref( Test::Proto::Base->new->eq('SCALAR'), @_ );
383             }
384              
385             =head3 object
386              
387             p->scalar->ok('a'); # passes
388             p->scalar->ok(\'');
389              
390             Passes if the subject is a blessed object.
391              
392             =cut
393              
394             sub object {
395 2     2 1 22 shift->blessed;
396             }
397              
398             =head3 refaddr
399              
400             p->refaddr(undef)->ok('b');
401             p->refaddr(p->gt(5))->ok($obj);
402              
403             Tests the result of the 'refaddr' (from L). Any prototype will do here.
404              
405             =cut
406              
407             sub refaddr {
408 4     4 1 26 my ( $self, $expected, $reason ) = @_;
409 4         27 $self->add_test( 'refaddr', { expected => $expected }, $reason );
410             }
411              
412             define_test 'refaddr' => sub {
413 7     7   18 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
414 7         40 upgrade( $data->{expected} )->validate( Scalar::Util::refaddr( $self->subject ), $self );
415             };
416              
417             =head3 refaddr_of
418              
419             $obj2 = $obj;
420             p->refaddr_of($obj)->ok($obj2); # passes
421             p->refaddr([])->ok([]); # fails
422              
423             Tests the result of the 'refaddr' (from L) is the same as the refaddr of the object passed. Do not supply prototypes.
424              
425             Note: This always passes for strings.
426              
427             =cut
428              
429             sub refaddr_of {
430 3     3 1 28 my ( $self, $expected, $reason ) = @_;
431 3         15 my $refaddr = Scalar::Util::refaddr($expected);
432 3 100       42 $refaddr = Test::Proto::Base->new->undefined unless defined $refaddr;
433 3         17 $self->add_test( 'refaddr', { expected => $refaddr }, $reason );
434             }
435              
436             {
437             my %num_eqv = qw(eq == ne != gt > lt < ge >= le <=);
438             foreach my $dir ( keys %num_eqv ) {
439              
440             define_test $dir => sub {
441 1622     1622   3815 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
        1622      
        1622      
        1622      
        1622      
        1622      
442 1622         2192 my $result;
443 1622         146620 eval "\$result = \$self->subject $dir \$data->{expected}";
444 1622 100       7191 if ($result) {
445 1421         5768 return $self->pass;
446             }
447             else {
448 201         1076 return $self->fail;
449             }
450             };
451              
452             my $num_dir = $num_eqv{$dir};
453              
454             define_test "num_$dir" => sub {
455 427     427   1040 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
        427      
        427      
        427      
        427      
        427      
456 427         915 my $result;
457 427         32072 eval "\$result = \$self->subject $num_dir \$data->{expected}";
458 427 100       2113 if ($result) {
459 233         1037 return $self->pass;
460             }
461             else {
462 194         1090 return $self->fail;
463             }
464             };
465             }
466             }
467              
468             =head3 also
469              
470             $positive = p->num_gt(0);
471             $integer->also($positive);
472             $integer->also(qr/[02468]$/);
473             $integer->ok(42); # passes
474              
475             Tests that the subject also matches the protoype given. If the argument given is not a prototype, the argument is upgraded to become one.
476              
477             =cut
478              
479             sub also {
480 4     4 1 18 my ( $self, $expected, $reason ) = @_;
481 4         19 $self->add_test( 'also', { expected => $expected }, $reason );
482             }
483              
484             define_test also => sub {
485 4     4   8 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
486 4         19 return upgrade( $data->{expected} )->validate( $self->subject, $self );
487             };
488              
489             =head3 any_of
490              
491             $positive = p->num_gt(0);
492             $all = p->eq('all');
493             $integer->any_of([$positive, $all]);
494             $integer->ok(42); # passes
495             $integer->ok('all'); # passes
496              
497             Tests that the subject also matches one of the protoypes given in the arrayref. If a member of the arrayref given is not a prototype, the argument is upgraded to become one.
498              
499             =cut
500              
501             sub any_of {
502 8     8 1 55 my ( $self, $expected, $reason ) = @_;
503 8         47 $self->add_test( 'any_of', { expected => $expected }, $reason );
504             }
505              
506             define_test any_of => sub {
507 8     8   23 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
508 8         23 my $i = 0;
509 8         13 foreach my $candidate ( @{ $data->{expected} } ) {
  8         31  
510 13         62 my $result = upgrade($candidate)->validate( $self->subject, $self->subtest );
511 13 100       79 return $self->pass("Candidate $i was successful") if $result;
512 8         31 $i++;
513             }
514 3         22 return $self->fail("None of the $i candidates were successful");
515             };
516              
517             =head3 all_of
518              
519             $positive = p->num_gt(0);
520             $under_a_hundred = p->num_lt(100);
521             $integer->all_of([$positive, $under_a_hundred]);
522             $integer->ok(42); # passes
523             $integer->ok('101'); # fails
524              
525             Tests that the subject also matches one of the protoypes given in the arrayref. If a member of the arrayref given is not a prototype, the argument is upgraded to become one.
526              
527             =cut
528              
529             sub all_of {
530 7     7 1 46 my ( $self, $expected, $reason ) = @_;
531 7         37 $self->add_test( 'all_of', { expected => $expected }, $reason );
532             }
533              
534             define_test all_of => sub {
535 7     7   18 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
536 7         13 my $i = 0;
537 7         14 foreach my $candidate ( @{ $data->{expected} } ) {
  7         35  
538 12         55 my $result = upgrade($candidate)->validate( $self->subject, $self->subtest );
539 12 100       76 return $self->fail("Candidate $i was unsuccessful") unless $result;
540 8         30 $i++;
541             }
542 3         23 return $self->pass("All of the $i candidates were successful");
543             };
544              
545             =head3 none_of
546              
547             $positive = p->num_gt(0);
548             $all = p->like(qr/[02468]$/);
549             $integer->none_of([$positive, $all]);
550             $integer->ok(-1); # passes
551             $integer->ok(-2); # fails
552             $integer->ok(1); # fails
553              
554             Tests that the subject does not match any of the protoypes given in the arrayref. If a member of the arrayref given is not a prototype, the argument is upgraded to become one.
555              
556             =cut
557              
558             sub none_of {
559 8     8 1 61 my ( $self, $expected, $reason ) = @_;
560 8         49 $self->add_test( 'none_of', { expected => $expected }, $reason );
561             }
562              
563             define_test none_of => sub {
564 8     8   20 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
565 8         17 my $i = 0;
566 8         14 foreach my $candidate ( @{ $data->{expected} } ) {
  8         27  
567 12         59 my $result = upgrade($candidate)->validate( $self->subject, $self->subtest );
568 12 100       81 return $self->fail("Candidate $i was successful") if $result;
569 7         27 $i++;
570             }
571 3         24 return $self->pass("None of the $i candidates were successful");
572             };
573              
574             =head3 some_of
575              
576             p->some_of([qr/cheap/, qr/fast/, qr/good/], 2, 'Pick two!');
577              
578             Tests that the subject some, all, or none of the protoypes given in the arrayref; the number of successful matches is tested against the second argument. If a member of the arrayref given is not a prototype, the argument is upgraded to become one.
579              
580             =cut
581              
582             sub some_of {
583 9     9 1 98 my ( $self, $expected, $count, $reason ) = @_;
584 9 50       38 $count = p->gt(0) unless defined $count;
585 9         61 $self->add_test(
586             'some_of',
587             {
588             expected => $expected,
589             count => $count
590             },
591             $reason
592             );
593             }
594              
595             define_test some_of => sub {
596 9     9   52 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
597 9         19 my $i = 0;
598 9         21 foreach my $candidate ( @{ $data->{expected} } ) {
  9         37  
599 25 100       125 $i++ if upgrade($candidate)->validate( $self->subject, $self->subtest );
600             }
601 9 100       66 return $self->pass if upgrade( $data->{count} )->validate( $i, $self->subtest );
602 4         24 return $self->fail;
603             };
604              
605             =head3 looks_like_number
606              
607             p->looks_like_number->ok('3'); # passes
608             p->looks_like_number->ok('a'); # fails
609              
610             If the test subject looks like a number according to Perl's internal rules (specifically, using Scalar::Util::looks_like_number), then pass.
611              
612             =cut
613              
614             sub looks_like_number {
615 23     23 1 210 my ( $self, $expected, $count, $reason ) = @_;
616 23         116 $self->add_test( 'looks_like_number', $reason );
617             }
618              
619             define_test looks_like_number => sub {
620 23     23   57 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
621 23 100       677 return $self->pass if Scalar::Util::looks_like_number( $self->subject );
622 15         78 return $self->fail;
623             };
624              
625             =head3 looks_unlike_number
626              
627             p->looks_unlike_number->ok('3'); # fails
628             p->looks_unlike_number->ok('a'); # passes
629              
630             If the test subject looks like a number according to Perl's internal rules (specifically, using Scalar::Util::looks_like_number), then fail.
631              
632             =cut
633              
634             sub looks_unlike_number {
635 23     23 1 221 my ( $self, $expected, $count, $reason ) = @_;
636 23         103 $self->add_test( 'looks_unlike_number', $reason );
637             }
638              
639             define_test looks_unlike_number => sub {
640 23     23   54 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
641 23 100       702 return $self->fail if Scalar::Util::looks_like_number( $self->subject );
642 15         79 return $self->pass;
643             };
644              
645             =head3 is_weak_ref
646              
647             DOES NOT WORK
648              
649             Tests that the subject is a weak reference using is_weak from L.
650              
651             =cut
652              
653             sub is_weak_ref {
654 3     3 1 22 my ( $self, $reason ) = @_;
655 3         16 $self->add_test( 'is_weak_ref', {}, $reason );
656             }
657              
658             define_test is_weak_ref => sub {
659 3     3   9 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
660 3 100       159 return $self->fail("Not a reference") unless CORE::ref $self->subject;
661 2 50       59 return $self->fail("Not weak") unless isweak $self->subject;
662 0         0 return $self->pass("Weak reference");
663             };
664              
665             =head3 is_strong_ref
666              
667             DOES NOT WORK
668              
669             Tests that the subject is not a weak reference using is_weak from L.
670              
671             =cut
672              
673             sub is_strong_ref {
674 3     3 1 25 my ( $self, $reason ) = @_;
675 3         18 $self->add_test( 'is_strong_ref', {}, $reason );
676             }
677              
678             define_test is_strong_ref => sub {
679 3     3   8 my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
680 3 100       76 return $self->fail("Not a reference") unless CORE::ref $self->subject;
681 2 50       46 return $self->fail("Weak reference") if isweak $self->subject;
682 2         10 return $self->pass("Not a weak reference");
683             };
684              
685             =head2 Data::DPath
686              
687             The following functions will load if you have Data::DPath installed.
688              
689             =cut
690              
691             eval {
692             require Data::DPath;
693             Data::DPath->import();
694             };
695             unless ($@) {
696              
697             #~ Data::DPath loaded ok
698              
699             =head3 dpath_true
700              
701             p->dpath_true('//answer[ val == 42 ]')
702              
703             Evaluates the dpath expression and passes if it finds a match.
704              
705             =cut
706              
707             sub dpath_true {
708 0     0 1   my ( $self, $path, $reason ) = @_;
709 0           $self->add_test( 'dpath_true', { path => $path }, $reason );
710             }
711              
712             =head3 dpath_false
713              
714             p->dpath_false('//answer[ !val ]')
715              
716             Evaluates the dpath expression and passes if it does not find a match.
717              
718             =cut
719              
720             sub dpath_false {
721 0     0 1   my ( $self, $path, $reason ) = @_;
722 0           $self->add_test( 'dpath_false', { path => $path }, $reason );
723             }
724              
725             =head3 dpath_results
726              
727             p->dpath_false('//answer', pArray->array_any(42))
728              
729             Evaluates the dpath expression and then uses the second argument (which should be upgradeable to a L) to validate the list of matches.
730              
731             =cut
732              
733             sub dpath_results {
734 0     0 1   my ( $self, $path, $expected, $reason ) = @_;
735 0           $self->add_test(
736             'dpath_results',
737             {
738             path => $path,
739             expected => $expected
740             },
741             $reason
742             );
743             }
744              
745             define_test dpath_true => sub {
746             my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
747             my $dpath = Data::DPath::build_dpath()->( $data->{path} );
748             my $result = scalar( $dpath->match( $self->subject ) );
749             return $self->pass if $result;
750             return $self->fail;
751             };
752             define_test dpath_false => sub {
753             my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
754             my $dpath = Data::DPath::build_dpath()->( $data->{path} );
755             my $result = scalar( $dpath->match( $self->subject ) );
756             return $self->fail if $result;
757             return $self->pass;
758             };
759             define_test dpath_results => sub {
760             my ( $self, $data, $reason ) = @_; # self is the runner, NOT the prototype
761             my $dpath = Data::DPath::build_dpath()->( $data->{path} );
762             my $result = [ $dpath->match( $self->subject ) ];
763             return upgrade( $data->{expected} )->validate( $result, $self );
764             };
765              
766             }
767              
768             =head1 OTHER INFORMATION
769              
770             For author, version, bug reports, support, etc, please see L.
771              
772             =cut
773              
774             1;