view release on metacpan or search on metacpan
Method-related assertions now require a blessed invocant or a known package.
Don't carp if we're throwing an exception and exceptions are trapped.
Support more than one word in ASSERT_CONDITIONAL (eg: "carp,always").
If ASSERT_CONDITIONAL contains "handlers", don't block @SIG{__{WARN,DIE}__}.
Don't let assert_isa die prematurely on an unblessed ref.
0.005 Sun May 20 20:40:25 CDT 2018
Initial beta release.
Reworked the hash key checkers into a simpler set: assert_keys, assert_min_keys, assert_max_keys, assert_minmax_keys.
Added invocant-specific assertions: assert_{object,class}_{isa,ainta,can,cant}.
Added assertions for ties, overloads, and locked hashes.
Made assert_private_method work despite Moose wrappers.
Added assert_protected_method that works despite Moose wrappers and roles.
Improved the looks of the uncompiled code for assert_happy_code.
Improved the reporting of some assertion failures.
0.006 Mon May 21 07:45:43 CDT 2018
Use hash_{,un}locked not hashref_{,un}locked to support pre-5.16 perls.
Unhid assert_unblessed_ref swallowed up by stray pod.
0.007 Mon May 21 19:13:58 CDT 2018
Add missing Hash::Util version requirement for old perls to get hashref_unlock imported.
0.008 Tue May 22 11:51:37 CDT 2018
Rewrite hash_unlocked missing till 5.16 as !hash_locked
Add omitted etc/generate-exporter-pod to MANIFEST
0.009 Tue Aug 21 06:29:56 MDT 2018
Delay slow calls to uca_sort till you really need them, credit Larry Leszczynski.
0.010 Sun Jul 19 13:52:00 MDT 2020
Fix coredump in perl 5.12 by replacing UNITCHECK in Assert::Conditional::Util with normal execution at botton.
Make perls below 5.18 work again by setting Hash::Util prereq in Makefile.PL to 0 because it's in the core only, never cpan.
Only provide assert_locked and assert_unlocked if core Hash::Util v0.15 is there (starting perl v5.17).
Bump version req of parent class Exporter::ConditionalSubs to v1.11.1 so we don't break Devel::Cover.
Normalize Export sub attribute tracing so either $Exporter::Verbose=1 or env ASSERT_CONDITIONAL_DEBUG=1 work for both Assert::Conditional{,::Utils}.
Mentioned $Exporter::Verbose support.
lib/Assert/Conditional.pm view on Meta::CPAN
sub assert_isa ( $@ ) ;
sub assert_isnt ( $$ ) ;
sub assert_keys ( \[%$] @ ) ;
sub assert_known_package ( $ ) ;
sub assert_latin1 ( $ ) ;
sub assert_latinish ( $ ) ;
sub assert_legal_exit_status ( ;$ ) ;
sub assert_like ( $$ ) ;
sub assert_list_context ( ) ;
sub assert_list_nonempty ( @ ) ;
sub assert_locked ( \[%$] @ ) ;
sub assert_lowercased ( $ ) ;
sub assert_max_keys ( \[%$] @ ) ;
sub assert_method ( ) ;
sub assert_min_keys ( \[%$] @ ) ;
sub assert_minmax_keys ( \[%$] \[@$] \[@$] ) ;
sub assert_multi_line ( $ ) ;
sub assert_natural_number ( $ ) ;
sub assert_negative ( $ ) ;
sub assert_negative_integer ( $ ) ;
sub assert_nfc ( $ ) ;
lib/Assert/Conditional.pm view on Meta::CPAN
sub assert_tied_hashref ( $ ) ;
sub assert_tied_referent ( $ ) ;
sub assert_tied_scalar ( \$ ) ;
sub assert_tied_scalarref ( $ ) ;
sub assert_true ( $ ) ;
sub assert_unblessed_ref ( $ ) ;
sub assert_undefined ( $ ) ;
sub assert_unhappy_code ( & ) ;
sub assert_unicode_ident ( $ ) ;
sub assert_unlike ( $$ ) ;
sub assert_unlocked ( \[%$] @ ) ;
sub assert_unsignalled ( ;$ ) ;
sub assert_untied ( \[$@%*] ) ;
sub assert_untied_array ( \@ ) ;
sub assert_untied_arrayref ( $ ) ;
sub assert_untied_glob ( \* ) ;
sub assert_untied_globref ( $ ) ;
sub assert_untied_hash ( \% ) ;
sub assert_untied_hashref ( $ ) ;
sub assert_untied_referent ( $ ) ;
sub assert_untied_scalar ( \$ ) ;
lib/Assert/Conditional.pm view on Meta::CPAN
sub assert_hashref_keys_allowed_and_required($$$)
:Assert( qw[hash] )
{
my($hashref, $allowed, $required) = @_;
assert_minmax_keys($hashref, $required, $allowed);
}
# From perl5180delta, you couldn't actually get any use of
# the predicates to check whether a hash or hashref was
# locked because even though they were exported those
# function did not exist before.!
##
## * Hash::Util has been upgraded to 0.15.
##
## "hash_unlocked" and "hashref_unlocked" now returns true if the hash
## is unlocked, instead of always returning false [perl #112126].
##
## "hash_unlocked", "hashref_unlocked", "lock_hash_recurse" and
## "unlock_hash_recurse" are now exportable [perl #112126].
##
## Two new functions, "hash_locked" and "hashref_locked", have been
## added. Oddly enough, these two functions were already exported,
## even though they did not exist [perl #112126].
BEGIN {
use Hash::Util qw{hash_locked};
my $want_version = 0.15;
my $have_version = Hash::Util->VERSION;
my $huv = "v$have_version of Hash::Util and we need";
my $compiling = "compiling assert_lock and assert_unlocked because your perl $^V has";
my $debugging = $Exporter::Verbose || $Assert_Debug;
if ($have_version < $want_version) {
carp "Not $compiling only $huv v$want_version at ", __FILE__, " line ", __LINE__ if $debugging;
} else {
carp "\u$compiling $huv only v$want_version at ", __FILE__, " line ", __LINE__ if $debugging;
confess "compilation eval blew up: $@" unless eval <<'END_OF_LOCK_STUFF';
sub assert_locked( \[%$] @ )
:Assert( qw[hash] )
{
my($hashref) = @_;
_promote_to_hashref($hashref);
hash_locked(%$hashref) || botch "hash is locked";
}
sub assert_unlocked( \[%$] @ )
:Assert( qw[hash] )
{
my($hashref) = @_;
_promote_to_hashref($hashref);
!hash_locked(%$hashref) || botch "hash is not locked";
}
1;
END_OF_LOCK_STUFF
}
}
sub assert_anyref($)
:Assert( qw[ref] )
lib/Assert/Conditional.pm view on Meta::CPAN
assert_isa ( $@ ) ;
assert_isnt ( $$ ) ;
assert_keys ( \[%$] @ ) ;
assert_known_package ( $ ) ;
assert_latin1 ( $ ) ;
assert_latinish ( $ ) ;
assert_legal_exit_status ( ;$ ) ;
assert_like ( $$ ) ;
assert_list_context ( ) ;
assert_list_nonempty ( @ ) ;
assert_locked ( \[%$] @ ) ;
assert_lowercased ( $ ) ;
assert_max_keys ( \[%$] @ ) ;
assert_method ( ) ;
assert_min_keys ( \[%$] @ ) ;
assert_minmax_keys ( \[%$] \[@$] \[@$] ) ;
assert_multi_line ( $ ) ;
assert_natural_number ( $ ) ;
assert_negative ( $ ) ;
assert_negative_integer ( $ ) ;
assert_nfc ( $ ) ;
lib/Assert/Conditional.pm view on Meta::CPAN
assert_tied_hashref ( $ ) ;
assert_tied_referent ( $ ) ;
assert_tied_scalar ( \$ ) ;
assert_tied_scalarref ( $ ) ;
assert_true ( $ ) ;
assert_unblessed_ref ( $ ) ;
assert_undefined ( $ ) ;
assert_unhappy_code ( & ) ;
assert_unicode_ident ( $ ) ;
assert_unlike ( $$ ) ;
assert_unlocked ( \[%$] @ ) ;
assert_unsignalled ( ;$ ) ;
assert_untied ( \[$@%*] ) ;
assert_untied_array ( \@ ) ;
assert_untied_arrayref ( $ ) ;
assert_untied_glob ( \* ) ;
assert_untied_globref ( $ ) ;
assert_untied_hash ( \% ) ;
assert_untied_hashref ( $ ) ;
assert_untied_referent ( $ ) ;
assert_untied_scalar ( \$ ) ;
lib/Assert/Conditional.pm view on Meta::CPAN
L</assert_hash_nonempty>, L</assert_hashref>, L</assert_hashref_keys>,
L</assert_hashref_keys_allowed>,
L</assert_hashref_keys_allowed_and_required>,
L</assert_hashref_keys_required>,
L</assert_hashref_keys_required_and_allowed>, L</assert_hashref_nonempty>,
L</assert_hex_number>, L</assert_in_list>, L</assert_in_numeric_range>,
L</assert_integer>, L</assert_ioref>, L</assert_is>, L</assert_isa>,
L</assert_isnt>, L</assert_keys>, L</assert_known_package>,
L</assert_latin1>, L</assert_latinish>, L</assert_legal_exit_status>,
L</assert_like>, L</assert_list_context>, L</assert_list_nonempty>,
L</assert_locked>, L</assert_lowercased>, L</assert_max_keys>,
L</assert_method>, L</assert_min_keys>, L</assert_minmax_keys>,
L</assert_multi_line>, L</assert_natural_number>, L</assert_negative>,
L</assert_negative_integer>, L</assert_nfc>, L</assert_nfd>,
L</assert_nfkc>, L</assert_nfkd>, L</assert_no_coredump>,
L</assert_nonalphabetic>, L</assert_nonascii>, L</assert_nonastral>,
L</assert_nonblank>, L</assert_nonbytes>, L</assert_nonempty>,
L</assert_nonlist_context>, L</assert_nonnegative>,
L</assert_nonnegative_integer>, L</assert_nonnumeric>,
L</assert_nonobject>, L</assert_nonpositive>,
L</assert_nonpositive_integer>, L</assert_nonref>,
lib/Assert/Conditional.pm view on Meta::CPAN
L</assert_reftype>, L</assert_regex>, L</assert_regular_file>,
L</assert_sad_exit>, L</assert_scalar_context>, L</assert_scalarref>,
L</assert_signalled>, L</assert_signed_number>,
L</assert_simple_perl_ident>, L</assert_single_line>,
L</assert_single_paragraph>, L</assert_text_file>, L</assert_tied>,
L</assert_tied_array>, L</assert_tied_arrayref>, L</assert_tied_glob>,
L</assert_tied_globref>, L</assert_tied_hash>, L</assert_tied_hashref>,
L</assert_tied_referent>, L</assert_tied_scalar>,
L</assert_tied_scalarref>, L</assert_true>, L</assert_unblessed_ref>,
L</assert_undefined>, L</assert_unhappy_code>, L</assert_unicode_ident>,
L</assert_unlike>, L</assert_unlocked>, L</assert_unsignalled>,
L</assert_untied>, L</assert_untied_array>, L</assert_untied_arrayref>,
L</assert_untied_glob>, L</assert_untied_globref>, L</assert_untied_hash>,
L</assert_untied_hashref>, L</assert_untied_referent>,
L</assert_untied_scalar>, L</assert_untied_scalarref>,
L</assert_uppercased>, L</assert_void_context>, L</assert_whole_number>,
L</assert_wide_characters>, and L</assert_zero>.
=item C<:argc>
L</assert_argc>, L</assert_argc_max>, L</assert_argc_min>, and
lib/Assert/Conditional.pm view on Meta::CPAN
=item C<:hash>
L</assert_hash_keys>, L</assert_hash_keys_allowed>,
L</assert_hash_keys_allowed_and_required>, L</assert_hash_keys_required>,
L</assert_hash_keys_required_and_allowed>, L</assert_hash_nonempty>,
L</assert_hashref>, L</assert_hashref_keys>,
L</assert_hashref_keys_allowed>,
L</assert_hashref_keys_allowed_and_required>,
L</assert_hashref_keys_required>,
L</assert_hashref_keys_required_and_allowed>, L</assert_hashref_nonempty>,
L</assert_keys>, L</assert_locked>, L</assert_max_keys>,
L</assert_min_keys>, L</assert_minmax_keys>, L</assert_tied_hash>,
L</assert_tied_hashref>, L</assert_unlocked>, L</assert_untied_hash>,
and L</assert_untied_hashref>.
=item C<:ident>
L</assert_ascii_ident>, L</assert_full_perl_ident>,
L</assert_known_package>, L</assert_qualified_ident>, and
L</assert_simple_perl_ident>.
=item C<:io>
lib/Assert/Conditional.pm view on Meta::CPAN
lock_keys(%some_hash);
or
use Hash::Util qw(lock_ref_keys);
my @exact_keys = qw[larry moe curly];
assert_keys($some_hashref, @exact_keys);
lock_ref_keys($some_hashref);
Now the I<keys> are locked down to keep your honest, although
the I<values> can be still be changed. See L<Hash::Util>.
=item assert_min_keys(I<HASH> | I<HASHREF>, I<KEY_LIST>)
=for comment
This is a workaround to create a "blank" line so that the code sample is distinct.
Z<>
assert_min_keys(%hash, qw[blue green red]);
lib/Assert/Conditional.pm view on Meta::CPAN
assert_minmax_keys(%hash, $minmax[0], $minmax[1]);
assert_minmax_keys($hashref, $minmax[0], $minmax[1]);
If you're careful to pass three refs of the right sorts in, you can
actually use this if you circumvent prototype checking:
&assert_minmax_keys(\%hash, @minmax);
&assert_minmax_keys( $hashref, @minmax);
=item assert_locked(I<HASH> | I<HASHREF>)
=for comment
This is a workaround to create a "blank" line.
Z<>
B<WARNING>: Only available under version 0.15 and greater of L<Hash::Util,> first found in perl v5.17.
assert_locked(%hash);
assert_locked($hashref);
assert_locked($array_of_hashes[0]);
assert_locked($arrayref_of_hashes->[0]);
assert_locked($hash_of_hashes{FIELD});
assert_locked($hashref_of_hashes->{FIELD});
The argument, which must be either a hash variable or else a scalar
variable holding a hashref, must have locked keys.
=item assert_unlocked(I<HASH> | I<HASHREF>)
=for comment
This is a workaround to create a "blank" line.
Z<>
B<WARNING>: Only available under version 0.15 and greater of L<Hash::Util>, first found in perl v5.17.
assert_unlocked(%hash);
assert_unlocked($hashref);
assert_unlocked($array_of_hashes[0]);
assert_unlocked($arrayref_of_hashes->[0]);
assert_unlocked($hash_of_hashes{FIELD});
assert_unlocked($hashref_of_hashes->{FIELD});
The argument, which must be either a hash variable or else a scalar
variable holding a hashref, must not have locked keys.
=back
=head2 Legacy Assertions about Hashes
You should usually prefer L</assert_keys>, L</assert_min_keys>,
L</assert_max_keys>, and L</assert_minmax_keys> over the assertions in this
section, since those have better names and aren't so finicky about their
first argument. The following assertions are retained for backwards
compatibility, but internally they all turn into one of those four.
lib/Assert/Conditional.pm view on Meta::CPAN
- Suppress overloading in botch messages for object-related assertions (but not others).
- Don't carp if we're throwing an exception and exceptions are trapped.
- Support more than one word in ASSERT_CONDITIONAL (eg: "carp,always").
- If ASSERT_CONDITIONAL contains "handlers", don't block @SIG{__{WARN,DIE}__}.
- Don't let assert_isa die prematurely on an unblessed ref.
0.005 Sun May 20 20:40:25 CDT 2018
- Initial beta release.
- Reworked the hash key checkers into a simpler set: assert_keys, assert_min_keys, assert_max_keys, assert_minmax_keys.
- Added invocant-specific assertions: assert_{object,class}_{isa,ainta,can,cant}.
- Added assertions for ties, overloads, and locked hashes.
- Made assert_private_method work despite Moose wrappers.
- Added assert_protected_method that works despite Moose wrappers and roles.
- Improved the looks of the uncompiled code for assert_happy_code.
- Fixed botch() to identify the most distant stack frame not the nearest for the name of the failed assertion.
- Improved the reporting of some assertion failures.
0.006 Mon May 21 07:45:43 CDT 2018
- Use hash_{,un}locked not hashref_{,un}locked to support pre-5.16 perls.
- Unhid assert_unblessed_ref swallowed up by stray pod.
0.007 Mon May 21 19:13:58 CDT 2018
- Add missing Hash::Util version requirement for old perls to get hashref_unlock imported.
0.008 Tue May 22 11:51:37 CDT 2018
- Rewrite hash_unlocked missing till 5.16 as !hash_locked
- Add omitted etc/generate-exporter-pod to MANIFEST
0.009 Tue Aug 21 06:29:56 MDT 2018
- Delay slow calls to uca_sort till you really need them, credit Larry Leszczynski.
0.010 Sun Jul 19 13:52:00 MDT 2020
- Fix coredump in perl 5.12 by replacing UNITCHECK in Assert::Conditional::Util with normal execution at botton.
- Make perls below 5.18 work again by setting Hash::Util prereq in Makefile.PL to 0 because it's in the core only, never cpan.
- Only provide assert_locked and assert_unlocked if core Hash::Util v0.15 is there (starting perl v5.17).
- Bump version req of parent class Exporter::ConditionalSubs to v1.11.1 so we don't break Devel::Cover.
- Normalize Export sub attribute tracing so either $Exporter::Verbose=1 or env ASSERT_CONDITIONAL_DEBUG=1 work for both Assert::Conditional{,::Utils}.
- Mentioned $Exporter::Verbose support.
=head1 AUTHOR
Tom Christiansen C<< <tchrist53147@gmail.com> >>
Thanks to Larry Leszczynski at Grant Street Group for making this module
possible. Without it, my programs would be much slower, since before I
t/asserts.t view on Meta::CPAN
my @ten = (1 .. 10);
my $class = "IO::File";
my $obj = $class->new();
my @primary_colors = qw(red green blue);
my @all_colors = (@primary_colors, qw(orange yellow cyan violet));
my @not_colors = qw(black white pink purple);
my %primary_color = map { $_ => 1 } @primary_colors;
my $primary_color_ref = \%primary_color;
my %locked_hash = %primary_color;
my $locked_hashref = \%locked_hash;
lock_keys %locked_hash;
my %unlocked_hash = %primary_color;
my $unlocked_hashref = \%unlocked_hash;
my %hash_of_hashes = (
LOCKED => $locked_hashref,
UNLOCKED => $unlocked_hashref,
);
my $hashref_of_hashes = \%hash_of_hashes;
my $ref_of_hashref_of_hashes = \\%hash_of_hashes;
my $bignum = Math::BigInt->new("1000");
my $tied_object = do {
no warnings "once";
tie *Tied_FH, "TieOut";
t/asserts.t view on Meta::CPAN
my $hu_version = Hash::Util->VERSION;
my %is_exported = map { $_ => 1 } (
@Assert::Conditional::EXPORT,
@Assert::Conditional::EXPORT_OK,
);
cmp_ok scalar keys %is_exported, ">", 50, "we exported at least 50 functions";
my @lock_assertions = qw(assert_locked assert_unlocked);
my $lock_tests = commify_and @lock_assertions;
if ($hu_version < 0.15) {
diag "Omitting tests for $lock_tests because Hash::Util version is only v$hu_version but we need v0.15";
for my $subname (@lock_assertions) {
is($is_exported{$subname}, undef, "$subname is not exported under $hu_version");
}
}
else {
diag "Including assert tests for $lock_tests because Hash::Util version is v$hu_version and we need only v0.15";
for my $subname (@lock_assertions) {
is $is_exported{$subname}, 1, "$subname is exported under $hu_version";
}
push @good_tests, (
q{assert_locked(%locked_hash)},
q{assert_locked($locked_hashref)},
q{assert_locked($hash_of_hashes{LOCKED})},
q{assert_locked($hashref_of_hashes->{LOCKED})},
q{assert_locked($$ref_of_hashref_of_hashes->{LOCKED})},
q{assert_unlocked(%unlocked_hash)},
q{assert_unlocked($unlocked_hashref)},
q{assert_unlocked($$ref_of_hashref_of_hashes)},
q{assert_unlocked($hash_of_hashes{UNLOCKED})},
q{assert_unlocked($hashref_of_hashes->{UNLOCKED})},
q{assert_unlocked($$ref_of_hashref_of_hashes->{UNLOCKED})},
);
}
my @bad_tests = (
q{assert(1)},
q{assert_ainta()},
q{assert_alnum()},
q{assert_alphabetic()},
q{assert_anyref()},
t/asserts.t view on Meta::CPAN
q{assert_max_keys(%primary_color, @not_colors)},
q{assert_max_keys(%primary_color, @empty)},
q{assert_max_keys($primary_color_ref, qw<orange yellow violet>)},
q{assert_max_keys($primary_color_ref, @not_colors)},
q{assert_minmax_keys(%primary_color, @all_colors, @primary_color)},
q{assert_minmax_keys($primary_color_ref, @all_colors, @primary_colors)},
q{assert_minmax_keys(%primary_color, @empty, @empty)},
q{assert_minmax_keys($primary_color_ref, @empty, @empty)},
q{assert_unlocked(%locked_hash)},
q{assert_unlocked($locked_hashref)},
q{assert_unlocked($hash_of_hashes{LOCKED})},
q{assert_unlocked($hashref_of_hashes->{LOCKED})},
q{assert_unlocked($$ref_of_hashref_of_hashes->{LOCKED})},
q{assert_locked(%unlocked_hash)},
q{assert_locked($unlocked_hashref)},
q{assert_locked($$ref_of_hashref_of_hashes)},
q{assert_locked($hash_of_hashes{UNLOCKED})},
q{assert_locked($hashref_of_hashes->{UNLOCKED})},
q{assert_locked($$ref_of_hashref_of_hashes->{UNLOCKED})},
q{assert_anyref( "string" )},
q{assert_anyref( 0 )},
q{assert_anyref( $0 )},
q{assert_anyref( *0 )},
q{assert_anyref( @ARGV )},
q{assert_anyref( )},
q{assert_anyref( %ENV )},
q{assert_anyref( defined &lives )},
q{assert_anyref( time() )},