File Coverage

blib/lib/Carp/Assert/More.pm
Criterion Covered Total %
statement 386 393 98.2
branch 220 228 96.4
condition 129 185 69.7
subroutine 46 47 97.8
pod 38 38 100.0
total 819 891 91.9


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