File Coverage

blib/lib/Test/Stream/Compare/Hash.pm
Criterion Covered Total %
statement 70 70 100.0
branch 28 28 100.0
condition 3 3 100.0
subroutine 11 11 100.0
pod 3 5 60.0
total 115 117 98.2


line stmt bran cond sub pod time code
1             package Test::Stream::Compare::Hash;
2 100     100   721 use strict;
  100         115  
  100         2397  
3 100     100   309 use warnings;
  100         120  
  100         2008  
4              
5 100     100   327 use base 'Test::Stream::Compare';
  100         123  
  100         6214  
6 100     100   406 use Test::Stream::HashBase accessors => [qw/inref ending items order/];
  100         109  
  100         583  
7              
8 100     100   426 use Carp qw/croak confess/;
  100         116  
  100         4056  
9 100     100   366 use Scalar::Util qw/reftype/;
  100         118  
  100         48165  
10              
11             sub init {
12 854     854 0 798 my $self = shift;
13              
14 854 100       1496 if(my $ref = $self->{+INREF}) {
15 801 100       1441 croak "Cannot specify both 'inref' and 'items'" if $self->{+ITEMS};
16 800 100       1214 croak "Cannot specify both 'inref' and 'order'" if $self->{+ORDER};
17 799         2265 $self->{+ITEMS} = {%$ref};
18 799         2339 $self->{+ORDER} = [sort keys %$ref];
19             }
20             else {
21             # Clone the ref to be safe
22 53 100       112 $self->{+ITEMS} = $self->{+ITEMS} ? {%{$self->{+ITEMS}}} : {};
  3         11  
23 53 100       100 if ($self->{+ORDER}) {
24 2         3 my @all = keys %{$self->{+ITEMS}};
  2         7  
25 2         2 my %have = map { $_ => 1 } @{$self->{+ORDER}};
  3         7  
  2         5  
26 2         3 my @missing = grep { !$have{$_} } @all;
  5         10  
27 2 100       85 croak "Keys are missing from the 'order' array: " . join(', ', sort @missing)
28             if @missing;
29             }
30             else {
31 51         44 $self->{+ORDER} = [sort keys %{$self->{+ITEMS}}];
  51         138  
32             }
33             }
34              
35 851         1936 $self->SUPER::init();
36             }
37              
38 12     12 1 34 sub name { '' }
39              
40             sub verify {
41 857     857 1 772 my $self = shift;
42 857         1562 my %params = @_;
43 857         1072 my ($got, $exists) = @params{qw/got exists/};
44              
45 857 100       1289 return 0 unless $exists;
46 855 100       1212 return 0 unless $got;
47 853 100       1309 return 0 unless ref($got);
48 850 100       1933 return 0 unless reftype($got) eq 'HASH';
49 845         1777 return 1;
50             }
51              
52             sub add_field {
53 86     86 0 89 my $self = shift;
54 86         89 my ($name, $check) = @_;
55              
56 86 100       230 croak "field name is required"
57             unless defined $name;
58              
59             croak "field '$name' has already been specified"
60 85 100       244 if exists $self->{+ITEMS}->{$name};
61              
62 84         72 push @{$self->{+ORDER}} => $name;
  84         116  
63 84         209 $self->{+ITEMS}->{$name} = $check;
64             }
65              
66             sub deltas {
67 850     850 1 775 my $self = shift;
68 850         1305 my %params = @_;
69 850         1074 my ($got, $convert, $seen) = @params{qw/got convert seen/};
70              
71 850         660 my @deltas;
72 850         826 my $items = $self->{+ITEMS};
73              
74             # Make a copy that we can munge as needed.
75 850         2039 my %fields = %$got;
76              
77 850         777 for my $key (@{$self->{+ORDER}}) {
  850         1450  
78 1879         3314 my $check = $convert->($items->{$key});
79 1879         1845 my $exists = exists $fields{$key};
80 1879         1852 my $val = delete $fields{$key};
81              
82 1879 100       5711 push @deltas => $check->run(
83             id => [HASH => $key],
84             convert => $convert,
85             seen => $seen,
86             exists => $exists,
87             $exists ? (got => $val) : (),
88             );
89             }
90              
91             # if items are left over, and ending is true, we have a problem!
92 850 100 100     2490 if($self->{+ENDING} && keys %fields) {
93 4         11 for my $key (sort keys %fields) {
94             push @deltas => $self->delta_class->new(
95             dne => 'check',
96             verified => undef,
97             id => [HASH => $key],
98 5         18 got => $fields{$key},
99             check => undef,
100             );
101             }
102             }
103              
104 850         1980 return @deltas;
105             }
106              
107             1;
108              
109             __END__