File Coverage

blib/lib/Acme/Given/Hash.pm
Criterion Covered Total %
statement 61 62 98.3
branch 13 14 92.8
condition n/a
subroutine 15 15 100.0
pod 0 1 0.0
total 89 92 96.7


line stmt bran cond sub pod time code
1             package Acme::Given::Hash;
2             {
3             $Acme::Given::Hash::VERSION = '0.007';
4             }
5 1     1   23181 use strict;
  1         2  
  1         39  
6 1     1   5 use warnings;
  1         2  
  1         40  
7             require 5.014;
8 1     1   909 use List::MoreUtils qw{natatime};
  1         1428  
  1         120  
9 1     1   7 use Exporter qw{import};
  1         2  
  1         32  
10 1     1   16 use v5.10;
  1         4  
  1         54  
11 1     1   4 no if $] >= 5.018, warnings => "experimental::smartmatch";
  1         2  
  1         9  
12             our @EXPORT = qw{gvn};
13              
14             #ABSTRACT: is given() too much typing for you?
15              
16             sub gvn ($) {
17 8     8 0 2671 my $when = shift;
18             # old hashref notation
19 8 100       33 if ( ref($when) eq 'HASH' ) {
    50          
20 6         112 return bless {exact => $when, calculate => []}, 'Acme::Given::Hash::Object';
21             }
22             # new arrayref notation
23             elsif ( ref($when) eq 'ARRAY' ) {
24 2         5 my $input = natatime 2, @{ $_[0] };
  2         111  
25 2         10 my $self = {exact=>{}, calculate=>[]};
26 2         13 my $it = natatime 2, @$when;
27 2         24 while (my @pairs = $it->()) {
28 7 100       18 if( ref($pairs[0]) eq '' ) {
29 1         15 $self->{exact}->{$pairs[0]} = $pairs[1];
30             }
31             else {
32 6         7 push @{ $self->{calculate} }, {match => $pairs[0], value => $pairs[1]};
  6         48  
33             }
34             }
35 2         27 return bless $self, 'Acme::Given::Hash::Object';
36             }
37 0         0 die 'gvn only takes hashrefs and arrayrefs, you have passed soemthing else';
38             }
39              
40             package Acme::Given::Hash::Object;
41             {
42             $Acme::Given::Hash::Object::VERSION = '0.007';
43             }
44 1     1   355 use strict;
  1         2  
  1         43  
45 1     1   5 use warnings;
  1         2  
  1         24  
46 1     1   16 use v5.10;
  1         4  
  1         50  
47 1     1   6 no if $] >= 5.018, warnings => "experimental::smartmatch";
  1         2  
  1         4  
48              
49             use overload '~~' => sub{
50 18     18   1047 my ($self, $key) = @_;
51              
52             # in the case of a sub as a value execute with $key
53             sub RUN($){
54 11     11   18 my $ref = shift;
55 11 100       63 return ref($ref) eq 'CODE' ? $ref->($key) : $ref;
56             }
57              
58             # first check and see if we have an exact match
59 18 100       62 return RUN $self->{exact}->{$key} if exists $self->{exact}->{$key};
60              
61 13         21 local $_ = $key; # allow match subs to just use $_;
62 13         15 foreach my $pair (@{ $self->{calculate} } ) {
  13         30  
63              
64 23         23 my $match;
65             # 'string' ~~ [1..10] throws a warning, this disables this just for the check
66 1     1   413 { no warnings qw{numeric};
  1         7  
  1         147  
  23         36  
67             # in the case of a sub as a key capture the return value
68 23 100       102 $match = ref($pair->{match}) eq 'CODE'
69             ? $pair->{match}->($key)
70             : $key ~~ $pair->{match}
71             ;
72             }
73              
74 23 100       68 return RUN $pair->{value} if $match;
75             }
76 7         21 return undef; # no matches found
77 1     1   1499 };
  1         1002  
  1         10  
78              
79             1;