1use strict; 2use warnings; 3 4use CPAN::Meta::Requirements; 5 6use Test::More 0.88; 7 8sub dies_ok (&@) { 9 my ($code, $qr, $comment) = @_; 10 11 no warnings 'redefine'; 12 local *Regexp::CARP_TRACE = sub { "<regexp>" }; 13 my $lived = eval { $code->(); 1 }; 14 15 if ($lived) { 16 fail("$comment: did not die"); 17 } else { 18 like($@, $qr, $comment); 19 } 20} 21 22{ 23 my $req = CPAN::Meta::Requirements->new; 24 25 $req->add_minimum('Foo::Bar' => 10); 26 $req->add_minimum('Foo::Bar' => 0); 27 $req->add_minimum('Foo::Bar' => 2); 28 29 $req->add_minimum('Foo::Baz' => version->declare('v1.2.3')); 30 31 $req->add_minimum('Foo::Undef' => undef); 32 33 is_deeply( 34 $req->as_string_hash, 35 { 36 'Foo::Bar' => 10, 37 'Foo::Baz' => 'v1.2.3', 38 'Foo::Undef' => 0, 39 }, 40 "some basic minimums", 41 ); 42 43 ok($req->is_simple, "just minimums? simple"); 44} 45 46{ 47 my $req = CPAN::Meta::Requirements->new; 48 $req->add_maximum(Foo => 1); 49 is_deeply($req->as_string_hash, { Foo => '<= 1' }, "max only"); 50 51 ok(! $req->is_simple, "maximums? not simple"); 52} 53 54{ 55 my $req = CPAN::Meta::Requirements->new; 56 $req->add_exclusion(Foo => 1); 57 $req->add_exclusion(Foo => 2); 58 59 # Why would you ever do this?? -- rjbs, 2010-02-20 60 is_deeply($req->as_string_hash, { Foo => '!= 1, != 2' }, "excl only"); 61} 62 63{ 64 my $req = CPAN::Meta::Requirements->new; 65 66 $req->add_minimum(Foo => 1); 67 $req->add_maximum(Foo => 2); 68 69 is_deeply( 70 $req->as_string_hash, 71 { 72 Foo => '>= 1, <= 2', 73 }, 74 "min and max", 75 ); 76 77 $req->add_maximum(Foo => 3); 78 79 is_deeply( 80 $req->as_string_hash, 81 { 82 Foo => '>= 1, <= 2', 83 }, 84 "exclusions already outside range do not matter", 85 ); 86 87 $req->add_exclusion(Foo => 1.5); 88 89 is_deeply( 90 $req->as_string_hash, 91 { 92 Foo => '>= 1, <= 2, != 1.5', 93 }, 94 "exclusions", 95 ); 96 97 $req->add_minimum(Foo => 1.6); 98 99 is_deeply( 100 $req->as_string_hash, 101 { 102 Foo => '>= 1.6, <= 2', 103 }, 104 "exclusions go away when made irrelevant", 105 ); 106} 107 108{ 109 my $req = CPAN::Meta::Requirements->new; 110 111 $req->add_minimum(Foo => 1); 112 $req->add_exclusion(Foo => 1); 113 $req->add_maximum(Foo => 2); 114 115 is_deeply( 116 $req->as_string_hash, 117 { 118 Foo => '> 1, <= 2', 119 }, 120 "we can exclude an endpoint", 121 ); 122} 123 124{ 125 my $req = CPAN::Meta::Requirements->new; 126 $req->add_minimum(Foo => 1); 127 128 $req->add_exclusion(Foo => 1); 129 130 dies_ok { $req->add_maximum(Foo => 1); } 131 qr/both 1, which is excluded/, 132 "can't exclude all values" ; 133} 134 135{ 136 my $req = CPAN::Meta::Requirements->new; 137 $req->add_minimum(Foo => 1); 138 dies_ok {$req->exact_version(Foo => 0.5); } 139 qr/outside of range/, 140 "can't add outside-range exact spec to range"; 141} 142 143{ 144 my $req = CPAN::Meta::Requirements->new; 145 $req->add_minimum(Foo => 1); 146 dies_ok { $req->add_maximum(Foo => 0.5); } 147 qr/minimum 1 exceeds maximum/, 148 "maximum must exceed (or equal) minimum"; 149 150 $req = CPAN::Meta::Requirements->new; 151 $req->add_maximum(Foo => 0.5); 152 dies_ok { $req->add_minimum(Foo => 1); } 153 qr/minimum 1 exceeds maximum/, 154 "maximum must exceed (or equal) minimum"; 155} 156 157{ 158 my $req = CPAN::Meta::Requirements->new; 159 160 $req->add_minimum(Foo => 1); 161 $req->add_maximum(Foo => 1); 162 163 $req->add_maximum(Foo => 2); # ignored 164 $req->add_minimum(Foo => 0); # ignored 165 $req->add_exclusion(Foo => .5); # ignored 166 167 is_deeply( 168 $req->as_string_hash, 169 { 170 'Foo' => '== 1', 171 }, 172 "if min==max, becomes exact requirement", 173 ); 174} 175 176{ 177 my $req = CPAN::Meta::Requirements->new; 178 $req->add_minimum(Foo => 1); 179 $req->add_exclusion(Foo => 0); 180 $req->add_maximum(Foo => 3); 181 $req->add_exclusion(Foo => 4); 182 183 $req->add_exclusion(Foo => 2); 184 $req->add_exclusion(Foo => 2); 185 186 is_deeply( 187 $req->as_string_hash, 188 { 189 Foo => '>= 1, <= 3, != 2', 190 }, 191 'test exclusion-skipping', 192 ); 193 194 is_deeply( 195 $req->structured_requirements_for_module('Foo'), 196 # remember, it's okay to change the exact results, as long as the meaning 197 # is unchanged -- rjbs, 2012-07-11 198 [ 199 [ '>=', '1' ], 200 [ '<=', '3' ], 201 [ '!=', '2' ], 202 ], 203 "structured requirements for Foo", 204 ); 205} 206 207sub foo_1 { 208 my $req = CPAN::Meta::Requirements->new; 209 $req->exact_version(Foo => 1); 210 return $req; 211} 212 213{ 214 my $req = foo_1; 215 216 $req->exact_version(Foo => 1); # ignored 217 218 is_deeply($req->as_string_hash, { Foo => '== 1' }, "exact requirement"); 219 220 dies_ok { $req->exact_version(Foo => 2); } 221 qr/can't be exactly 2.+already/, 222 "can't exactly specify differing versions" ; 223 224 $req = foo_1; 225 $req->add_minimum(Foo => 0); # ignored 226 $req->add_maximum(Foo => 2); # ignored 227 228 dies_ok { $req->add_maximum(Foo => 0); } qr/maximum 0 below exact/, "max < fixed"; 229 230 $req = foo_1; 231 dies_ok { $req->add_minimum(Foo => 2); } qr/minimum 2 exceeds exact/, "min > fixed"; 232 233 $req = foo_1; 234 $req->add_exclusion(Foo => 8); # ignored 235 dies_ok { $req->add_exclusion(Foo => 1); } qr/tried to exclude/, "!= && =="; 236} 237 238{ 239 my $req = foo_1; 240 241 is($req->requirements_for_module('Foo'), '== 1', 'requirements_for_module'); 242 243 is_deeply( 244 $req->structured_requirements_for_module('Foo'), 245 [ [ '==', '1' ] ], 246 'structured_requirements_for_module' 247 ); 248 249 # test empty/undef returns 250 my @list = $req->requirements_for_module('FooBarBamBaz'); 251 my $scalar = $req->requirements_for_module('FooBarBamBaz'); 252 is ( scalar @list, 0, "requirements_for_module() returns empty for not found (list)" ); 253 is ( $scalar, undef, "requirements_for_module() returns undef for not found (scalar)" ); 254} 255 256{ 257 my $req = CPAN::Meta::Requirements->new; 258 259 $req->add_minimum(Foo => "0.00"); 260 261 my $req2 = CPAN::Meta::Requirements->new; 262 $req2->add_requirements($req); 263 264 is_deeply( 265 $req2->as_string_hash, 266 { 267 Foo => '0.00' 268 }, 269 "0.00 precision preserved", 270 ); 271 272} 273 274done_testing; 275