File Coverage

blib/lib/Test/Stream/Compare/Object.pm
Criterion Covered Total %
statement 79 79 100.0
branch 28 28 100.0
condition 13 17 76.4
subroutine 19 19 100.0
pod 9 10 90.0
total 148 153 96.7


line stmt bran cond sub pod time code
1             package Test::Stream::Compare::Object;
2 100     100   776 use strict;
  100         101  
  100         2281  
3 100     100   294 use warnings;
  100         114  
  100         2079  
4              
5 100     100   347 use Test::Stream::Util qw/try/;
  100         112  
  100         525  
6              
7 100     100   385 use Test::Stream::Compare::Meta();
  100         131  
  100         1655  
8              
9 100     100   317 use base 'Test::Stream::Compare';
  100         123  
  100         6116  
10 100     100   387 use Test::Stream::HashBase accessors => [qw/calls meta refcheck ending/];
  100         216  
  100         566  
11              
12 100     100   420 use Carp qw/croak confess/;
  100         114  
  100         4115  
13 100     100   350 use Scalar::Util qw/reftype blessed/;
  100         136  
  100         54723  
14              
15             sub init {
16 435     435 0 420 my $self = shift;
17 435   100     1613 $self->{+CALLS} ||= [];
18 435         939 $self->SUPER::init();
19             }
20              
21 18     18 1 39 sub name { '' }
22              
23 112     112 1 235 sub meta_class { 'Test::Stream::Compare::Meta' }
24 145     145 1 362 sub object_base { 'UNIVERSAL' }
25              
26             sub verify {
27 452     452 1 424 my $self = shift;
28 452         824 my %params = @_;
29 452         596 my ($got, $exists) = @params{qw/got exists/};
30              
31 452 100       717 return 0 unless $exists;
32 451 100       708 return 0 unless $got;
33 450 100       709 return 0 unless ref($got);
34 447 100       1012 return 0 unless blessed($got);
35 445 100       978 return 0 unless $got->isa($self->object_base);
36 444         940 return 1;
37             }
38              
39             sub add_prop {
40 512     512 1 425 my $self = shift;
41 512   66     1543 $self->{+META} ||= $self->meta_class->new;
42 512         1224 $self->{+META}->add_prop(@_);
43             }
44              
45             sub add_field {
46 76     76 1 90 my $self = shift;
47 76   66     208 $self->{+REFCHECK} ||= Test::Stream::Compare::Hash->new;
48              
49             croak "Underlying reference does not have fields"
50 76 100       330 unless $self->{+REFCHECK}->can('add_field');
51              
52 75         162 $self->{+REFCHECK}->add_field(@_);
53             }
54              
55             sub add_item {
56 8     8 1 24 my $self = shift;
57 8   66     34 $self->{+REFCHECK} ||= Test::Stream::Compare::Array->new;
58              
59             croak "Underlying reference does not have items"
60 8 100       103 unless $self->{+REFCHECK}->can('add_item');
61              
62 7         19 $self->{+REFCHECK}->add_item(@_);
63             }
64              
65             sub add_call {
66 1078     1078 1 777 my $self = shift;
67 1078         911 my ($meth, $check, $name) = @_;
68 1078 100 66     2817 $name ||= ref $meth ? '\&CODE' : $meth;
69 1078         721 push @{$self->{+CALLS}} => [$meth, $check, $name];
  1078         2976  
70             }
71              
72             sub deltas {
73 445     445 1 408 my $self = shift;
74 445         834 my %params = @_;
75 445         592 my ($got, $convert, $seen) = @params{qw/got convert seen/};
76              
77 445         350 my @deltas;
78 445         515 my $meta = $self->{+META};
79 445         422 my $refcheck = $self->{+REFCHECK};
80              
81 445 100       1649 push @deltas => $meta->deltas(%params) if $meta;
82              
83 445         499 for my $call (@{$self->{+CALLS}}) {
  445         853  
84 1116         1700 my ($meth, $check, $name)= @$call;
85              
86 1116         2069 $check = $convert->($check);
87              
88 1116   100     3993 my $exists = ref($meth) || $got->can($meth);
89 1116         910 my $val;
90 1116 100   1116   4326 my ($ok, $err) = try { $val = $exists ? $got->$meth : undef };
  1116         2926  
91              
92 1116 100       2832 if (!$ok) {
93 2         8 push @deltas => $self->delta_class->new(
94             verified => undef,
95             id => [METHOD => $name],
96             got => undef,
97             check => $check,
98             exception => $err,
99             );
100             }
101             else {
102 1114 100       3536 push @deltas => $check->run(
103             id => [METHOD => $name],
104             convert => $convert,
105             seen => $seen,
106             exists => $exists,
107             $exists ? (got => $val) : (),
108             );
109             }
110             }
111              
112 445 100       1140 return @deltas unless $refcheck;
113              
114 230         843 $refcheck->set_ending($self->{+ENDING});
115              
116 230 100       1291 if ($refcheck->verify(%params)) {
117 227         635 push @deltas => $refcheck->deltas(%params);
118             }
119             else {
120 3         8 push @deltas => $self->delta_class->new(
121             verified => undef,
122             id => [META => 'Object Ref'],
123             got => $got,
124             check => $refcheck,
125             );
126             }
127              
128 230         615 return @deltas;
129             }
130              
131             1;
132              
133             __END__