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   1341 use strict;
  100         199  
  100         2591  
3 100     100   524 use warnings;
  100         207  
  100         2500  
4              
5 100     100   542 use Test::Stream::Compare;
  100         185  
  100         669  
6             use Test::Stream::HashBase(
7 100         794 base => 'Test::Stream::Compare',
8             accessors => [qw/inref ending items order/],
9 100     100   548 );
  100         203  
10              
11 100     100   567 use Carp qw/croak confess/;
  100         195  
  100         5430  
12 100     100   541 use Scalar::Util qw/reftype/;
  100         206  
  100         73194  
13              
14             sub init {
15 838     838 0 1344 my $self = shift;
16              
17 838 100       2260 if(my $ref = $self->{+INREF}) {
18 785 100       2126 croak "Cannot specify both 'inref' and 'items'" if $self->{+ITEMS};
19 784 100       1855 croak "Cannot specify both 'inref' and 'order'" if $self->{+ORDER};
20 783         3055 $self->{+ITEMS} = {%$ref};
21 783         3278 $self->{+ORDER} = [sort keys %$ref];
22             }
23             else {
24             # Clone the ref to be safe
25 53 100       175 $self->{+ITEMS} = $self->{+ITEMS} ? {%{$self->{+ITEMS}}} : {};
  3         12  
26 53 100       122 if ($self->{+ORDER}) {
27 2         3 my @all = keys %{$self->{+ITEMS}};
  2         7  
28 2         4 my %have = map { $_ => 1 } @{$self->{+ORDER}};
  3         9  
  2         4  
29 2         5 my @missing = grep { !$have{$_} } @all;
  5         12  
30 2 100       128 croak "Keys are missing from the 'order' array: " . join(', ', sort @missing)
31             if @missing;
32             }
33             else {
34 51         103 $self->{+ORDER} = [sort keys %{$self->{+ITEMS}}];
  51         182  
35             }
36             }
37              
38 835         2958 $self->SUPER::init();
39             }
40              
41 12     12 1 43 sub name { '' }
42              
43             sub verify {
44 841     841 1 1295 my $self = shift;
45 841         2638 my %params = @_;
46 841         1702 my ($got, $exists) = @params{qw/got exists/};
47              
48 841 100       1963 return 0 unless $exists;
49 839 100       1738 return 0 unless $got;
50 837 100       1962 return 0 unless ref($got);
51 834 100       2703 return 0 unless reftype($got) eq 'HASH';
52 829         3057 return 1;
53             }
54              
55             sub add_field {
56 86     86 0 130 my $self = shift;
57 86         129 my ($name, $check) = @_;
58              
59 86 100       313 croak "field name is required"
60             unless defined $name;
61              
62             croak "field '$name' has already been specified"
63 85 100       306 if exists $self->{+ITEMS}->{$name};
64              
65 84         104 push @{$self->{+ORDER}} => $name;
  84         187  
66 84         329 $self->{+ITEMS}->{$name} = $check;
67             }
68              
69             sub deltas {
70 834     834 1 1213 my $self = shift;
71 834         2466 my %params = @_;
72 834         1712 my ($got, $convert, $seen) = @params{qw/got convert seen/};
73              
74 834         1049 my @deltas;
75 834         1342 my $items = $self->{+ITEMS};
76              
77             # Make a copy that we can munge as needed.
78 834         2953 my %fields = %$got;
79              
80 834         1335 for my $key (@{$self->{+ORDER}}) {
  834         2077  
81 1837         5368 my $check = $convert->($items->{$key});
82 1837         3363 my $exists = exists $fields{$key};
83 1837         3007 my $val = delete $fields{$key};
84              
85 1837 100       9181 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     3624 if($self->{+ENDING} && keys %fields) {
96 4         15 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         25 got => $fields{$key},
102             check => undef,
103             );
104             }
105             }
106              
107 834         3299 return @deltas;
108             }
109              
110             1;
111              
112             __END__