File Coverage

blib/lib/Carp/Assert/More.pm
Criterion Covered Total %
statement 405 412 98.3
branch 228 236 96.6
condition 136 197 69.0
subroutine 47 48 97.9
pod 39 39 100.0
total 855 932 91.7


line stmt bran cond sub pod time code
1             package Carp::Assert::More;
2              
3 42     42   2848111 use 5.010;
  42         521  
4 42     42   226 use strict;
  42         74  
  42         836  
5 42     42   200 use warnings;
  42         79  
  42         1060  
6              
7 42     42   199 use Exporter;
  42         76  
  42         1985  
8 42     42   255 use Scalar::Util qw( looks_like_number );;
  42         77  
  42         2464  
9              
10 42     42   312 use vars qw( $VERSION @ISA @EXPORT );
  42         79  
  42         6000  
11              
12             =head1 NAME
13              
14             Carp::Assert::More - Convenience assertions for common situations
15              
16             =head1 VERSION
17              
18             Version 2.3.0
19              
20             =cut
21              
22             BEGIN {
23 42     42   167 $VERSION = '2.3.0';
24 42         699 @ISA = qw(Exporter);
25 42         54609 @EXPORT = qw(
26             assert_all_keys_in
27             assert_aoh
28             assert_arrayref
29             assert_arrayref_nonempty
30             assert_arrayref_of
31             assert_cmp
32             assert_coderef
33             assert_context_nonvoid
34             assert_context_scalar
35             assert_datetime
36             assert_defined
37             assert_empty
38             assert_exists
39             assert_fail
40             assert_hashref
41             assert_hashref_nonempty
42             assert_in
43             assert_integer
44             assert_is
45             assert_isa
46             assert_isa_in
47             assert_isnt
48             assert_keys_are
49             assert_lacks
50             assert_like
51             assert_listref
52             assert_negative
53             assert_negative_integer
54             assert_nonblank
55             assert_nonempty
56             assert_nonnegative
57             assert_nonnegative_integer
58             assert_nonref
59             assert_nonzero
60             assert_nonzero_integer
61             assert_numeric
62             assert_positive
63             assert_positive_integer
64             assert_undefined
65             assert_unlike
66             );
67             }
68              
69             my $INTEGER = qr/^-?\d+$/;
70              
71             =head1 SYNOPSIS
72              
73             A set of convenience functions for common assertions.
74              
75             use Carp::Assert::More;
76              
77             my $obj = My::Object;
78             assert_isa( $obj, 'My::Object', 'Got back a correct object' );
79              
80             =head1 DESCRIPTION
81              
82             Carp::Assert::More is a convenient set of assertions to make the habit
83             of writing assertions even easier.
84              
85             Everything in here is effectively syntactic sugar. There's no technical
86             difference between calling one of these functions:
87              
88             assert_datetime( $foo );
89             assert_isa( $foo, 'DateTime' );
90              
91             that are provided by Carp::Assert::More and calling these assertions
92             from Carp::Assert
93              
94             assert( defined $foo );
95             assert( ref($foo) eq 'DateTime' );
96              
97             My intent here is to make common assertions easy so that we as programmers
98             have no excuse to not use them.
99              
100             =head1 SIMPLE ASSERTIONS
101              
102             =head2 assert_is( $string, $match [,$name] )
103              
104             Asserts that I<$string> is the same string value as I<$match>.
105              
106             C is not converted to an empty string. If both strings are
107             C, they match. If only one string is C, they don't match.
108              
109             =cut
110              
111             sub assert_is($$;$) {
112 8     8 1 4062 my $string = shift;
113 8         11 my $match = shift;
114 8         12 my $name = shift;
115              
116 8 100       18 if ( defined($string) ) {
117 6 100 100     38 return if defined($match) && ($string eq $match);
118             }
119             else {
120 2 100       8 return if !defined($match);
121             }
122              
123 3         16 require Carp;
124 3         8 &Carp::confess( _failure_msg($name) );
125             }
126              
127              
128             =head2 assert_isnt( $string, $unmatch [,$name] )
129              
130             Asserts that I<$string> does NOT have the same string value as I<$unmatch>.
131              
132             C is not converted to an empty string.
133              
134             =cut
135              
136             sub assert_isnt($$;$) {
137 8     8 1 5032 my $string = shift;
138 8         14 my $unmatch = shift;
139 8         13 my $name = shift;
140              
141             # undef only matches undef
142 8 100 100     46 return if defined($string) xor defined($unmatch);
143              
144 6 100 66     31 return if defined($string) && defined($unmatch) && ($string ne $unmatch);
      100        
145              
146 5         28 require Carp;
147 5         14 &Carp::confess( _failure_msg($name) );
148             }
149              
150              
151             =head2 assert_cmp( $x, $op, $y [,$name] )
152              
153             Asserts that the relation C<$x $op $y> is true. It lets you know why
154             the comparsison failed, rather than simply that it did fail, by giving
155             better diagnostics than a plain C, as well as showing the
156             operands in the stacktrace.
157              
158             Plain C:
159              
160             assert( $nitems <= 10, 'Ten items or fewer in the express lane' );
161              
162             Assertion (Ten items or fewer in the express lane) failed!
163             Carp::Assert::assert("", "Ten items or fewer in the express lane") called at foo.pl line 12
164              
165             With C:
166              
167             assert_cmp( $nitems, '<=', 10, 'Ten items or fewer in the express lane' );
168              
169             Assertion (Ten items or fewer in the express lane) failed!
170             Failed: 14 <= 10
171             Carp::Assert::More::assert_cmp(14, "<=", 10, "Ten items or fewer in the express lane") called at foo.pl line 11
172              
173             The following operators are supported:
174              
175             =over 4
176              
177             =item * == numeric equal
178              
179             =item * != numeric not equal
180              
181             =item * > numeric greater than
182              
183             =item * >= numeric greater than or equal
184              
185             =item * < numeric less than
186              
187             =item * <= numeric less than or equal
188              
189             =item * lt string less than
190              
191             =item * le string less than or equal
192              
193             =item * gt string less than
194              
195             =item * ge string less than or equal
196              
197             =back
198              
199             There is no support for C or C because those already have
200             C and C, respectively.
201              
202             If either C<$x> or C<$y> is undef, the assertion will fail.
203              
204             If the operator is numeric, and C<$x> or C<$y> are not numbers, the assertion will fail.
205              
206             =cut
207              
208             sub assert_cmp($$$;$) {
209 113     113 1 70526 my $x = shift;
210 113         176 my $op = shift;
211 113         164 my $y = shift;
212 113         189 my $name = shift;
213              
214 113         153 my $why;
215              
216 113 100       519 if ( !defined($op) ) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
217 1         3 $why = 'Invalid operator ';
218             }
219             elsif ( $op eq '==' ) {
220 13 100 100     99 return if looks_like_number($x) && looks_like_number($y) && ($x == $y);
      100        
221             }
222             elsif ( $op eq '!=' ) {
223 13 100 100     96 return if looks_like_number($x) && looks_like_number($y) && ($x != $y);
      100        
224             }
225             elsif ( $op eq '<' ) {
226 17 100 100     128 return if looks_like_number($x) && looks_like_number($y) && ($x < $y);
      100        
227             }
228             elsif ( $op eq '<=' ) {
229 17 100 100     128 return if looks_like_number($x) && looks_like_number($y) && ($x <= $y);
      100        
230             }
231             elsif ( $op eq '>' ) {
232 18 100 100     132 return if looks_like_number($x) && looks_like_number($y) && ($x > $y);
      100        
233             }
234             elsif ( $op eq '>=' ) {
235 17 100 100     131 return if looks_like_number($x) && looks_like_number($y) && ($x >= $y);
      100        
236             }
237             elsif ( $op eq 'lt' ) {
238 2 100 33     19 return if defined($x) && defined($y) && ($x lt $y);
      66        
239             }
240             elsif ( $op eq 'le' ) {
241 2 100 33     18 return if defined($x) && defined($y) && ($x le $y);
      66        
242             }
243             elsif ( $op eq 'gt' ) {
244 2 100 33     29 return if defined($x) && defined($y) && ($x gt $y);
      66        
245             }
246             elsif ( $op eq 'ge' ) {
247 2 100 33     16 return if defined($x) && defined($y) && ($x ge $y);
      66        
248             }
249             else {
250 9         19 $why = qq{Invalid operator "$op"};
251             }
252              
253 71   100     425 $why //= "Failed: " . ($x // 'undef') . ' ' . $op . ' ' . ($y // 'undef');
      100        
      66        
254              
255 71         379 require Carp;
256 71         178 &Carp::confess( _failure_msg($name, $why) );
257             }
258              
259              
260             =head2 assert_like( $string, qr/regex/ [,$name] )
261              
262             Asserts that I<$string> matches I.
263              
264             The assertion fails either the string or the regex are undef.
265              
266             =cut
267              
268             sub assert_like($$;$) {
269 7     7 1 3827 my $string = shift;
270 7         14 my $regex = shift;
271 7         12 my $name = shift;
272              
273 7 100 66     31 if ( defined($string) && !ref($string) ) {
274 6 100       13 if ( ref($regex) ) {
275 5 100       50 return if $string =~ $regex;
276             }
277             }
278              
279 4         22 require Carp;
280 4         12 &Carp::confess( _failure_msg($name) );
281             }
282              
283              
284             =head2 assert_unlike( $string, qr/regex/ [,$name] )
285              
286             Asserts that I<$string> matches I.
287              
288             The assertion fails if the regex is undef.
289              
290             =cut
291              
292             sub assert_unlike($$;$) {
293 7     7 1 4318 my $string = shift;
294 7         12 my $regex = shift;
295 7         10 my $name = shift;
296              
297 7 100       20 return if !defined($string);
298              
299 5 100       14 if ( ref($regex) eq 'Regexp' ) {
300 3 100       21 return if $string !~ $regex;
301             }
302              
303 4         20 require Carp;
304 4         9 &Carp::confess( _failure_msg($name) );
305             }
306              
307              
308             =head2 assert_defined( $this [, $name] )
309              
310             Asserts that I<$this> is defined.
311              
312             =cut
313              
314             sub assert_defined($;$) {
315 9 100   9 1 1784 return if defined( $_[0] );
316              
317 2         13 require Carp;
318 2         12 &Carp::confess( _failure_msg($_[1]) );
319             }
320              
321              
322             =head2 assert_undefined( $this [, $name] )
323              
324             Asserts that I<$this> is not defined.
325              
326             =cut
327              
328             sub assert_undefined($;$) {
329 4 100   4 1 2831 return unless defined( $_[0] );
330              
331 3         17 require Carp;
332 3         8 &Carp::confess( _failure_msg($_[1]) );
333             }
334              
335             =head2 assert_nonblank( $this [, $name] )
336              
337             Asserts that I<$this> is not a reference and is not an empty string.
338              
339             =cut
340              
341             sub assert_nonblank($;$) {
342 7     7 1 5159 my $this = shift;
343 7         12 my $name = shift;
344              
345 7         10 my $why;
346 7 100       24 if ( !defined($this) ) {
347 2         5 $why = 'Value is undef.';
348             }
349             else {
350 5 100       10 if ( ref($this) ) {
351 1         8 $why = 'Value is a reference to ' . ref($this) . '.';
352             }
353             else {
354 4 100       18 return if $this ne '';
355 2         4 $why = 'Value is blank.';
356             }
357             }
358              
359 5         26 require Carp;
360 5         12 &Carp::confess( _failure_msg($name, $why) );
361             }
362              
363              
364             =head1 NUMERIC ASSERTIONS
365              
366             =head2 assert_numeric( $n [, $name] )
367              
368             Asserts that C<$n> looks like a number, according to C.
369             C will always fail.
370              
371             =cut
372              
373             sub assert_numeric {
374 21     21 1 10953 my $n = shift;
375 21         38 my $name = shift;
376              
377 21 100       100 return if Scalar::Util::looks_like_number( $n );
378              
379 9         52 require Carp;
380 9         23 &Carp::confess( _failure_msg($name) );
381             }
382              
383              
384             =head2 assert_integer( $this [, $name ] )
385              
386             Asserts that I<$this> is an integer, which may be zero or negative.
387              
388             assert_integer( 0 ); # pass
389             assert_integer( 14 ); # pass
390             assert_integer( -14 ); # pass
391             assert_integer( '14.' ); # FAIL
392              
393             =cut
394              
395             sub assert_integer($;$) {
396 20     20 1 7932 my $this = shift;
397 20         33 my $name = shift;
398              
399 20 100       45 if ( defined($this) ) {
400 18 100       119 return if $this =~ $INTEGER;
401             }
402              
403 14         69 require Carp;
404 14         32 &Carp::confess( _failure_msg($name) );
405             }
406              
407              
408             =head2 assert_nonzero( $this [, $name ] )
409              
410             Asserts that the numeric value of I<$this> is defined and is not zero.
411              
412             assert_nonzero( 0 ); # FAIL
413             assert_nonzero( -14 ); # pass
414             assert_nonzero( '14.' ); # pass
415              
416             =cut
417              
418             sub assert_nonzero($;$) {
419 10     10 1 5481 my $this = shift;
420 10         16 my $name = shift;
421              
422 10 100       38 if ( Scalar::Util::looks_like_number($this) ) {
423 5 100       18 return if $this != 0;
424             }
425              
426 6         34 require Carp;
427 6         18 &Carp::confess( _failure_msg($name) );
428             }
429              
430              
431             =head2 assert_positive( $this [, $name ] )
432              
433             Asserts that I<$this> is defined, numeric and greater than zero.
434              
435             assert_positive( 0 ); # FAIL
436             assert_positive( -14 ); # FAIL
437             assert_positive( '14.' ); # pass
438              
439             =cut
440              
441             sub assert_positive($;$) {
442 10     10 1 5500 my $this = shift;
443 10         16 my $name = shift;
444              
445 10 100       44 if ( Scalar::Util::looks_like_number($this) ) {
446 5 100       20 return if ($this+0 > 0);
447             }
448              
449 7         36 require Carp;
450 7         29 &Carp::confess( _failure_msg($name) );
451             }
452              
453              
454             =head2 assert_nonnegative( $this [, $name ] )
455              
456             Asserts that I<$this> is defined, numeric and greater than or equal
457             to zero.
458              
459             assert_nonnegative( 0 ); # pass
460             assert_nonnegative( -14 ); # FAIL
461             assert_nonnegative( '14.' ); # pass
462             assert_nonnegative( 'dog' ); # pass
463              
464             =cut
465              
466             sub assert_nonnegative($;$) {
467 10     10 1 6764 my $this = shift;
468 10         15 my $name = shift;
469              
470 10 100       41 if ( Scalar::Util::looks_like_number( $this ) ) {
471 5 100       20 return if $this >= 0;
472             }
473              
474 6         30 require Carp;
475 6         18 &Carp::confess( _failure_msg($name) );
476             }
477              
478              
479             =head2 assert_negative( $this [, $name ] )
480              
481             Asserts that the numeric value of I<$this> is defined and less than zero.
482              
483             assert_negative( 0 ); # FAIL
484             assert_negative( -14 ); # pass
485             assert_negative( '14.' ); # FAIL
486              
487             =cut
488              
489             sub assert_negative($;$) {
490 10     10 1 5440 my $this = shift;
491 10         17 my $name = shift;
492              
493 42     42   370 no warnings;
  42         95  
  42         127204  
494 10 100 100     59 return if defined($this) && ($this+0 < 0);
495              
496 9         47 require Carp;
497 9         22 &Carp::confess( _failure_msg($name) );
498             }
499              
500              
501             =head2 assert_nonzero_integer( $this [, $name ] )
502              
503             Asserts that the numeric value of I<$this> is defined, an integer, and not zero.
504              
505             assert_nonzero_integer( 0 ); # FAIL
506             assert_nonzero_integer( -14 ); # pass
507             assert_nonzero_integer( '14.' ); # FAIL
508              
509             =cut
510              
511             sub assert_nonzero_integer($;$) {
512 10     10 1 5742 my $this = shift;
513 10         16 my $name = shift;
514              
515 10 100 100     101 if ( defined($this) && ($this =~ $INTEGER) ) {
516 3 100       13 return if $this != 0;
517             }
518              
519 8         45 require Carp;
520 8         25 &Carp::confess( _failure_msg($name) );
521             }
522              
523              
524             =head2 assert_positive_integer( $this [, $name ] )
525              
526             Asserts that the numeric value of I<$this> is defined, an integer and greater than zero.
527              
528             assert_positive_integer( 0 ); # FAIL
529             assert_positive_integer( -14 ); # FAIL
530             assert_positive_integer( '14.' ); # FAIL
531             assert_positive_integer( '14' ); # pass
532              
533             =cut
534              
535             sub assert_positive_integer($;$) {
536 11     11 1 8181 my $this = shift;
537 11         16 my $name = shift;
538              
539 11 100 100     98 if ( defined($this) && ($this =~ $INTEGER) ) {
540 4 100       20 return if $this > 0;
541             }
542              
543 9         47 require Carp;
544 9         20 &Carp::confess( _failure_msg($name) );
545             }
546              
547              
548             =head2 assert_nonnegative_integer( $this [, $name ] )
549              
550             Asserts that the numeric value of I<$this> is defined, an integer, and not less than zero.
551              
552             assert_nonnegative_integer( 0 ); # pass
553             assert_nonnegative_integer( -14 ); # FAIL
554             assert_nonnegative_integer( '14.' ); # FAIL
555              
556             =cut
557              
558             sub assert_nonnegative_integer($;$) {
559 10     10 1 5502 my $this = shift;
560 10         17 my $name = shift;
561              
562 10 100 100     97 if ( defined($this) && ($this =~ $INTEGER) ) {
563 3 100       21 return if $this >= 0;
564             }
565              
566 8         44 require Carp;
567 8         24 &Carp::confess( _failure_msg($name) );
568             }
569              
570              
571             =head2 assert_negative_integer( $this [, $name ] )
572              
573             Asserts that the numeric value of I<$this> is defined, an integer, and less than zero.
574              
575             assert_negative_integer( 0 ); # FAIL
576             assert_negative_integer( -14 ); # pass
577             assert_negative_integer( '14.' ); # FAIL
578              
579             =cut
580              
581             sub assert_negative_integer($;$) {
582 11     11 1 7535 my $this = shift;
583 11         18 my $name = shift;
584              
585 11 100 100     111 if ( defined($this) && ($this =~ $INTEGER) ) {
586 3 100       11 return if $this < 0;
587             }
588              
589 10         55 require Carp;
590 10         25 &Carp::confess( _failure_msg($name) );
591             }
592              
593              
594             =head1 REFERENCE ASSERTIONS
595              
596             =head2 assert_isa( $this, $type [, $name ] )
597              
598             Asserts that I<$this> is an object of type I<$type>.
599              
600             =cut
601              
602             sub assert_isa($$;$) {
603 6     6 1 2636 my $this = shift;
604 6         13 my $type = shift;
605 6         10 my $name = shift;
606              
607             # The assertion is true if
608             # 1) For objects, $this is of class $type or of a subclass of $type
609             # 2) For non-objects, $this is a reference to a HASH, SCALAR, ARRAY, etc.
610              
611 6 100 66     51 return if Scalar::Util::blessed( $this ) && $this->isa( $type );
612 4 100       14 return if ref($this) eq $type;
613              
614 3         15 require Carp;
615 3         8 &Carp::confess( _failure_msg($name) );
616             }
617              
618              
619             =head2 assert_isa_in( $obj, \@types [, $description] )
620              
621             Assert that the blessed C<$obj> isa one of the types in C<\@types>.
622              
623             assert_isa_in( $obj, [ 'My::Foo', 'My::Bar' ], 'Must pass either a Foo or Bar object' );
624              
625             =cut
626              
627             sub assert_isa_in($$;$) {
628 17     17 1 10135 my $obj = shift;
629 17         29 my $types = shift;
630 17         24 my $name = shift;
631              
632 17 100       65 if ( Scalar::Util::blessed($obj) ) {
633 12         15 for ( @{$types} ) {
  12         25  
634 12 100       80 return if $obj->isa($_);
635             }
636             }
637              
638 8         46 require Carp;
639 8         23 &Carp::confess( _failure_msg($name) );
640             }
641              
642              
643             =head2 assert_empty( $this [, $name ] )
644              
645             I<$this> must be a ref to either a hash or an array. Asserts that that
646             collection contains no elements. Will assert (with its own message,
647             not I<$name>) unless given a hash or array ref. It is OK if I<$this> has
648             been blessed into objecthood, but the semantics of checking an object to see
649             if it does not have keys (for a hashref) or returns 0 in scalar context (for
650             an array ref) may not be what you want.
651              
652             assert_empty( 0 ); # FAIL
653             assert_empty( 'foo' ); # FAIL
654             assert_empty( undef ); # FAIL
655             assert_empty( {} ); # pass
656             assert_empty( [] ); # pass
657             assert_empty( {foo=>1} );# FAIL
658             assert_empty( [1,2,3] ); # FAIL
659              
660             =cut
661              
662             sub assert_empty($;$) {
663 13     13 1 10750 my $ref = shift;
664 13         26 my $name = shift;
665              
666 13         17 my $underlying_type;
667 13 100       48 if ( Scalar::Util::blessed( $ref ) ) {
668 6         15 $underlying_type = Scalar::Util::reftype( $ref );
669             }
670             else {
671 7         14 $underlying_type = ref( $ref );
672             }
673              
674 13         24 my $why;
675             my $n;
676 13 100       33 if ( $underlying_type eq 'HASH' ) {
    100          
677 5 100       6 return if scalar keys %{$ref} == 0;
  5         29  
678 3         6 $n = scalar keys %{$ref};
  3         6  
679 3         9 $why = "Hash contains $n key";
680             }
681             elsif ( $underlying_type eq 'ARRAY' ) {
682 5 100       8 return if @{$ref} == 0;
  5         18  
683 3         6 $n = scalar @{$ref};
  3         5  
684 3         10 $why = "Array contains $n element";
685             }
686             else {
687 3         16 $why = 'Argument is not a hash or array.';
688             }
689              
690 9 100 100     40 $why .= 's' if $n && ($n>1);
691 9         15 $why .= '.';
692              
693 9         59 require Carp;
694 9         26 &Carp::confess( _failure_msg($name, $why) );
695             }
696              
697              
698             =head2 assert_nonempty( $this [, $name ] )
699              
700             I<$this> must be a ref to either a hash or an array. Asserts that that
701             collection contains at least 1 element. Will assert (with its own message,
702             not I<$name>) unless given a hash or array ref. It is OK if I<$this> has
703             been blessed into objecthood, but the semantics of checking an object to see
704             if it has keys (for a hashref) or returns >0 in scalar context (for an array
705             ref) may not be what you want.
706              
707             assert_nonempty( 0 ); # FAIL
708             assert_nonempty( 'foo' ); # FAIL
709             assert_nonempty( undef ); # FAIL
710             assert_nonempty( {} ); # FAIL
711             assert_nonempty( [] ); # FAIL
712             assert_nonempty( {foo=>1} );# pass
713             assert_nonempty( [1,2,3] ); # pass
714              
715             =cut
716              
717             sub assert_nonempty($;$) {
718 13     13 1 11113 my $ref = shift;
719 13         24 my $name = shift;
720              
721 13         18 my $underlying_type;
722 13 100       48 if ( Scalar::Util::blessed( $ref ) ) {
723 4         24 $underlying_type = Scalar::Util::reftype( $ref );
724             }
725             else {
726 9         17 $underlying_type = ref( $ref );
727             }
728              
729 13         25 my $why;
730             my $n;
731 13 100       52 if ( $underlying_type eq 'HASH' ) {
    100          
732 4 100       6 return if scalar keys %{$ref} > 0;
  4         18  
733 2         5 $why = "Hash contains 0 keys.";
734             }
735             elsif ( $underlying_type eq 'ARRAY' ) {
736 4 100       7 return if scalar @{$ref} > 0;
  4         25  
737 2         4 $why = "Array contains 0 elements.";
738             }
739             else {
740 5         9 $why = 'Argument is not a hash or array.';
741             }
742              
743 9         47 require Carp;
744 9         27 &Carp::confess( _failure_msg($name, $why) );
745             }
746              
747              
748             =head2 assert_nonref( $this [, $name ] )
749              
750             Asserts that I<$this> is not undef and not a reference.
751              
752             =cut
753              
754             sub assert_nonref($;$) {
755 5     5 1 2735 my $this = shift;
756 5         10 my $name = shift;
757              
758 5         15 assert_defined( $this, $name );
759 4 100       14 return unless ref( $this );
760              
761 1         6 require Carp;
762 1         4 &Carp::confess( _failure_msg($name) );
763             }
764              
765              
766             =head2 assert_hashref( $ref [,$name] )
767              
768             Asserts that I<$ref> is defined, and is a reference to a (possibly empty) hash.
769              
770             B This method returns I for objects, even those whose underlying
771             data is a hashref. This is as it should be, under the assumptions that:
772              
773             =over 4
774              
775             =item (a)
776              
777             you shouldn't rely on the underlying data structure of a particular class, and
778              
779             =item (b)
780              
781             you should use C instead.
782              
783             =back
784              
785             =cut
786              
787             sub assert_hashref($;$) {
788 7     7 1 5291 my $ref = shift;
789 7         16 my $name = shift;
790              
791 7 100 66     48 if ( ref($ref) eq 'HASH' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'HASH' )) ) {
      66        
792 3         13 return;
793             }
794              
795 4         22 require Carp;
796 4         13 &Carp::confess( _failure_msg($name) );
797             }
798              
799              
800             =head2 assert_hashref_nonempty( $ref [,$name] )
801              
802             Asserts that I<$ref> is defined and is a reference to a hash with at
803             least one key/value pair.
804              
805             =cut
806              
807             sub assert_hashref_nonempty($;$) {
808 10     10 1 6671 my $ref = shift;
809 10         16 my $name = shift;
810              
811 10 100 66     64 if ( ref($ref) eq 'HASH' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'HASH' )) ) {
      66        
812 6 100       8 return if scalar keys %{$ref} > 0;
  6         29  
813             }
814              
815 7         41 require Carp;
816 7         15 &Carp::confess( _failure_msg($name) );
817             }
818              
819              
820             =head2 assert_arrayref( $ref [, $name] )
821              
822             =head2 assert_listref( $ref [,$name] )
823              
824             Asserts that I<$ref> is defined, and is a reference to an array, which
825             may or may not be empty.
826              
827             B The same caveat about objects whose underlying structure is a
828             hash (see C) applies here; this method returns false
829             even for objects whose underlying structure is an array.
830              
831             C is an alias for C and may go away in
832             the future. Use C instead.
833              
834             =cut
835              
836             sub assert_arrayref($;$) {
837 13     13 1 8153 my $ref = shift;
838 13         23 my $name = shift;
839              
840 13 100 66     98 if ( ref($ref) eq 'ARRAY' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'ARRAY' )) ) {
      66        
841 5         18 return;
842             }
843              
844 8         45 require Carp;
845 8         27 &Carp::confess( _failure_msg($name) );
846             }
847             *assert_listref = *assert_arrayref;
848              
849              
850             =head2 assert_arrayref_nonempty( $ref [, $name] )
851              
852             Asserts that I<$ref> is reference to an array that has at least one element in it.
853              
854             =cut
855              
856             sub assert_arrayref_nonempty($;$) {
857 11     11 1 6826 my $ref = shift;
858 11         28 my $name = shift;
859              
860 11 100 66     66 if ( ref($ref) eq 'ARRAY' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'ARRAY' )) ) {
      66        
861 7 100       11 return if scalar @{$ref} > 0;
  7         29  
862             }
863              
864 7         36 require Carp;
865 7         23 &Carp::confess( _failure_msg($name) );
866             }
867              
868              
869             =head2 assert_arrayref_of( $ref, $type [, $name] )
870              
871             Asserts that I<$ref> is reference to an array that has at least one
872             element in it, and every one of those elements is of type I<$type>.
873              
874             For example:
875              
876             my @users = get_users();
877             assert_arrayref_of( \@users, 'My::User' );
878              
879             =cut
880              
881             sub assert_arrayref_of($$;$) {
882 10     10 1 6780 my $ref = shift;
883 10         19 my $type = shift;
884 10         14 my $name = shift;
885              
886 10         17 my $ok;
887             my @why;
888              
889 10 100 33     43 if ( ref($ref) eq 'ARRAY' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'ARRAY' )) ) {
      66        
890 6 100       9 if ( scalar @{$ref} > 0 ) {
  6         17  
891 4         5 my $n = 0;
892 4         6 for my $i ( @{$ref} ) {
  4         7  
893 9 100 66     56 if ( !( ( Scalar::Util::blessed( $i ) && $i->isa( $type ) ) || (ref($i) eq $type) ) ) {
      66        
894 2         8 push @why, "Element #$n is not of type $type";
895             }
896 9         19 ++$n;
897             }
898 4         8 $ok = !@why;
899             }
900             else {
901 2         5 push @why, 'Array contains no elements';
902             }
903             }
904              
905 10 100       23 if ( !$ok ) {
906 8         41 require Carp;
907 8         20 &Carp::confess( _failure_msg($name), @why );
908             }
909              
910 2         7 return;
911             }
912              
913              
914             =head2 assert_aoh( $ref [, $name ] )
915              
916             Verifies that C<$array> is an arrayref, and that every element is a hashref.
917              
918             The array C<$array> can be an empty arraref and the assertion will pass.
919              
920             =cut
921              
922             sub assert_aoh {
923 8     8 1 4537 my $ref = shift;
924 8         14 my $name = shift;
925              
926 8         13 my $ok = 0;
927 8 100 66     58 if ( ref($ref) eq 'ARRAY' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'ARRAY' )) ) {
      66        
928 4         9 $ok = 1;
929 4         5 for my $val ( @{$ref} ) {
  4         12  
930 5 50 33     24 if ( not ( ref($val) eq 'HASH' || (Scalar::Util::blessed( $val) && $val->isa( 'HASH' )) ) ) {
      66        
931 2         4 $ok = 0;
932 2         4 last;
933             }
934             }
935             }
936              
937 8 100       24 return if $ok;
938              
939 6         28 require Carp;
940 6         17 &Carp::confess( _failure_msg($name) );
941             }
942              
943              
944             =head2 assert_coderef( $ref [,$name] )
945              
946             Asserts that I<$ref> is defined, and is a reference to a closure.
947              
948             =cut
949              
950             sub assert_coderef($;$) {
951 7     7 1 3609 my $ref = shift;
952 7         13 my $name = shift;
953              
954 7 100 66     51 if ( ref($ref) eq 'CODE' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'CODE' )) ) {
      66        
955 2         6 return;
956             }
957              
958 5         26 require Carp;
959 5         14 &Carp::confess( _failure_msg($name) );
960             }
961              
962              
963             =head1 TYPE-SPECIFIC ASSERTIONS
964              
965             =head2 assert_datetime( $date )
966              
967             Asserts that C<$date> is a DateTime object.
968              
969             =cut
970              
971             sub assert_datetime($;$) {
972 0     0 1 0 my $ref = shift;
973 0         0 my $name = shift;
974              
975 0 0 0     0 if ( ref($ref) eq 'DateTime' || (Scalar::Util::blessed( $ref ) && $ref->isa( 'DateTime' )) ) {
      0        
976 0         0 return;
977             }
978              
979 0         0 require Carp;
980 0         0 &Carp::confess( _failure_msg($name) );
981             }
982              
983              
984             =head1 SET AND HASH MEMBERSHIP
985              
986             =head2 assert_in( $string, \@inlist [,$name] );
987              
988             Asserts that I<$string> matches one of the elements of I<\@inlist>.
989             I<$string> may be undef.
990              
991             I<\@inlist> must be an array reference of non-ref strings. If any
992             element is a reference, the assertion fails.
993              
994             =cut
995              
996             sub assert_in($$;$) {
997 12     12 1 6516 my $needle = shift;
998 12         20 my $haystack = shift;
999 12         18 my $name = shift;
1000              
1001 12         18 my $found = 0;
1002              
1003             # String has to be a non-ref scalar, or undef.
1004 12 50       30 if ( !ref($needle) ) {
1005              
1006             # Target list has to be an array...
1007 12 100 33     43 if ( ref($haystack) eq 'ARRAY' || (Scalar::Util::blessed( $haystack ) && $haystack->isa( 'ARRAY' )) ) {
      66        
1008              
1009             # ... and all elements have to be non-refs.
1010 10         16 my $elements_ok = 1;
1011 10         13 foreach my $element (@{$haystack}) {
  10         20  
1012 28 100       52 if ( ref($element) ) {
1013 1         12 $elements_ok = 0;
1014 1         2 last;
1015             }
1016             }
1017              
1018             # Now we can actually do the search.
1019 10 100       35 if ( $elements_ok ) {
1020 9 100       22 if ( defined($needle) ) {
1021 7         10 foreach my $element (@{$haystack}) {
  7         9  
1022 17 100       34 if ( $needle eq $element ) {
1023 5         6 $found = 1;
1024 5         11 last;
1025             }
1026             }
1027             }
1028             else {
1029 2         13 foreach my $element (@{$haystack}) {
  2         4  
1030 5 100       12 if ( !defined($element) ) {
1031 1         2 $found = 1;
1032 1         2 last;
1033             }
1034             }
1035             }
1036             }
1037             }
1038             }
1039              
1040 12 100       31 return if $found;
1041              
1042 6         34 require Carp;
1043 6         15 &Carp::confess( _failure_msg($name) );
1044             }
1045              
1046              
1047             =head2 assert_exists( \%hash, $key [,$name] )
1048              
1049             =head2 assert_exists( \%hash, \@keylist [,$name] )
1050              
1051             Asserts that I<%hash> is indeed a hash, and that I<$key> exists in
1052             I<%hash>, or that all of the keys in I<@keylist> exist in I<%hash>.
1053              
1054             assert_exists( \%custinfo, 'name', 'Customer has a name field' );
1055              
1056             assert_exists( \%custinfo, [qw( name addr phone )],
1057             'Customer has name, address and phone' );
1058              
1059             =cut
1060              
1061             sub assert_exists($$;$) {
1062 10     10 1 6937 my $hash = shift;
1063 10         19 my $key = shift;
1064 10         12 my $name = shift;
1065              
1066 10         17 my $ok = 0;
1067              
1068 10 50 0     35 if ( ref($hash) eq 'HASH' || (Scalar::Util::blessed( $hash ) && $hash->isa( 'HASH' )) ) {
      33        
1069 10 100       21 if ( defined($key) ) {
1070 9 100       26 if ( ref($key) eq 'ARRAY' ) {
    100          
1071 5         7 $ok = (@{$key} > 0);
  5         13  
1072 5         9 for ( @{$key} ) {
  5         9  
1073 7 100       20 if ( !exists( $hash->{$_} ) ) {
1074 2         10 $ok = 0;
1075 2         4 last;
1076             }
1077             }
1078             }
1079             elsif ( !ref($key) ) {
1080 3         9 $ok = exists( $hash->{$key} );
1081             }
1082             else {
1083 1         7 $ok = 0;
1084             }
1085             }
1086             }
1087              
1088 10 100       25 return if $ok;
1089              
1090 6         41 require Carp;
1091 6         17 &Carp::confess( _failure_msg($name) );
1092             }
1093              
1094              
1095             =head2 assert_lacks( \%hash, $key [,$name] )
1096              
1097             =head2 assert_lacks( \%hash, \@keylist [,$name] )
1098              
1099             Asserts that I<%hash> is indeed a hash, and that I<$key> does NOT exist
1100             in I<%hash>, or that none of the keys in I<@keylist> exist in I<%hash>.
1101             The list C<@keylist> cannot be empty.
1102              
1103             assert_lacks( \%users, 'root', 'Root is not in the user table' );
1104              
1105             assert_lacks( \%users, [qw( root admin nobody )], 'No bad usernames found' );
1106              
1107             =cut
1108              
1109             sub assert_lacks($$;$) {
1110 6     6 1 3042 my $hash = shift;
1111 6         12 my $key = shift;
1112 6         7 my $name = shift;
1113              
1114 6         9 my $ok = 0;
1115              
1116 6 50 0     22 if ( ref($hash) eq 'HASH' || (Scalar::Util::blessed( $hash ) && $hash->isa( 'HASH' )) ) {
      33        
1117 6 50       12 if ( defined($key) ) {
1118 6 100       16 if ( ref($key) eq 'ARRAY' ) {
    50          
1119 4         8 $ok = (@{$key} > 0);
  4         8  
1120 4         5 for ( @{$key} ) {
  4         9  
1121 6 100       14 if ( exists( $hash->{$_} ) ) {
1122 1         1 $ok = 0;
1123 1         3 last;
1124             }
1125             }
1126             }
1127             elsif ( !ref($key) ) {
1128 2         6 $ok = !exists( $hash->{$key} );
1129             }
1130             else {
1131 0         0 $ok = 0;
1132             }
1133             }
1134             }
1135              
1136 6 100       19 return if $ok;
1137              
1138 3         15 require Carp;
1139 3         19 &Carp::confess( _failure_msg($name) );
1140             }
1141              
1142              
1143             =head2 assert_all_keys_in( \%hash, \@names [, $name ] )
1144              
1145             Asserts that each key in C<%hash> is in the list of C<@names>.
1146              
1147             This is used to ensure that there are no extra keys in a given hash.
1148              
1149             assert_all_keys_in( $obj, [qw( height width depth )], '$obj can only contain height, width and depth keys' );
1150              
1151             You can pass an empty list of C<@names>.
1152              
1153             =cut
1154              
1155             sub assert_all_keys_in($$;$) {
1156 9     9 1 5883 my $hash = shift;
1157 9         13 my $keys = shift;
1158 9         18 my $name = shift;
1159              
1160 9         12 my @why;
1161 9         16 my $ok = 0;
1162 9 100 33     43 if ( ref($hash) eq 'HASH' || (Scalar::Util::blessed( $hash ) && $hash->isa( 'HASH' )) ) {
      66        
1163 8 100       20 if ( ref($keys) eq 'ARRAY' ) {
1164 7         13 $ok = 1;
1165 7         9 my %keys = map { $_ => 1 } @{$keys};
  15         70  
  7         16  
1166 7         16 for my $key ( keys %{$hash} ) {
  7         33  
1167 18 100       43 if ( !exists $keys{$key} ) {
1168 9         14 $ok = 0;
1169 9         24 push @why, qq{Key "$key" is not a valid key.};
1170             }
1171             }
1172             }
1173             else {
1174 1         7 push @why, 'Argument for array of keys is not an arrayref.';
1175             }
1176             }
1177             else {
1178 1         14 push @why, 'Argument for hash is not a hashref.';
1179             }
1180              
1181 9 100       33 return if $ok;
1182              
1183 6         31 require Carp;
1184 6         17 &Carp::confess( _failure_msg($name, @why) );
1185             }
1186              
1187              
1188             =head2 assert_keys_are( \%hash, \@keys [, $name ] )
1189              
1190             Asserts that the keys for C<%hash> are exactly C<@keys>, no more and no less.
1191              
1192             =cut
1193              
1194             sub assert_keys_are($$;$) {
1195 15     15 1 10877 my $hash = shift;
1196 15         23 my $keys = shift;
1197 15         23 my $name = shift;
1198              
1199 15         21 my @why;
1200 15         23 my $ok = 0;
1201 15 100 33     68 if ( ref($hash) eq 'HASH' || (Scalar::Util::blessed( $hash ) && $hash->isa( 'HASH' )) ) {
      66        
1202 14 100       33 if ( ref($keys) eq 'ARRAY' ) {
1203 13         15 my %keys = map { $_ => 1 } @{$keys};
  38         86  
  13         27  
1204              
1205             # First check all the keys are allowed.
1206 13         33 $ok = 1;
1207 13         20 for my $key ( keys %{$hash} ) {
  13         36  
1208 33 100       69 if ( !exists $keys{$key} ) {
1209 16         22 $ok = 0;
1210 16         42 push @why, qq{Key "$key" is not a valid key.};
1211             }
1212             }
1213              
1214             # Now check that all the valid keys are represented.
1215 13         25 for my $key ( @{$keys} ) {
  13         21  
1216 38 100       83 if ( !exists $hash->{$key} ) {
1217 21         25 $ok = 0;
1218 21         47 push @why, qq{Key "$key" is not in the hash.};
1219             }
1220             }
1221             }
1222             else {
1223 1         3 push @why, 'Argument for array of keys is not an arrayref.';
1224             }
1225             }
1226             else {
1227 1         2 push @why, 'Argument for hash is not a hashref.';
1228             }
1229              
1230 15 100       41 return if $ok;
1231              
1232 12         59 require Carp;
1233 12         29 &Carp::confess( _failure_msg($name, @why) );
1234             }
1235              
1236              
1237             =head1 CONTEXT ASSERTIONS
1238              
1239             =head2 assert_context_nonvoid( [$name] )
1240              
1241             Verifies that the function currently being executed has not been called
1242             in void context. This is to ensure the calling function is not ignoring
1243             the return value of the executing function.
1244              
1245             Given this function:
1246              
1247             sub something {
1248             ...
1249              
1250             assert_context_scalar();
1251              
1252             return $important_value;
1253             }
1254              
1255             These calls to C will pass:
1256              
1257             my $val = something();
1258             my @things = something();
1259              
1260             but this will fail:
1261              
1262             something();
1263              
1264             =cut
1265              
1266             sub assert_context_nonvoid(;$) {
1267 3     3 1 1831 my $name = shift;
1268              
1269 3         22 my $wantarray = (caller(1))[5];
1270              
1271 3 100       13 return if defined($wantarray);
1272              
1273 1         5 require Carp;
1274 1         4 &Carp::confess( _failure_msg($name) );
1275             }
1276              
1277              
1278             =head2 assert_context_scalar( [$name] )
1279              
1280             Verifies that the function currently being executed has been called in
1281             scalar context. This is to ensure the calling function is not ignoring
1282             the return value of the executing function.
1283              
1284             Given this function:
1285              
1286             sub something {
1287             ...
1288              
1289             assert_context_scalar();
1290              
1291             return $important_value;
1292             }
1293              
1294             This call to C will pass:
1295              
1296             my $val = something();
1297              
1298             but these will fail:
1299              
1300             something();
1301             my @things = something();
1302              
1303             =cut
1304              
1305             sub assert_context_scalar(;$) {
1306 3     3 1 1946 my $name = shift;
1307              
1308 3         22 my $wantarray = (caller(1))[5];
1309              
1310 3 100 100     23 return if defined($wantarray) && !$wantarray;
1311              
1312 2         12 require Carp;
1313 2         5 &Carp::confess( _failure_msg($name) );
1314             }
1315              
1316              
1317             =head1 UTILITY ASSERTIONS
1318              
1319             =head2 assert_fail( [$name] )
1320              
1321             Assertion that always fails. C is exactly the same
1322             as calling C, but it eliminates that case where you
1323             accidentally use C, which of course never fires.
1324              
1325             =cut
1326              
1327             sub assert_fail(;$) {
1328 1     1 1 97 require Carp;
1329 1         5 &Carp::confess( _failure_msg($_[0]) );
1330             }
1331              
1332              
1333             # Can't call confess() here or the stack trace will be wrong.
1334             sub _failure_msg {
1335 295     295   659 my ($name, @why) = @_;
1336              
1337 295         516 my $msg = 'Assertion';
1338 295 100       771 $msg .= " ($name)" if defined $name;
1339 295         692 $msg .= " failed!\n";
1340 295         848 $msg .= "$_\n" for @why;
1341              
1342 295         15401 return $msg;
1343             }
1344              
1345              
1346             =head1 COPYRIGHT & LICENSE
1347              
1348             Copyright 2005-2023 Andy Lester
1349              
1350             This program is free software; you can redistribute it and/or modify
1351             it under the terms of the Artistic License version 2.0.
1352              
1353             =head1 ACKNOWLEDGEMENTS
1354              
1355             Thanks to
1356             Eric A. Zarko,
1357             Bob Diss,
1358             Pete Krawczyk,
1359             David Storrs,
1360             Dan Friedman,
1361             Allard Hoeve,
1362             Thomas L. Shinnick,
1363             and Leland Johnson
1364             for code and fixes.
1365              
1366             =cut
1367              
1368             1;