File Coverage

blib/lib/Pandoc/Version.pm
Criterion Covered Total %
statement 60 60 100.0
branch 15 16 93.7
condition 9 12 75.0
subroutine 13 13 100.0
pod 6 7 85.7
total 103 108 95.3


line stmt bran cond sub pod time code
1             package Pandoc::Version;
2 11     11   70442 use 5.014;
  11         53  
3 11     11   63 use warnings;
  11         30  
  11         685  
4              
5             our $VERSION = '0.9.0';
6              
7             use overload
8 11         79 '""' => 'string',
9             '0+' => 'number',
10             cmp => 'cmp',
11             '<=>' => 'cmp',
12 11     11   12248 fallback => 1;
  11         10278  
13 11     11   1491 use Scalar::Util qw(reftype blessed);
  11         25  
  11         561  
14 11     11   4415 use Pandoc::Error;
  11         29  
  11         3415  
15              
16             our @CARP_NOT = ('Pandoc');
17              
18             sub new {
19 87     87 0 6910 my $class = shift;
20              
21             # We accept array or string input
22             # (or mixed but let's not document that!)
23             my @nums =
24             map {
25 212         317 my $num = $_;
26 212 100       595 $num =~ /^\d+$/
27             or Pandoc::Error->throw(
28             message => 'invalid version number',
29             version => $num
30             );
31 207         646 $num =~ s/^0+(?=\d)//; # ensure decimal interpretation
32 207         334 $num = 0 + $num;
33 207         388 $num
34             }
35 109         260 map { s/^v//i; split /\./ } ## no critic
  109         273  
36 89 100 100     396 map { 'ARRAY' CORE::eq ( reftype $_ // "" ) ? @$_ : $_ }
37 87   100     173 map { $_ // '' } @_;
  89         265  
38              
39 82 100       207 Pandoc::Error->throw('invalid version number') unless @nums;
40              
41 79         236 return bless \@nums => $class;
42             }
43              
44 25     25 1 388 sub string { join '.', @{ $_[0] } }
  25         132  
45              
46             sub number {
47 133     133 1 171 my ( $major, @minors ) = @{ $_[0] };
  133         270  
48 11     11   84 no warnings qw(uninitialized numeric);
  11         23  
  11         6792  
49 133 100       254 if (@minors) {
50 121         171 my $minor = join '', map { sprintf '%03d', $_ } @minors;
  178         518  
51 121         589 return 0 + "$major.$minor"; # return a true number
52             }
53 12         32 return 0 + $major;
54             }
55              
56             sub cmp {
57             my ( $a, $b ) = map {
58 55 100 66 55 1 121 ( blessed $_ and $_->isa('Pandoc::Version') )
  110   33     588  
59             ? $_
60             : Pandoc::Version->new( $_ // () )
61             } ( $_[0], $_[1] );
62 55         117 return $a->number <=> $b->number;
63             }
64              
65             sub match {
66 7     7 1 2365 my ( $a, $b ) = map { Pandoc::Version->new($_) } @_;
  14         34  
67 7         29 pop @$a while @$a > @$b;
68 7         17 pop @$b while @$b > @$a;
69              
70 7         14 return $a->number == $b->number;
71             }
72              
73             my %cmp_truth_table = (
74             '==' => [ 0, 1, 0 ],
75             '!=' => [ 1, 0, 1 ],
76             '>=' => [ 0, 1, 1 ],
77             '<=' => [ 1, 1, 0 ],
78             '<' => [ 1, 0, 0 ],
79             '>' => [ 0, 0, 1 ]
80             );
81              
82             sub fulfills {
83 17     17 1 5595 my ( $self, $req ) = @_;
84 17 50       79 return 1 unless $req;
85              
86 17         145 my @parts = split qr{\s*,\s*}, $req;
87 17         50 for my $part (@parts) {
88 32         207 my ( $op, $ver ) =
89             $part =~ m{^\s*(==|>=|>|<=|<|!=)?\s*v?(\d+(\.\d+)*)$};
90 32 100       109 if ( !defined $ver ) {
91 1         10 Pandoc::Error->throw(
92             message => "invalid version requirement: $req",
93             require => $req,
94             );
95             }
96              
97 31         55 my $cmp = $self->cmp($ver) + 1; # will be 0 for <, 1 for ==, 2 for >
98 31 100 100     147 return unless $cmp_truth_table{ $op || '>=' }->[$cmp];
99             }
100              
101 8         36 1;
102             }
103              
104             sub TO_JSON {
105 4     4 1 1502 my ($self) = @_;
106 4         33 return [ map { 0 + $_ } @$self ];
  16         41  
107             }
108              
109             1;
110              
111             __END__