File Coverage

lib/Test/Chai/Util/PathInfo.pm
Criterion Covered Total %
statement 52 52 100.0
branch 20 22 90.9
condition 2 3 66.6
subroutine 8 8 100.0
pod 0 1 0.0
total 82 86 95.3


line stmt bran cond sub pod time code
1             package Test::Chai::Util::PathInfo;
2 5     5   222268 use strict;
  5         11  
  5         137  
3 5     5   26 use warnings;
  5         9  
  5         130  
4 5     5   27 use utf8;
  5         8  
  5         29  
5              
6 5     5   123 use Exporter qw/import/;
  5         9  
  5         317  
7             our @EXPORT_OK = qw/get_path_info/;
8              
9 5     5   1700 use Test::Chai::Util::Property qw/has_property/;
  5         12  
  5         3092  
10              
11             sub get_path_info {
12 24     24 0 697 my ($path, $obj) = @_;
13              
14 24         61 my $parsed = _parse_path($path);
15 24         56 my $last = $parsed->[@$parsed - 1];
16              
17             my $info = {
18             parent => @$parsed > 1 ? _get_path_value($parsed, $obj, @$parsed - 1) : $obj,
19             name => $last->{p} // $last->{i},
20 24 100 66     104 value => _get_path_value($parsed, $obj),
21             };
22              
23 24         94 $info->{exists} = has_property($info->{name}, $info->{parent});
24 24         135 return $info;
25             }
26              
27             sub _parse_path {
28 28     28   688 my $path = shift;
29              
30 28         49 my $str = $path; $str =~ s/([^\\])\[/$1.[/g;
  28         155  
31 28         247 my @parts = $str =~ /(\\\.|[^.]+)+/g;
32              
33             return [ map {
34 28         72 my $value = $_;
  60         88  
35 60         174 my $re = qr/^\[(\d+)\]$/;
36 60         251 my @m_arr = $value =~ $re;
37              
38 60 100       139 if (@m_arr > 0) {
39 25         139 { i => $m_arr[0] };
40             }
41              
42             else {
43 35         57 $value =~ s/\\([.\[\]])/$1/g;
44 35         194 { p => $value };
45             }
46             } @parts ];
47             }
48              
49             sub _get_path_value {
50 49     49   747 my ($parsed, $obj, $index) = @_;
51              
52 49         62 my $tmp = $obj;
53 49         54 my $res;
54              
55 49 100       107 $index = defined $index ? $index : @$parsed;
56              
57 49         140 for (my ($i, $l) = (0, $index); $i < $l; $i++) {
58 83         131 my $part = $parsed->[$i];
59              
60 83 100       148 if ($tmp) {
61 78 100       229 if (ref $tmp eq 'ARRAY') {
    100          
62 31 100       129 if (defined $part->{p}) {
    50          
63 1         4 $tmp = $tmp->[$part->{p}];
64             }
65              
66             elsif (defined $part->{i}) {
67 30         78 $tmp = $tmp->[$part->{i}];
68             }
69             }
70              
71             elsif (ref $tmp eq 'HASH') {
72 46 100       105 if (defined $part->{p}) {
    50          
73 45         93 $tmp = $tmp->{$part->{p}};
74             }
75              
76             elsif (defined $part->{i}) {
77 1         4 $tmp = $tmp->{$part->{i}};
78             }
79             }
80              
81             else {
82 1         3 $tmp = undef;
83             }
84              
85 78 100       247 if ($i == $l - 1) {
86 44         114 $res = $tmp;
87             }
88             }
89              
90             else {
91 5         13 $res = undef;
92             }
93             }
94              
95 49         225 return $res;
96             }
97              
98             1;