File Coverage

lib/App/Perlbrew/Util.pm
Criterion Covered Total %
statement 60 61 98.3
branch 18 20 90.0
condition 6 8 75.0
subroutine 10 10 100.0
pod 0 6 0.0
total 94 105 89.5


line stmt bran cond sub pod time code
1             package App::Perlbrew::Util;
2 61     61   208849 use strict;
  61         175  
  61         2534  
3 61     61   363 use warnings;
  61         125  
  61         1608  
4 61     61   1042 use 5.008;
  61         221  
5              
6 61     61   341 use Exporter 'import';
  61         137  
  61         52376  
7             our @EXPORT = qw( uniq min editdist files_are_the_same perl_version_to_integer );
8             our @EXPORT_OK = qw( find_similar_tokens );
9              
10             sub uniq {
11 38     38 0 58 my %seen;
12 38         104 grep { !$seen{$_}++ } @_;
  0         0  
13             }
14              
15             sub min(@) {
16 18506     18506 0 22590 my $m = $_[0];
17 18506         25312 for(@_) {
18 55518 100       93052 $m = $_ if $_ < $m;
19             }
20 18506         30571 return $m;
21             }
22              
23             # straight copy of Wikipedia's "Levenshtein Distance"
24             sub editdist {
25 192     192 0 658 my @a = split //, shift;
26 192         474 my @b = split //, shift;
27              
28             # There is an extra row and column in the matrix. This is the
29             # distance from the empty string to a substring of the target.
30 192         236 my @d;
31 192         1157 $d[$_][0] = $_ for (0 .. @a);
32 192         882 $d[0][$_] = $_ for (0 .. @b);
33              
34 192         308 for my $i (1 .. @a) {
35 1995         3295 for my $j (1 .. @b) {
36 19819 100       42066 $d[$i][$j] = ($a[$i-1] eq $b[$j-1] ? $d[$i-1][$j-1]
37             : 1 + min($d[$i-1][$j], $d[$i][$j-1], $d[$i-1][$j-1]));
38             }
39             }
40              
41 192         987 return $d[@a][@b];
42             }
43              
44             sub files_are_the_same {
45             ## Check dev and inode num. Not useful on Win32.
46             ## The for loop should always return false on Win32, as a result.
47              
48 25     25 0 6099 my @files = @_;
49 25         50 my @stats = map {[ stat($_) ]} @files;
  50         729  
50              
51 25         72 my $stats0 = join " ", @{$stats[0]}[0,1];
  25         103  
52 25         67 for (@stats) {
53 50 100 66     240 return 0 if ((! defined($_->[1])) || $_->[1] == 0);
54 49 100       1304 unless ($stats0 eq join(" ", $_->[0], $_->[1])) {
55 14         70 return 0;
56             }
57             }
58 10         40 return 1
59             }
60              
61             sub perl_version_to_integer {
62 209     209 0 49353 my $version = shift;
63              
64 209         291 my @v;
65 209 100       368 if ($version eq 'blead') {
66 1         5 @v = (999,999,999);
67             } else {
68 208         762 @v = split(/[\.\-_]/, $version);
69             }
70 209 50       449 return undef if @v < 2;
71              
72 209 100       478 if ($v[1] <= 5) {
73 24   100     80 $v[2] ||= 0;
74 24         32 $v[3] = 0;
75             }
76             else {
77 185 50 66     634 $v[3] ||= $v[1] >= 6 ? 9 : 0;
78 185         432 $v[3] =~ s/[^0-9]//g;
79             }
80              
81 209         632 return $v[1]*1000000 + $v[2]*1000 + $v[3];
82             }
83              
84             sub find_similar_tokens {
85 7     7 0 9324 my ($token, $tokens) = @_;
86 7         13 my $SIMILAR_DISTANCE = 6;
87              
88 51         101 my @similar_tokens = sort { $a->[1] <=> $b->[1] } map {
89 7         19 my $d = editdist( $_, $token );
  186         315  
90 186 100       439 ( ( $d < $SIMILAR_DISTANCE ) ? [$_, $d] : () )
91             } @$tokens;
92              
93 7 100       31 if (@similar_tokens) {
94 6         12 my $best_score = $similar_tokens[0][1];
95 6         19 @similar_tokens = map { $_->[0] } grep { $_->[1] == $best_score } @similar_tokens;
  8         31  
  32         86  
96             }
97              
98 7         77 return \@similar_tokens;
99             }
100              
101             1;