Test-Magpie/lib/Test/Magpie/Util.pm
package Test::Magpie::Util;
{
$Test::Magpie::Util::VERSION = '0.11';
}
# ABSTRACT: Internal utility functions for Test::Magpie
use strict;
use warnings;
# smartmatch dependencies
use 5.010001;
use experimental qw( smartmatch );
use Exporter qw( import );
use Scalar::Util qw( blessed looks_like_number refaddr );
use Moose::Util qw( find_meta );
our @EXPORT_OK = qw(
extract_method_name
get_attribute_value
has_caller_package
match
);
sub extract_method_name {
my ($method_name) = @_;
$method_name =~ s/.*:://;
return $method_name;
}
sub get_attribute_value {
my ($object, $attribute) = @_;
return find_meta($object)
->find_attribute_by_name($attribute)
->get_value($object);
}
sub has_caller_package {
my $package= shift;
my $level = 1;
while (my ($caller) = caller $level++) {
return 1 if $caller eq $package;
}
return;
}
sub match {
my ($a, $b) = @_;
# This function uses smart matching, but we need to limit the scenarios
# in which it is used because of its quirks.
# ref types must match
return if ref($a) ne ref($b);
# objects match only if they are the same object
if (blessed($a) || ref($a) eq 'CODE') {
return refaddr($a) == refaddr($b);
}
# don't smartmatch on arrays because it recurses
# which leads to the same quirks that we want to avoid
if (ref($a) eq 'ARRAY') {
return if $#{$a} != $#{$b};
# recurse to handle nested structures
foreach (0 .. $#{$a}) {
return if !match( $a->[$_], $b->[$_] );
}
return 1;
}
# smartmatch only matches hash keys
# but we want to match the values too
if (ref($a) eq 'HASH') {
return unless $a ~~ $b;
foreach (keys %$a) {
return if !match( $a->{$_}, $b->{$_} );
}
return 1;
}
# avoid smartmatch doing number matches on strings
# e.g. '5x' ~~ 5 is true
return if looks_like_number($a) xor looks_like_number($b);
return $a ~~ $b;
}
1;
__END__
=pod
=encoding utf-8
=head1 NAME
Test::Magpie::Util - Internal utility functions for Test::Magpie
=head1 FUNCTIONS
=head2 extract_method_name
$method_name = extract_method_name($full_method_name)
From a fully qualified method name such as Foo::Bar::baz, will return
just the method name (in this example, baz).
=head2 get_attribute_value
$value = get_attribute_value($object, $attr_name)
Gets value of Moose attributes that have no accessors by accessing the class'
underlying meta-object.
=head2 has_caller_package
$bool = has_caller_package($package_name)
Returns whether the given C<$package> is in the current call stack.
=head2 match
$bool = match($a, $b)
Match 2 values for equality.
=head1 AUTHORS
=over 4
=item *
Oliver Charles <oliver.g.charles@googlemail.com>
=item *
Steven Lee <stevenwh.lee@gmail.com>
=back
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2013 by Oliver Charles.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut