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   1057 use strict;
  100         188  
  100         2786  
3 100     100   516 use warnings;
  100         194  
  100         2509  
4              
5 100     100   621 use Test::Stream::Compare;
  100         194  
  100         699  
6             use Test::Stream::HashBase(
7 100         790 base => 'Test::Stream::Compare',
8             accessors => [qw/inref ending items order/],
9 100     100   529 );
  100         207  
10              
11 100     100   627 use Carp qw/croak confess/;
  100         195  
  100         5396  
12 100     100   542 use Scalar::Util qw/reftype/;
  100         210  
  100         72916  
13              
14             sub init {
15 838     838 0 1257 my $self = shift;
16              
17 838 100       2201 if(my $ref = $self->{+INREF}) {
18 785 100       2063 croak "Cannot specify both 'inref' and 'items'" if $self->{+ITEMS};
19 784 100       1844 croak "Cannot specify both 'inref' and 'order'" if $self->{+ORDER};
20 783         3044 $self->{+ITEMS} = {%$ref};
21 783         3199 $self->{+ORDER} = [sort keys %$ref];
22             }
23             else {
24             # Clone the ref to be safe
25 53 100       158 $self->{+ITEMS} = $self->{+ITEMS} ? {%{$self->{+ITEMS}}} : {};
  3         12  
26 53 100       125 if ($self->{+ORDER}) {
27 2         2 my @all = keys %{$self->{+ITEMS}};
  2         7  
28 2         4 my %have = map { $_ => 1 } @{$self->{+ORDER}};
  3         9  
  2         5  
29 2         4 my @missing = grep { !$have{$_} } @all;
  5         13  
30 2 100       125 croak "Keys are missing from the 'order' array: " . join(', ', sort @missing)
31             if @missing;
32             }
33             else {
34 51         74 $self->{+ORDER} = [sort keys %{$self->{+ITEMS}}];
  51         186  
35             }
36             }
37              
38 835         2963 $self->SUPER::init();
39             }
40              
41 12     12 1 52 sub name { '' }
42              
43             sub verify {
44 841     841 1 1248 my $self = shift;
45 841         2624 my %params = @_;
46 841         1671 my ($got, $exists) = @params{qw/got exists/};
47              
48 841 100       1814 return 0 unless $exists;
49 839 100       1742 return 0 unless $got;
50 837 100       1969 return 0 unless ref($got);
51 834 100       2660 return 0 unless reftype($got) eq 'HASH';
52 829         2895 return 1;
53             }
54              
55             sub add_field {
56 86     86 0 131 my $self = shift;
57 86         136 my ($name, $check) = @_;
58              
59 86 100       318 croak "field name is required"
60             unless defined $name;
61              
62             croak "field '$name' has already been specified"
63 85 100       327 if exists $self->{+ITEMS}->{$name};
64              
65 84         103 push @{$self->{+ORDER}} => $name;
  84         172  
66 84         325 $self->{+ITEMS}->{$name} = $check;
67             }
68              
69             sub deltas {
70 834     834 1 1182 my $self = shift;
71 834         2504 my %params = @_;
72 834         1718 my ($got, $convert, $seen) = @params{qw/got convert seen/};
73              
74 834         995 my @deltas;
75 834         1273 my $items = $self->{+ITEMS};
76              
77             # Make a copy that we can munge as needed.
78 834         2923 my %fields = %$got;
79              
80 834         1252 for my $key (@{$self->{+ORDER}}) {
  834         2112  
81 1837         5324 my $check = $convert->($items->{$key});
82 1837         3204 my $exists = exists $fields{$key};
83 1837         2911 my $val = delete $fields{$key};
84              
85 1837 100       9042 push @deltas => $check->run(
86             id => [HASH => $key],
87             convert => $convert,
88             seen => $seen,
89             exists => $exists,
90             $exists ? (got => $val) : (),
91             );
92             }
93              
94             # if items are left over, and ending is true, we have a problem!
95 834 100 100     3549 if($self->{+ENDING} && keys %fields) {
96 4         13 for my $key (sort keys %fields) {
97             push @deltas => $self->delta_class->new(
98             dne => 'check',
99             verified => undef,
100             id => [HASH => $key],
101 5         24 got => $fields{$key},
102             check => undef,
103             );
104             }
105             }
106              
107 834         3320 return @deltas;
108             }
109              
110             1;
111              
112             __END__