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   70244 use strict;
  3         22  
  3         91  
8 3     3   15 use warnings;
  3         7  
  3         113  
9 3     3   27 use Carp 'croak';
  3         5  
  3         194  
10 3     3   20 use List::Util;
  3         6  
  3         290  
11 3     3   21 use Scalar::Util 'blessed';
  3         14  
  3         220  
12 3     3   21 use re ();
  3         6  
  3         173  
13              
14 3 50   3   18 use constant REDUCE => ($] >= 5.008009 ? \&List::Util::reduce : \&_reduce);
  3         6  
  3         357  
15 3     3   19 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   31 !!(eval { require Role::Tiny; Role::Tiny->VERSION('2.000001'); 1 });
  3         6  
  3         5  
  3         1807  
  3         13265  
  3         2642  
20              
21             our $VERSION = '3.000';
22              
23             sub new {
24 760     760 0 53590 my $class = shift;
25 760   66     8129 return bless [@_], ref $class || $class;
26             }
27              
28 1     1 0 57 sub TO_JSON { [@{shift()}] }
  1         4  
29              
30             sub compact {
31 3     3 0 6 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 851 my ($self, $cb) = @_;
37 115 100       298 return @$self unless $cb;
38 105         170 my $i = 1;
39 105         433 $_->$cb($i++) for @$self;
40 105         225 return $self;
41             }
42              
43             sub first {
44 76     76 0 1357 my ($self, $cb) = (shift, shift);
45 76 100       367 return $self->[0] unless $cb;
46 11 100   2   35 return List::Util::first { $_ =~ $cb } @$self if HAS_IS_REGEXP ? re::is_regexp($cb) : ref $cb eq 'Regexp';
  2         14  
47 10     22   43 return List::Util::first { $_->$cb(@_) } @$self;
  22         74  
48             }
49              
50 5     5 0 16 sub flatten { $_[0]->new(_flatten(@{$_[0]})) }
  5         22  
51              
52             sub grep {
53 35     35 0 98 my ($self, $cb) = (shift, shift);
54 35 100       123 return $self->new(grep { $_ =~ $cb } @$self) if HAS_IS_REGEXP ? re::is_regexp($cb) : ref $cb eq 'Regexp';
  9         35  
55 34         71 return $self->new(grep { $_->$cb(@_) } @$self);
  106         346  
56             }
57              
58             sub head {
59 9     9 0 29 my ($self, $size) = @_;
60 9 100       28 return $self->new(@$self) if $size > @$self;
61 8 100       30 return $self->new(@$self[0 .. ($size - 1)]) if $size >= 0;
62 4         18 return $self->new(@$self[0 .. ($#$self + $size)]);
63             }
64              
65             sub join {
66 49 100   49 0 135 join +(defined($_[1]) ? $_[1] : ''), map {"$_"} @{$_[0]};
  114         412  
  49         121  
67             }
68              
69 24     24 0 105 sub last { shift->[-1] }
70              
71             sub map {
72 54     54 0 160 my ($self, $cb) = (shift, shift);
73 54         142 return $self->new(map { $_->$cb(@_) } @$self);
  113         369  
74             }
75              
76             sub reduce {
77 3     3 0 604 my $self = shift;
78 3         10 @_ = (@_, @$self);
79 3         6 goto &{REDUCE()};
  3         22  
80             }
81              
82 8     8 0 23 sub reverse { $_[0]->new(reverse @{$_[0]}) }
  8         19  
83              
84 2     2 0 182 sub shuffle { $_[0]->new(List::Util::shuffle @{$_[0]}) }
  2         299  
85              
86 54     54 0 115 sub size { scalar @{$_[0]} }
  54         262  
87              
88             sub slice {
89 8     8 0 20 my $self = shift;
90 8         26 return $self->new(@$self[@_]);
91             }
92              
93             sub sort {
94 6     6 0 28 my ($self, $cb) = @_;
95              
96 6 100       25 return $self->new(sort @$self) unless $cb;
97              
98 4         9 my $caller = caller;
99 3     3   28 no strict 'refs';
  3         13  
  3         1953  
100             my @sorted = sort {
101 4         17 local (*{"${caller}::a"}, *{"${caller}::b"}) = (\$a, \$b);
  12         39  
  12         26  
  12         27  
102 12         27 $a->$cb($b);
103             } @$self;
104 4         20 return $self->new(@sorted);
105             }
106              
107             sub tail {
108 9     9 0 27 my ($self, $size) = @_;
109 9 100       26 return $self->new(@$self) if $size > @$self;
110 8 100       30 return $self->new(@$self[($#$self - ($size - 1)) .. $#$self]) if $size >= 0;
111 4         15 return $self->new(@$self[(0 - $size) .. $#$self]);
112             }
113              
114             sub tap {
115 2     2 0 50 my ($self, $cb) = (shift, shift);
116 2         11 $_->$cb(@_) for $self;
117 2         12 return $self;
118             }
119              
120 57     57 0 103 sub to_array { [@{shift()}] }
  57         309  
121              
122             sub uniq {
123 7     7 0 36 my ($self, $cb) = (shift, shift);
124 7         15 my %seen;
125 7 100       21 return $self->new(grep { my $r = $_->$cb(@_); !$seen{defined $r ? $r : ''}++ } @$self) if $cb;
  12 100       29  
  12         52  
126 4 100       9 return $self->new(grep { !$seen{defined $_ ? $_ : ''}++ } @$self);
  27         75  
127             }
128              
129             sub with_roles {
130 2     2 0 4 croak 'Role::Tiny 2.000001+ is required for roles' unless ROLES;
131 2         8 my ($self, @roles) = @_;
132            
133             return Role::Tiny->create_class_with_roles($self,
134 2 50       12 map { /^\+(.+)$/ ? "${self}::Role::$1" : $_ } @roles)
  1 100       8  
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         9  
139             }
140              
141             sub _flatten {
142 16 100   16   37 map { _ref($_) ? _flatten(@$_) : $_ } @_;
  41         73  
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         514  
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   246 sub _ref { ref $_[0] eq 'ARRAY' || blessed $_[0] && $_[0]->isa(__PACKAGE__) }
167              
168             1;
169              
170             =for Pod::Coverage *EVERYTHING*
171              
172             =cut