Assert-Conditional

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

         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()  )},



( run in 0.797 second using v1.01-cache-2.11-cpan-49f99fa48dc )