| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Test::Auto::Data; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 6 |  |  | 6 |  | 43 | use strict; | 
|  | 6 |  |  |  |  | 13 |  | 
|  | 6 |  |  |  |  | 183 |  | 
| 4 | 6 |  |  | 6 |  | 30 | use warnings; | 
|  | 6 |  |  |  |  | 9 |  | 
|  | 6 |  |  |  |  | 139 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 6 |  |  | 6 |  | 28 | use Moo; | 
|  | 6 |  |  |  |  | 11 |  | 
|  | 6 |  |  |  |  | 25 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | require Carp; | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | our $VERSION = '0.12'; # VERSION | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | # BUILD | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | has data => ( | 
| 15 |  |  |  |  |  |  | is => 'ro', | 
| 16 |  |  |  |  |  |  | builder => 'new_data', | 
| 17 |  |  |  |  |  |  | lazy => 1 | 
| 18 |  |  |  |  |  |  | ); | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | sub new_data { | 
| 21 | 42 |  |  | 42 | 0 | 410 | my ($self) = @_; | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 42 | 50 |  |  |  | 645 | my $file = $self->file or die []; | 
| 24 | 42 |  |  |  |  | 449 | my $data = $self->parser($self->lines); | 
| 25 |  |  |  |  |  |  |  | 
| 26 | 42 |  |  |  |  | 215 | return $data; | 
| 27 |  |  |  |  |  |  | } | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | has file => ( | 
| 30 |  |  |  |  |  |  | is => 'ro', | 
| 31 |  |  |  |  |  |  | builder => 'new_file', | 
| 32 |  |  |  |  |  |  | lazy => 1 | 
| 33 |  |  |  |  |  |  | ); | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | sub new_file { | 
| 36 | 0 |  |  | 0 | 0 | 0 | my ($self) = @_; | 
| 37 |  |  |  |  |  |  |  | 
| 38 | 0 | 0 |  |  |  | 0 | my $from = $self->from or return; | 
| 39 | 0 |  |  |  |  | 0 | my $path = $from =~ s/::/\//gr; | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 0 |  |  |  |  | 0 | return $INC{"$path.pm"}; | 
| 42 |  |  |  |  |  |  | } | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | has from => ( | 
| 45 |  |  |  |  |  |  | is => 'ro', | 
| 46 |  |  |  |  |  |  | lazy => 1 | 
| 47 |  |  |  |  |  |  | ); | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | sub BUILD { | 
| 50 | 42 |  |  | 42 | 0 | 8762 | my ($self, $args) = @_; | 
| 51 |  |  |  |  |  |  |  | 
| 52 | 42 |  |  |  |  | 782 | $self->file; | 
| 53 | 42 |  |  |  |  | 1071 | $self->data; | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 42 |  |  |  |  | 235 | return $self; | 
| 56 |  |  |  |  |  |  | } | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | # METHODS | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | sub content { | 
| 61 | 468 |  |  | 468 | 0 | 819 | my ($self, $name) = @_; | 
| 62 |  |  |  |  |  |  |  | 
| 63 | 468 | 100 |  |  |  | 828 | my $item = $self->item($name) or return; | 
| 64 | 312 |  |  |  |  | 523 | my $data = $item->{data}; | 
| 65 |  |  |  |  |  |  |  | 
| 66 | 312 |  |  |  |  | 864 | return $data; | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | sub contents { | 
| 70 | 1580 |  |  | 1580 | 0 | 2822 | my ($self, $name, $seek) = @_; | 
| 71 |  |  |  |  |  |  |  | 
| 72 | 1580 | 50 |  |  |  | 2505 | my $items = $self->list($name) or return; | 
| 73 | 1580 | 50 |  |  |  | 3570 | @$items = grep { $_->{name} eq $seek } @$items if $seek; | 
|  | 16369 |  |  |  |  | 27955 |  | 
| 74 | 1580 |  |  |  |  | 2430 | my $data = [map { $_->{data} } @$items]; | 
|  | 1192 |  |  |  |  | 2873 |  | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 1580 |  |  |  |  | 4793 | return $data; | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | sub item { | 
| 80 | 468 |  |  | 468 | 0 | 712 | my ($self, $name) = @_; | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 468 |  |  |  |  | 597 | for my $item (@{$self->{data}}) { | 
|  | 468 |  |  |  |  | 811 |  | 
| 83 | 8366 | 100 | 100 |  |  | 17927 | return $item if !$item->{list} && $item->{name} eq $name; | 
| 84 |  |  |  |  |  |  | } | 
| 85 |  |  |  |  |  |  |  | 
| 86 | 156 |  |  |  |  | 551 | return; | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | sub lines { | 
| 90 | 42 |  |  | 42 | 0 | 90 | my ($self) = @_; | 
| 91 |  |  |  |  |  |  |  | 
| 92 | 42 |  |  |  |  | 635 | my $file = $self->file; | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 42 | 50 |  |  |  | 2435 | open my $fh, '<', $file or Carp::confess "$!: $file"; | 
| 95 | 42 |  |  |  |  | 12328 | my $lines = join "\n", <$fh>; | 
| 96 | 42 |  |  |  |  | 1681 | close $fh; | 
| 97 |  |  |  |  |  |  |  | 
| 98 | 42 |  |  |  |  | 399 | return $lines; | 
| 99 |  |  |  |  |  |  | } | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | sub list { | 
| 102 | 1658 |  |  | 1658 | 0 | 2401 | my ($self, $name) = @_; | 
| 103 |  |  |  |  |  |  |  | 
| 104 | 1658 | 50 |  |  |  | 2837 | return if !$name; | 
| 105 |  |  |  |  |  |  |  | 
| 106 | 1658 |  |  |  |  | 2133 | my @list; | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 1658 |  |  |  |  | 1939 | for my $item (@{$self->{data}}) { | 
|  | 1658 |  |  |  |  | 2840 |  | 
| 109 | 82372 | 100 | 100 |  |  | 210489 | push @list, $item if $item->{list} && $item->{list} eq $name; | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 | 1658 |  |  |  |  | 4861 | return [sort { $a->{index} <=> $b->{index} } @list]; | 
|  | 31374 |  |  |  |  | 43566 |  | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | sub list_item { | 
| 116 | 0 |  |  | 0 | 0 | 0 | my ($self, $list, $name) = @_; | 
| 117 |  |  |  |  |  |  |  | 
| 118 | 0 | 0 |  |  |  | 0 | my $items = $self->list($list) or return; | 
| 119 | 0 |  |  |  |  | 0 | my $data = [grep { $_->{name} eq $name } @$items]; | 
|  | 0 |  |  |  |  | 0 |  | 
| 120 |  |  |  |  |  |  |  | 
| 121 | 0 |  |  |  |  | 0 | return $data; | 
| 122 |  |  |  |  |  |  | } | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | sub parser { | 
| 125 | 42 |  |  | 42 | 0 | 159 | my ($self, $data) = @_; | 
| 126 |  |  |  |  |  |  |  | 
| 127 | 42 |  |  |  |  | 43159 | $data =~ s/\n*$/\n/; | 
| 128 |  |  |  |  |  |  |  | 
| 129 | 42 |  |  |  |  | 7037 | my @chunks = split /^=\s*(.+?)\s*\r?\n/m, $data; | 
| 130 |  |  |  |  |  |  |  | 
| 131 | 42 |  |  |  |  | 130 | shift @chunks; | 
| 132 |  |  |  |  |  |  |  | 
| 133 | 42 |  |  |  |  | 122 | my $items = []; | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 42 |  |  |  |  | 278 | while (my ($meta, $data) = splice @chunks, 0, 2) { | 
| 136 | 1632 | 50 | 33 |  |  | 4346 | next unless $meta && $data; | 
| 137 | 1632 | 100 |  |  |  | 2733 | next unless $meta ne 'cut'; | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 1590 |  |  |  |  | 3818 | my @info = split /\s/, $meta, 2; | 
| 140 | 1590 | 100 |  |  |  | 3346 | my ($list, $name) = @info == 2 ? @info : (undef, @info); | 
| 141 |  |  |  |  |  |  |  | 
| 142 | 1590 |  |  |  |  | 7556 | $data = [split /\n\n/, $data]; | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 1590 |  |  |  |  | 4795 | my $item = { name => $name, data => $data, index => @$items + 1, list => $list }; | 
| 145 |  |  |  |  |  |  |  | 
| 146 | 1590 |  |  |  |  | 4896 | push @$items, $item; | 
| 147 |  |  |  |  |  |  | } | 
| 148 |  |  |  |  |  |  |  | 
| 149 | 42 |  |  |  |  | 111 | return $items; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | sub pluck { | 
| 153 | 0 |  |  | 0 | 0 |  | my ($self, $type, $name) = @_; | 
| 154 |  |  |  |  |  |  |  | 
| 155 | 0 | 0 |  |  |  |  | return if !$name; | 
| 156 | 0 | 0 | 0 |  |  |  | return if !$type || ($type ne 'item' && $type ne 'list'); | 
|  |  |  | 0 |  |  |  |  | 
| 157 |  |  |  |  |  |  |  | 
| 158 | 0 |  |  |  |  |  | my (@list, @copy); | 
| 159 |  |  |  |  |  |  |  | 
| 160 | 0 |  |  |  |  |  | for my $item (@{$self->{data}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 161 | 0 |  |  |  |  |  | my $matched = 0; | 
| 162 |  |  |  |  |  |  |  | 
| 163 | 0 | 0 | 0 |  |  |  | $matched = 1 if $type eq 'list' && $item->{list} && $item->{list} eq $name; | 
|  |  |  | 0 |  |  |  |  | 
| 164 | 0 | 0 | 0 |  |  |  | $matched = 1 if $type eq 'item' && $item->{name} && $item->{name} eq $name; | 
|  |  |  | 0 |  |  |  |  | 
| 165 |  |  |  |  |  |  |  | 
| 166 | 0 | 0 |  |  |  |  | push @list, $item if $matched; | 
| 167 | 0 | 0 |  |  |  |  | push @copy, $item if !$matched; | 
| 168 |  |  |  |  |  |  | } | 
| 169 |  |  |  |  |  |  |  | 
| 170 | 0 |  |  |  |  |  | $self->{data} = [sort { $a->{index} <=> $b->{index} } @copy]; | 
|  | 0 |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  |  | 
| 172 | 0 | 0 |  |  |  |  | return $type eq 'name' ? $list[0] : [@list]; | 
| 173 |  |  |  |  |  |  | } | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | 1; |