File Coverage

blib/lib/Data/Rx/Failure.pm
Criterion Covered Total %
statement 49 69 71.0
branch 7 18 38.8
condition n/a
subroutine 13 17 76.4
pod 0 13 0.0
total 69 117 58.9


line stmt bran cond sub pod time code
1 1     1   6 use strict;
  1         2  
  1         33  
2 1     1   6 use warnings;
  1         2  
  1         63  
3             package Data::Rx::Failure;
4             # ABSTRACT: structured failure report from an Rx checker
5             $Data::Rx::Failure::VERSION = '0.200006';
6 1     1   6 use overload '""' => \&stringify;
  1         3  
  1         15  
7              
8             sub new {
9 1507     1507 0 2785 my ($class, $arg) = @_;
10              
11 1507         7880 my $guts = {
12             rx => $arg->{rx},
13             struct => [ $arg->{struct} ],
14             };
15              
16 1507         14467 bless $guts => $class;
17             }
18              
19 4780     4780 0 30796 sub struct { $_[0]->{struct} }
20              
21             sub contextualize {
22 253     253 0 359 my ($self, $struct) = @_;
23              
24 253         286 push @{ $self->struct }, $struct;
  253         453  
25              
26 253 50       485 if (my $failures = $self->struct->[0]{failures}) {
27 0         0 $_->contextualize($struct) foreach @$failures;
28             }
29              
30 253         864 return $self;
31             }
32              
33             sub value {
34 0     0 0 0 my ($self) = @_;
35              
36 0         0 return $self->struct->[0]{value};
37             }
38              
39             sub error_types {
40 1488     1488 0 3325 my ($self) = @_;
41              
42 1488         2272 return @{ $self->struct->[0]{error} };
  1488         3544  
43             }
44              
45             sub error_string {
46 47     47 0 77 my ($self) = @_;
47              
48 47         110 join ', ', $self->error_types;
49             }
50              
51             sub keys {
52 0     0 0 0 my ($self) = @_;
53              
54 0 0       0 return @{ $self->struct->[0]{keys} || [] };
  0         0  
55             }
56              
57             sub size {
58 0     0 0 0 my ($self) = @_;
59              
60 0         0 return $self->struct->[0]{size};
61             }
62              
63             sub data_path {
64 1347     1347 0 34555 my ($self) = @_;
65              
66 1452 100       2874 map {; map { $_->[0] } @{ $_->{data_path} || [] } }
  38         453  
  1452         14795  
  1347         3732  
67 1347         2103 reverse @{ $self->struct };
68             }
69              
70             sub data_string {
71 47     47 0 79 my ($self) = @_;
72              
73 47         159 return $self->_path_string('$data', 'data_path');
74             }
75              
76             sub check_path {
77 1345     1345 0 2240 my ($self) = @_;
78              
79 1450 100       1916 map {; map { $_->[0] } @{ $_->{check_path} || [] } }
  177         420  
  1450         12277  
  1345         4514  
80 1345         2362 reverse @{ $self->struct };
81             }
82              
83             sub check_string {
84 0     0 0 0 my ($self) = @_;
85              
86 0         0 return $self->_path_string('$schema', 'check_path');
87             }
88              
89             sub _path_string {
90 47     47   119 my ($self, $base, $key) = @_;
91              
92 47         69 my $str = $base;
93              
94 47 50       73 for my $frame (reverse @{ $self->struct || [] }) {
  47         101  
95 47         85 my $hunk = $frame->{ $key };
96 47         196 for my $entry (@$hunk) {
97 0 0       0 if ($entry->[1] eq 'key') { $str .= "->{$entry->[0]}"; }
  0 0       0  
    0          
98 0         0 elsif ($entry->[1] eq 'index') { $str .= "->[$entry->[0]]"; }
99 0         0 elsif ($entry->[2]) { $str = $entry->[2]->($str, @$entry) }
100 0         0 else { $str .= "->? $entry->[0] ?"; }
101             }
102             }
103              
104 47         400 return $str;
105             }
106              
107             sub stringify {
108 47     47 0 559 my ($self) = @_;
109              
110 47         111 my $struct = $self->struct;
111              
112 47         283 my $str = sprintf "Failed %s: %s (error: %s at %s)",
113             $struct->[0]{type},
114             $struct->[0]{message},
115             $self->error_string,
116             $self->data_string;
117              
118             # also stringify failures under the current failure (as for //any),
119             # with indentation
120 47 50       208 if (my $failures = $struct->[0]{failures}) {
121 0         0 foreach my $fail (@$failures) {
122 0         0 my $tmp = "$fail";
123 0         0 $tmp =~ s/\A/ - /;
124 0         0 $tmp =~ s/(?<=\n)^/ /mg;
125 0         0 $str .= "\n$tmp";
126             }
127             }
128              
129 47         216 return $str;
130             }
131              
132             1;
133              
134             __END__