File Coverage

blib/lib/Articulate/Sortation/Slug.pm
Criterion Covered Total %
statement 33 37 89.1
branch 16 22 72.7
condition 2 2 100.0
subroutine 6 6 100.0
pod 0 1 0.0
total 57 68 83.8


line stmt bran cond sub pod time code
1             package Articulate::Sortation::Slug;
2 2     2   1379 use strict;
  2         3  
  2         66  
3 2     2   7 use warnings;
  2         3  
  2         40  
4              
5 2     2   7 use Moo;
  2         4  
  2         8  
6             with 'Articulate::Role::Sortation::AllYouNeedIsCmp';
7              
8 1     1   2 sub _left { -1 }
9              
10 4     4   15 sub _right { 1 }
11              
12             sub cmp {
13 19     19 0 17 my $self = shift;
14 19         17 my $left = shift;
15 19         12 my $right = shift;
16 19         34 my $re_break = qr/(?: # Breaks between groups of characters
17             # (?<=[a-z])|(?=[a-z]) # aa
18             (?<=[a-z])(?![a-z]) # a0
19             | (?
20             | (?<=[0-9])(?![0-9]) # 0_
21             | (?
22             )/ix;
23 19         108 my $la = [ grep { $_ ne '' } split ($re_break, $left)];
  55         66  
24 19         80 my $ra = [ grep { $_ ne '' } split ($re_break, $right)];
  50         60  
25             #warn Dump {left => {$left, $la}, right => {$right,$ra}};
26 19   100     100 while (scalar @$la && scalar @$ra) {
27 39         37 my $l = shift @$la;
28 39         38 my $r = shift @$ra;
29 39 100       104 if ($l =~ /^[^a-z0-9]/i) {
    100          
    100          
30 11 50       19 if ($r =~ /^[a-z0-9]/i) {
31             # left is dash and right is not - left wins
32 0         0 return _left;
33             }
34 11         28 next; # otherwise both are dash - continue
35             }
36             elsif ($r =~ /^[^a-z0-9]/i) {
37             # right is dash and left is not - right wins
38 1         4 return _right;
39             }
40             elsif ($l =~ /^[0-9]/) {
41 11 50       14 if ($r =~ /^[0-9]/) {
42             # both are numbers
43 11         15 my $res = ( $l <=> $r );
44 11 100       50 return $res if $res;
45             }
46             else {
47             # left is number, right is alpha - left wins
48 0         0 return _left;
49             }
50             }
51             else {
52             # both are alphabetic
53 16         14 my $res = ( $l cmp $r );
54 16 100       51 return $res if $res;
55             }
56             }
57 4 50       11 return @$ra ? _left : 0 if (!@$la);
    100          
58 3 50       9 return _right if (!@$ra);
59 0 0         die 'shouldn\'t be here' if $left ne $right;
60 0           return $left cmp $right;
61             }
62              
63             1;