1use strict;
2use warnings;
3use Test::More 0.88;
4
5sub dies_ok (&@) {
6  my ($code, $qr, $comment) = @_;
7
8  no warnings 'redefine';
9  local *Regexp::CARP_TRACE  = sub { "<regexp>" };
10  my $lived = eval { $code->(); 1 };
11
12  if ($lived) {
13    fail("$comment: did not die");
14  } else {
15    like($@, $qr, $comment);
16  }
17}
18
19use CPAN::Meta::Requirements;
20
21
22my $base = 'CPAN::Meta::Requirements::Range';
23
24# Test ==
25my $range = $base->with_string_requirement('== 1.3');
26ok($range->accepts('1.3'), 'exact version (==)');
27ok(!$range->accepts('1.2'), 'lower version (==)');
28ok(!$range->accepts('1.4'), 'higher version (==)');
29
30# Test !=
31$range = $base->with_string_requirement('!= 1.3');
32ok(!$range->accepts('1.3'), 'exact version (!=)');
33ok($range->accepts('1.2'), 'lower version (!=)');
34ok($range->accepts('1.4'), 'higher version (!=)');
35
36# Test >=
37$range = $base->with_string_requirement('>= 1.3');
38ok($range->accepts('1.3'), 'exact version (>=)');
39ok(!$range->accepts('1.2'), 'lower version (>=)');
40ok($range->accepts('1.4'), 'higher version (>=)');
41
42# Test <=
43$range = $range = $base->with_string_requirement('<= 1.3');
44ok($range->accepts('1.3'), 'exact version (<=)');
45ok($range->accepts('1.2'), 'lower version (<=)');
46ok(!$range->accepts('1.4'), 'higher version (<=)');
47
48# Test ""
49$range = $base->with_string_requirement('1.3');
50ok($range->accepts('1.3'), 'exact version ("")');
51ok(!$range->accepts('1.2'), 'lower version ("")');
52ok($range->accepts('1.4'), 'higher version ("")');
53
54# Test multiple requirements
55$range = $base->with_string_requirement('>= 1.3, <= 2.0, != 1.6');
56ok($range->accepts('1.5'), 'middle version (>=, <=, !)');
57ok(!$range->accepts('1.2'), 'lower version (>=, <=, !)');
58ok(!$range->accepts('2.1'), 'higher version (>=, <=, !)');
59ok(!$range->accepts('1.6'), 'excluded version (>=, <=, !)');
60
61# Test multiple requirements with implicit minimum
62$range = $base->with_string_requirement('0.90, != 0.91');
63ok(!$range->accepts('0.88'), 'lower version ("", !)');
64ok($range->accepts('0.90'), 'exact version ("", !)');
65ok($range->accepts('0.901'), 'middle version ("", !)');
66ok(!$range->accepts('0.91'), 'excluded version ("", !)');
67ok($range->accepts('0.92'), 'higher version ("", !)');
68
69my $req = CPAN::Meta::Requirements->new;
70
71# Test ==
72$req->add_string_requirement('Foo::Bar', '== 1.3');
73ok($req->accepts_module('Foo::Bar' => '1.3'), 'exact version (==)');
74ok(!$req->accepts_module('Foo::Bar' => '1.2'), 'lower version (==)');
75ok(!$req->accepts_module('Foo::Bar' => '1.4'), 'higher version (==)');
76
77# Test !=
78$req->add_string_requirement('Foo::Baz', '!= 1.3');
79ok(!$req->accepts_module('Foo::Baz' => '1.3'), 'exact version (!=)');
80ok($req->accepts_module('Foo::Baz' => '1.2'), 'lower version (!=)');
81ok($req->accepts_module('Foo::Baz' => '1.4'), 'higher version (!=)');
82
83# Test >=
84$req->add_string_requirement('Foo::Gorch', '>= 1.3');
85ok($req->accepts_module('Foo::Gorch' => '1.3'), 'exact version (>=)');
86ok(!$req->accepts_module('Foo::Gorch' => '1.2'), 'lower version (>=)');
87ok($req->accepts_module('Foo::Gorch' => '1.4'), 'higher version (>=)');
88
89# Test <=
90$req->add_string_requirement('Foo::Graz', '<= 1.3');
91ok($req->accepts_module('Foo::Graz' => '1.3'), 'exact version (<=)');
92ok($req->accepts_module('Foo::Graz' => '1.2'), 'lower version (<=)');
93ok(!$req->accepts_module('Foo::Graz' => '1.4'), 'higher version (<=)');
94
95# Test ""
96$req->add_string_requirement('Foo::Blurb', '1.3');
97ok($req->accepts_module('Foo::Blurb' => '1.3'), 'exact version ("")');
98ok(!$req->accepts_module('Foo::Blurb' => '1.2'), 'lower version ("")');
99ok($req->accepts_module('Foo::Blurb' => '1.4'), 'higher version ("")');
100
101# Test multiple requirements
102$req->add_string_requirement('A::Tribe::Called', '>= 1.3, <= 2.0, != 1.6');
103ok($req->accepts_module('A::Tribe::Called' => '1.5'), 'middle version (>=, <=, !)');
104ok(!$req->accepts_module('A::Tribe::Called' => '1.2'), 'lower version (>=, <=, !)');
105ok(!$req->accepts_module('A::Tribe::Called' => '2.1'), 'higher version (>=, <=, !)');
106ok(!$req->accepts_module('A::Tribe::Called' => '1.6'), 'excluded version (>=, <=, !)');
107
108# Test multiple requirements with implicit minimum
109{
110  my $req = CPAN::Meta::Requirements->new;
111
112  $req->add_string_requirement('Foo::MyModule', '0.90, != 0.91');
113
114  is_deeply(
115    $req->as_string_hash,
116    {
117      'Foo::MyModule' => '>= 0.90, != 0.91'
118    },
119    "multiple requirements with implicit minimum",
120  );
121}
122
123# Test precision
124{
125  my $req = CPAN::Meta::Requirements->new;
126
127  $req->add_string_requirement(Foo => "0.00");
128
129  is_deeply(
130    $req->as_string_hash,
131    {
132      Foo => '0.00'
133    },
134    "0.00 precision preserved",
135  );
136}
137
138# Test fatal errors
139dies_ok { $req->add_string_requirement('Foo::Bar', "not really a version") }
140  qr/Can't convert/,
141  "conversion failure caught";
142
143done_testing;
144