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   72932 use 5.014;
  11         47  
3 11     11   65 use warnings;
  11         20  
  11         819  
4              
5             our $VERSION = '0.9.1';
6              
7             use overload
8 11         72 '""' => 'string',
9             '0+' => 'number',
10             cmp => 'cmp',
11             '<=>' => 'cmp',
12 11     11   12369 fallback => 1;
  11         10441  
13 11     11   1553 use Scalar::Util qw(reftype blessed);
  11         24  
  11         572  
14 11     11   4568 use Pandoc::Error;
  11         28  
  11         3513  
15              
16             our @CARP_NOT = ('Pandoc');
17              
18             sub new {
19 87     87 0 6938 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         308 my $num = $_;
26 212 100       579 $num =~ /^\d+$/
27             or Pandoc::Error->throw(
28             message => 'invalid version number',
29             version => $num
30             );
31 207         312 $num =~ s/^0+(?=\d)//; # ensure decimal interpretation
32 207         336 $num = 0 + $num;
33 207         429 $num
34             }
35 109         267 map { s/^v//i; split /\./ } ## no critic
  109         265  
36 89 100 100     381 map { 'ARRAY' CORE::eq ( reftype $_ // "" ) ? @$_ : $_ }
37 87   100     136 map { $_ // '' } @_;
  89         269  
38              
39 82 100       188 Pandoc::Error->throw('invalid version number') unless @nums;
40              
41 79         220 return bless \@nums => $class;
42             }
43              
44 25     25 1 386 sub string { join '.', @{ $_[0] } }
  25         167  
45              
46             sub number {
47 133     133 1 172 my ( $major, @minors ) = @{ $_[0] };
  133         241  
48 11     11   151 no warnings qw(uninitialized numeric);
  11         30  
  11         7060  
49 133 100       255 if (@minors) {
50 121         164 my $minor = join '', map { sprintf '%03d', $_ } @minors;
  178         512  
51 121         910 return 0 + "$major.$minor"; # return a true number
52             }
53 12         30 return 0 + $major;
54             }
55              
56             sub cmp {
57             my ( $a, $b ) = map {
58 55 100 66 55 1 119 ( blessed $_ and $_->isa('Pandoc::Version') )
  110   33     1307  
59             ? $_
60             : Pandoc::Version->new( $_ // () )
61             } ( $_[0], $_[1] );
62 55         105 return $a->number <=> $b->number;
63             }
64              
65             sub match {
66 7     7 1 1551 my ( $a, $b ) = map { Pandoc::Version->new($_) } @_;
  14         28  
67 7         25 pop @$a while @$a > @$b;
68 7         15 pop @$b while @$b > @$a;
69              
70 7         13 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 4295 my ( $self, $req ) = @_;
84 17 50       39 return 1 unless $req;
85              
86 17         190 my @parts = split qr{\s*,\s*}, $req;
87 17         45 for my $part (@parts) {
88 32         204 my ( $op, $ver ) =
89             $part =~ m{^\s*(==|>=|>|<=|<|!=)?\s*v?(\d+(\.\d+)*)$};
90 32 100       76 if ( !defined $ver ) {
91 1         11 Pandoc::Error->throw(
92             message => "invalid version requirement: $req",
93             require => $req,
94             );
95             }
96              
97 31         61 my $cmp = $self->cmp($ver) + 1; # will be 0 for <, 1 for ==, 2 for >
98 31 100 100     155 return unless $cmp_truth_table{ $op || '>=' }->[$cmp];
99             }
100              
101 8         31 1;
102             }
103              
104             sub TO_JSON {
105 4     4 1 1500 my ($self) = @_;
106 4         32 return [ map { 0 + $_ } @$self ];
  16         44  
107             }
108              
109             1;
110              
111             __END__