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   1389 use strict;
  2         4  
  2         76  
3 2     2   8 use warnings;
  2         3  
  2         53  
4              
5 2     2   8 use Moo;
  2         3  
  2         17  
6             with 'Articulate::Role::Sortation::AllYouNeedIsCmp';
7              
8 1     1   3 sub _left { -1 }
9              
10 4     4   12 sub _right { 1 }
11              
12             sub cmp {
13 19     19 0 13 my $self = shift;
14 19         12 my $left = shift;
15 19         19 my $right = shift;
16 19         27 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         99 my $la = [ grep { $_ ne '' } split( $re_break, $left ) ];
  55         67  
24 19         78 my $ra = [ grep { $_ ne '' } split( $re_break, $right ) ];
  50         54  
25              
26             #warn Dump {left => {$left, $la}, right => {$right,$ra}};
27 19   100     62 while ( scalar @$la && scalar @$ra ) {
28 39         34 my $l = shift @$la;
29 39         28 my $r = shift @$ra;
30 39 100       87 if ( $l =~ /^[^a-z0-9]/i ) {
    100          
    100          
31 11 50       19 if ( $r =~ /^[a-z0-9]/i ) {
32              
33             # left is dash and right is not - left wins
34 0         0 return _left;
35             }
36 11         22 next; # otherwise both are dash - continue
37             }
38             elsif ( $r =~ /^[^a-z0-9]/i ) {
39              
40             # right is dash and left is not - right wins
41 1         2 return _right;
42             }
43             elsif ( $l =~ /^[0-9]/ ) {
44 11 50       15 if ( $r =~ /^[0-9]/ ) {
45              
46             # both are numbers
47 11         12 my $res = ( $l <=> $r );
48 11 100       38 return $res if $res;
49             }
50             else {
51             # left is number, right is alpha - left wins
52 0         0 return _left;
53             }
54             }
55             else {
56             # both are alphabetic
57 16         14 my $res = ( $l cmp $r );
58 16 100       45 return $res if $res;
59             }
60             }
61 4 50       9 return @$ra ? _left : 0 if ( !@$la );
    100          
62 3 50       7 return _right if ( !@$ra );
63 0 0         die 'shouldn\'t be here' if $left ne $right;
64 0           return $left cmp $right;
65             }
66              
67             1;