Carp::Assert::More - Convenience assertions for common situations
Version 2.5.0
A set of convenience functions for common assertions.
use Carp::Assert::More;
my $obj = My::Object;
assert_isa( $obj, 'My::Object', 'Got back a correct object' );
Carp::Assert::More is a convenient set of assertions to make the habit of writing assertions even easier.
Everything in here is effectively syntactic sugar. There's no technical difference between calling one of these functions:
assert_datetime( $foo );
assert_isa( $foo, 'DateTime' );
that are provided by Carp::Assert::More and calling these assertions from Carp::Assert
assert( defined $foo );
assert( ref($foo) eq 'DateTime' );
My intent here is to make common assertions easy so that we as programmers have no excuse to not use them.
Asserts that $string is the same string value as $match.
undef
is not converted to an empty string. If both strings are undef
, they match. If only one string is undef
, they don't match.
Asserts that $string does NOT have the same string value as $unmatch.
undef
is not converted to an empty string.
Asserts that the relation $x $op $y
is true. It lets you know why the comparsison failed, rather than simply that it did fail, by giving better diagnostics than a plain assert()
, as well as showing the operands in the stacktrace.
Plain assert()
:
assert( $nitems <= 10, 'Ten items or fewer in the express lane' );
Assertion (Ten items or fewer in the express lane) failed!
Carp::Assert::assert("", "Ten items or fewer in the express lane") called at foo.pl line 12
With assert_cmp()
:
assert_cmp( $nitems, '<=', 10, 'Ten items or fewer in the express lane' );
Assertion (Ten items or fewer in the express lane) failed!
Failed: 14 <= 10
Carp::Assert::More::assert_cmp(14, "<=", 10, "Ten items or fewer in the express lane") called at foo.pl line 11
The following operators are supported:
== numeric equal
!= numeric not equal
> numeric greater than
>= numeric greater than or equal
< numeric less than
<= numeric less than or equal
lt string less than
le string less than or equal
gt string less than
ge string less than or equal
There is no support for eq
or ne
because those already have assert_is
and assert_isnt
, respectively.
If either $x
or $y
is undef, the assertion will fail.
If the operator is numeric, and $x
or $y
are not numbers, the assertion will fail.
Asserts that $string matches qr/regex/.
The assertion fails either the string or the regex are undef.
Asserts that $string matches qr/regex/.
The assertion fails if the regex is undef.
Asserts that $this is defined.
Asserts that $this is not defined.
Asserts that $this is not a reference and is not an empty string.
Asserts that $n
looks like a number, according to Scalar::Util::looks_like_number
. undef
will always fail.
Asserts that $this is an integer, which may be zero or negative.
assert_integer( 0 ); # pass
assert_integer( 14 ); # pass
assert_integer( -14 ); # pass
assert_integer( '14.' ); # FAIL
Asserts that the numeric value of $this is defined and is not zero.
assert_nonzero( 0 ); # FAIL
assert_nonzero( -14 ); # pass
assert_nonzero( '14.' ); # pass
Asserts that $this is defined, numeric and greater than zero.
assert_positive( 0 ); # FAIL
assert_positive( -14 ); # FAIL
assert_positive( '14.' ); # pass
Asserts that $this is defined, numeric and greater than or equal to zero.
assert_nonnegative( 0 ); # pass
assert_nonnegative( -14 ); # FAIL
assert_nonnegative( '14.' ); # pass
assert_nonnegative( 'dog' ); # pass
Asserts that the numeric value of $this is defined and less than zero.
assert_negative( 0 ); # FAIL
assert_negative( -14 ); # pass
assert_negative( '14.' ); # FAIL
Asserts that the numeric value of $this is defined, an integer, and not zero.
assert_nonzero_integer( 0 ); # FAIL
assert_nonzero_integer( -14 ); # pass
assert_nonzero_integer( '14.' ); # FAIL
Asserts that the numeric value of $this is defined, an integer and greater than zero.
assert_positive_integer( 0 ); # FAIL
assert_positive_integer( -14 ); # FAIL
assert_positive_integer( '14.' ); # FAIL
assert_positive_integer( '14' ); # pass
Asserts that the numeric value of $this is defined, an integer, and not less than zero.
assert_nonnegative_integer( 0 ); # pass
assert_nonnegative_integer( -14 ); # FAIL
assert_nonnegative_integer( '14.' ); # FAIL
Asserts that the numeric value of $this is defined, an integer, and less than zero.
assert_negative_integer( 0 ); # FAIL
assert_negative_integer( -14 ); # pass
assert_negative_integer( '14.' ); # FAIL
Asserts that $this is an object of type $type.
Assert that the blessed $obj
isa one of the types in \@types
.
assert_isa_in( $obj, [ 'My::Foo', 'My::Bar' ], 'Must pass either a Foo or Bar object' );
$this must be a ref to either a hash or an array. Asserts that that collection contains no elements. Will assert (with its own message, not $name) unless given a hash or array ref. It is OK if $this has been blessed into objecthood, but the semantics of checking an object to see if it does not have keys (for a hashref) or returns 0 in scalar context (for an array ref) may not be what you want.
assert_empty( 0 ); # FAIL
assert_empty( 'foo' ); # FAIL
assert_empty( undef ); # FAIL
assert_empty( {} ); # pass
assert_empty( [] ); # pass
assert_empty( {foo=>1} );# FAIL
assert_empty( [1,2,3] ); # FAIL
$this must be a ref to either a hash or an array. Asserts that that collection contains at least 1 element. Will assert (with its own message, not $name) unless given a hash or array ref. It is OK if $this has been blessed into objecthood, but the semantics of checking an object to see if it has keys (for a hashref) or returns >0 in scalar context (for an array ref) may not be what you want.
assert_nonempty( 0 ); # FAIL
assert_nonempty( 'foo' ); # FAIL
assert_nonempty( undef ); # FAIL
assert_nonempty( {} ); # FAIL
assert_nonempty( [] ); # FAIL
assert_nonempty( {foo=>1} );# pass
assert_nonempty( [1,2,3] ); # pass
Asserts that $this is not undef and not a reference.
Asserts that $ref is defined, and is a reference to a (possibly empty) hash.
NB: This method returns false for objects, even those whose underlying data is a hashref. This is as it should be, under the assumptions that:
you shouldn't rely on the underlying data structure of a particular class, and
you should use assert_isa
instead.
Asserts that $ref is defined and is a reference to a hash with at least one key/value pair.
Asserts that $ref is defined, and is a reference to an array, which may or may not be empty.
NB: The same caveat about objects whose underlying structure is a hash (see assert_hashref
) applies here; this method returns false even for objects whose underlying structure is an array.
assert_listref
is an alias for assert_arrayref
and may go away in the future. Use assert_arrayref
instead.
Asserts that $ref is reference to an array that has at least one element in it.
Asserts that $ref is reference to an array that has at least one element in it, and every one of those elements is of type $type.
For example:
my @users = get_users();
assert_arrayref_of( \@users, 'My::User' );
Asserts that $aref is reference to an array that has at least one element in it. Each element of the array is passed to subroutine $sub which is assumed to be an assertion.
For example:
my $aref_of_counts = get_counts();
assert_arrayref_all( $aref, \&assert_positive_integer, 'Counts are positive' );
Whatever is passed as $name, a string saying "Element #N" will be appended, where N is the zero-based index of the array.
Verifies that $array
is an arrayref, and that every element is a hashref.
The array $array
can be an empty arraref and the assertion will pass.
Asserts that $ref is defined, and is a reference to a closure.
Asserts that $date
is a DateTime object.
Asserts that $string matches one of the elements of \@inlist. $string may be undef.
\@inlist must be an array reference of non-ref strings. If any element is a reference, the assertion fails.
Asserts that %hash is indeed a hash, and that $key exists in %hash, or that all of the keys in @keylist exist in %hash.
assert_exists( \%custinfo, 'name', 'Customer has a name field' );
assert_exists( \%custinfo, [qw( name addr phone )],
'Customer has name, address and phone' );
Asserts that %hash is indeed a hash, and that $key does NOT exist in %hash, or that none of the keys in @keylist exist in %hash. The list @keylist
cannot be empty.
assert_lacks( \%users, 'root', 'Root is not in the user table' );
assert_lacks( \%users, [qw( root admin nobody )], 'No bad usernames found' );
Asserts that each key in %hash
is in the list of @names
.
This is used to ensure that there are no extra keys in a given hash.
assert_all_keys_in( $obj, [qw( height width depth )], '$obj can only contain height, width and depth keys' );
You can pass an empty list of @names
.
Asserts that the keys for %hash
are exactly @keys
, no more and no less.
Verifies that the function currently being executed has not been called in void context. This is to ensure the calling function is not ignoring the return value of the executing function.
Given this function:
sub something {
...
assert_context_nonvoid();
return $important_value;
}
These calls to something
will pass:
my $val = something();
my @things = something();
but this will fail:
something();
If the $name
argument is not passed, a default message of "<funcname> must not be called in void context" is provided.
Verifies that the function currently being executed has been called in void context. This is for functions that do not return anything meaningful.
Given this function:
sub something {
...
assert_context_void();
return; # No meaningful value.
}
These calls to something
will fail:
my $val = something();
my @things = something();
but this will pass:
something();
If the $name
argument is not passed, a default message of "<funcname> must be called in void context" is provided.
Verifies that the function currently being executed has been called in scalar context. This is to ensure the calling function is not ignoring the return value of the executing function.
Given this function:
sub something {
...
assert_context_scalar();
return $important_value;
}
This call to something
will pass:
my $val = something();
but these will fail:
something();
my @things = something();
If the $name
argument is not passed, a default message of "<funcname> must be called in scalar context" is provided.
Verifies that the function currently being executed has been called in list context.
Given this function:
sub something {
...
assert_context_scalar();
return @values;
}
This call to something
will pass:
my @vals = something();
but these will fail:
something();
my $thing = something();
If the $name
argument is not passed, a default message of "<funcname> must be called in list context" is provided.
Assertion that always fails. assert_fail($msg)
is exactly the same as calling assert(0,$msg)
, but it eliminates that case where you accidentally use assert($msg)
, which of course never fires.
Copyright 2005-2024 Andy Lester
This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.
Thanks to Eric A. Zarko, Bob Diss, Pete Krawczyk, David Storrs, Dan Friedman, Allard Hoeve, Thomas L. Shinnick, and Leland Johnson for code and fixes.