File Coverage

blib/lib/Mojo/DOM58/_Collection.pm
Criterion Covered Total %
statement 118 129 91.4
branch 37 42 88.1
condition 7 9 77.7
subroutine 37 38 97.3
pod 0 22 0.0
total 199 240 82.9


line stmt bran cond sub pod time code
1             package Mojo::DOM58::_Collection;
2              
3             # This file is part of Mojo::DOM58 which is released under:
4             # The Artistic License 2.0 (GPL Compatible)
5             # See the documentation for Mojo::DOM58 for full license details.
6              
7 3     3   75316 use strict;
  3         81  
  3         99  
8 3     3   17 use warnings;
  3         7  
  3         115  
9 3     3   17 use Carp 'croak';
  3         12  
  3         194  
10 3     3   19 use List::Util;
  3         7  
  3         325  
11 3     3   21 use Scalar::Util 'blessed';
  3         13  
  3         211  
12 3     3   18 use re ();
  3         12  
  3         176  
13              
14 3 50   3   18 use constant REDUCE => ($] >= 5.008009 ? \&List::Util::reduce : \&_reduce);
  3         6  
  3         357  
15 3     3   18 use constant HAS_IS_REGEXP => !!($] >= 5.010000);
  3         6  
  3         289  
16              
17             # Role support requires Role::Tiny 2.000001+
18             use constant ROLES =>
19 3     3   21 !!(eval { require Role::Tiny; Role::Tiny->VERSION('2.000001'); 1 });
  3         6  
  3         4  
  3         1848  
  3         13496  
  3         2749  
20              
21             our $VERSION = '3.001';
22              
23             sub new {
24 760     760 0 58688 my $class = shift;
25 760   66     7916 return bless [@_], ref $class || $class;
26             }
27              
28 1     1 0 62 sub TO_JSON { [@{shift()}] }
  1         5  
29              
30             sub compact {
31 3     3 0 8 my $self = shift;
32 3 100 66     7 return $self->new(grep { defined && (ref || length) } @$self);
  9         40  
33             }
34              
35             sub each {
36 115     115 0 835 my ($self, $cb) = @_;
37 115 100       297 return @$self unless $cb;
38 105         159 my $i = 1;
39 105         401 $_->$cb($i++) for @$self;
40 105         234 return $self;
41             }
42              
43             sub first {
44 76     76 0 1427 my ($self, $cb) = (shift, shift);
45 76 100       351 return $self->[0] unless $cb;
46 11 100   2   39 return List::Util::first { $_ =~ $cb } @$self if HAS_IS_REGEXP ? re::is_regexp($cb) : ref $cb eq 'Regexp';
  2         15  
47 10     22   48 return List::Util::first { $_->$cb(@_) } @$self;
  22         76  
48             }
49              
50 5     5 0 13 sub flatten { $_[0]->new(_flatten(@{$_[0]})) }
  5         22  
51              
52             sub grep {
53 35     35 0 101 my ($self, $cb) = (shift, shift);
54 35 100       113 return $self->new(grep { $_ =~ $cb } @$self) if HAS_IS_REGEXP ? re::is_regexp($cb) : ref $cb eq 'Regexp';
  9         34  
55 34         75 return $self->new(grep { $_->$cb(@_) } @$self);
  106         350  
56             }
57              
58             sub head {
59 9     9 0 30 my ($self, $size) = @_;
60 9 100       26 return $self->new(@$self) if $size > @$self;
61 8 100       30 return $self->new(@$self[0 .. ($size - 1)]) if $size >= 0;
62 4         19 return $self->new(@$self[0 .. ($#$self + $size)]);
63             }
64              
65             sub join {
66 49 100   49 0 132 join +(defined($_[1]) ? $_[1] : ''), map {"$_"} @{$_[0]};
  114         390  
  49         102  
67             }
68              
69 24     24 0 106 sub last { shift->[-1] }
70              
71             sub map {
72 54     54 0 138 my ($self, $cb) = (shift, shift);
73 54         119 return $self->new(map { $_->$cb(@_) } @$self);
  113         317  
74             }
75              
76             sub reduce {
77 3     3 0 732 my $self = shift;
78 3         9 @_ = (@_, @$self);
79 3         5 goto &{REDUCE()};
  3         22  
80             }
81              
82 8     8 0 27 sub reverse { $_[0]->new(reverse @{$_[0]}) }
  8         25  
83              
84 2     2 0 187 sub shuffle { $_[0]->new(List::Util::shuffle @{$_[0]}) }
  2         290  
85              
86 54     54 0 119 sub size { scalar @{$_[0]} }
  54         253  
87              
88             sub slice {
89 8     8 0 21 my $self = shift;
90 8         24 return $self->new(@$self[@_]);
91             }
92              
93             sub sort {
94 6     6 0 30 my ($self, $cb) = @_;
95              
96 6 100       27 return $self->new(sort @$self) unless $cb;
97              
98 4         9 my $caller = caller;
99 3     3   29 no strict 'refs';
  3         15  
  3         1889  
100             my @sorted = sort {
101 4         18 local (*{"${caller}::a"}, *{"${caller}::b"}) = (\$a, \$b);
  12         41  
  12         27  
  12         22  
102 12         26 $a->$cb($b);
103             } @$self;
104 4         23 return $self->new(@sorted);
105             }
106              
107             sub tail {
108 9     9 0 27 my ($self, $size) = @_;
109 9 100       27 return $self->new(@$self) if $size > @$self;
110 8 100       29 return $self->new(@$self[($#$self - ($size - 1)) .. $#$self]) if $size >= 0;
111 4         19 return $self->new(@$self[(0 - $size) .. $#$self]);
112             }
113              
114             sub tap {
115 2     2 0 44 my ($self, $cb) = (shift, shift);
116 2         13 $_->$cb(@_) for $self;
117 2         12 return $self;
118             }
119              
120 57     57 0 106 sub to_array { [@{shift()}] }
  57         325  
121              
122             sub uniq {
123 7     7 0 39 my ($self, $cb) = (shift, shift);
124 7         13 my %seen;
125 7 100       19 return $self->new(grep { my $r = $_->$cb(@_); !$seen{defined $r ? $r : ''}++ } @$self) if $cb;
  12 100       30  
  12         52  
126 4 100       10 return $self->new(grep { !$seen{defined $_ ? $_ : ''}++ } @$self);
  27         77  
127             }
128              
129             sub with_roles {
130 2     2 0 5 croak 'Role::Tiny 2.000001+ is required for roles' unless ROLES;
131 2         7 my ($self, @roles) = @_;
132            
133             return Role::Tiny->create_class_with_roles($self,
134 2 50       13 map { /^\+(.+)$/ ? "${self}::Role::$1" : $_ } @roles)
  1 100       9  
135             unless my $class = blessed $self;
136            
137             return Role::Tiny->apply_roles_to_object($self,
138 1 50       4 map { /^\+(.+)$/ ? "${class}::Role::$1" : $_ } @roles);
  1         12  
139             }
140              
141             sub _flatten {
142 16 100   16   32 map { _ref($_) ? _flatten(@$_) : $_ } @_;
  41         78  
143             }
144              
145             # For perl < 5.8.9
146             sub _reduce (&@) {
147 0     0   0 my $code = shift;
148              
149 0 0       0 return shift unless @_ > 1;
150              
151 0         0 my $caller = caller;
152              
153 3     3   26 no strict 'refs';
  3         7  
  3         527  
154              
155 0         0 local (*{"${caller}::a"}, *{"${caller}::b"}) = (\my $x, \my $y);
  0         0  
  0         0  
156              
157 0         0 $x = shift;
158 0         0 foreach my $e (@_) {
159 0         0 $y = $e;
160 0         0 $x = $code->();
161             }
162              
163 0         0 $x;
164             }
165              
166 41 100 100 41   245 sub _ref { ref $_[0] eq 'ARRAY' || blessed $_[0] && $_[0]->isa(__PACKAGE__) }
167              
168             1;
169              
170             =for Pod::Coverage *EVERYTHING*
171              
172             =cut