This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Revise check for negative versions plus test
[perl5.git] / lib / version.t
1 #! /usr/local/perl -w
2
3 use Test::More qw(no_plan);
4 use Data::Dumper;
5 require Test::Harness;
6 no warnings 'once';
7 *Verbose = \$Test::Harness::Verbose;
8 use POSIX qw/locale_h/;
9 use File::Temp qw/tempfile/;
10 use File::Basename;
11
12 BEGIN {
13     use_ok("version", 0.77);
14     # If we made it this far, we are ok.
15 }
16
17 my $Verbose;
18
19 diag "Tests with base class" unless $ENV{PERL_CORE};
20
21 BaseTests("version","new","qv");
22 BaseTests("version","new","declare");
23 BaseTests("version","parse", "qv");
24 BaseTests("version","parse", "declare");
25
26 # dummy up a redundant call to satisfy David Wheeler
27 local $SIG{__WARN__} = sub { die $_[0] };
28 eval 'use version;';
29 unlike ($@, qr/^Subroutine main::declare redefined/,
30     "Only export declare once per package (to prevent redefined warnings)."); 
31
32 package version::Bad;
33 use base 'version';
34 sub new { my($self,$n)=@_;  bless \$n, $self }
35
36 package main;
37
38 my $warning;
39 local $SIG{__WARN__} = sub { $warning = $_[0] };
40 my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
41 (my $package = basename($filename)) =~ s/\.pm$//;
42 print $fh <<"EOF";
43 # This is an empty subclass
44 package $package;
45 use base 'version';
46 use vars '\$VERSION';
47 \$VERSION=0.001;
48 EOF
49 close $fh;
50
51 sub main_reset {
52     delete $main::INC{'$package'};
53     undef &qv; undef *::qv; # avoid 'used once' warning
54     undef &declare; undef *::declare; # avoid 'used once' warning
55 }
56
57 diag "Tests with empty derived class"  unless $ENV{PERL_CORE};
58
59 use_ok($package, 0.001);
60 my $testobj = $package->new(1.002_003);
61 isa_ok( $testobj, $package );
62 ok( $testobj->numify == 1.002003, "Numified correctly" );
63 ok( $testobj->stringify eq "1.002003", "Stringified correctly" );
64 ok( $testobj->normal eq "v1.2.3", "Normalified correctly" );
65
66 my $verobj = version::->new("1.2.4");
67 ok( $verobj > $testobj, "Comparison vs parent class" );
68
69 BaseTests($package, "new", "qv");
70 main_reset;
71 use_ok($package, 0.001, "declare");
72 BaseTests($package, "new", "declare");
73 main_reset;
74 use_ok($package, 0.001);
75 BaseTests($package, "parse", "qv");
76 main_reset;
77 use_ok($package, 0.001, "declare");
78 BaseTests($package, "parse", "declare");
79
80 diag "tests with bad subclass"  unless $ENV{PERL_CORE};
81 $testobj = version::Bad->new(1.002_003);
82 isa_ok( $testobj, "version::Bad" );
83 eval { my $string = $testobj->numify };
84 like($@, qr/Invalid version object/,
85     "Bad subclass numify");
86 eval { my $string = $testobj->normal };
87 like($@, qr/Invalid version object/,
88     "Bad subclass normal");
89 eval { my $string = $testobj->stringify };
90 like($@, qr/Invalid version object/,
91     "Bad subclass stringify");
92 eval { my $test = ($testobj > 1.0) };
93 like($@, qr/Invalid version object/,
94     "Bad subclass vcmp");
95
96 # Invalid structure
97 eval { $a = \\version->new(1); bless $a, "version"; print "# $a\n" };
98 like($@, qr/Invalid version object/,
99     "Bad internal structure (RT#78286)");
100
101 # do strict lax tests in a sub to isolate a package to test importing
102 strict_lax_tests();
103
104 sub strict_lax_tests {
105   package temp12345;
106   # copied from perl core test t/op/packagev.t
107   # format: STRING STRICT_OK LAX_OK
108   my $strict_lax_data = << 'CASE_DATA';
109 1.00            pass    pass
110 1.00001         pass    pass
111 0.123           pass    pass
112 12.345          pass    pass
113 42              pass    pass
114 0               pass    pass
115 0.0             pass    pass
116 v1.2.3          pass    pass
117 v1.2.3.4        pass    pass
118 v0.1.2          pass    pass
119 v0.0.0          pass    pass
120 01              fail    pass
121 01.0203         fail    pass
122 v01             fail    pass
123 v01.02.03       fail    pass
124 .1              fail    pass
125 .1.2            fail    pass
126 1.              fail    pass
127 1.a             fail    fail
128 1._             fail    fail
129 1.02_03         fail    pass
130 v1.2_3          fail    pass
131 v1.02_03        fail    pass
132 v1.2_3_4        fail    fail
133 v1.2_3.4        fail    fail
134 1.2_3.4         fail    fail
135 0_              fail    fail
136 1_              fail    fail
137 1_.             fail    fail
138 1.1_            fail    fail
139 1.02_03_04      fail    fail
140 1.2.3           fail    pass
141 v1.2            fail    pass
142 v0              fail    pass
143 v1              fail    pass
144 v.1.2.3         fail    fail
145 v               fail    fail
146 v1.2345.6       fail    pass
147 undef           fail    pass
148 1a              fail    fail
149 1.2a3           fail    fail
150 bar             fail    fail
151 _               fail    fail
152 CASE_DATA
153
154   require version;
155   version->import( qw/is_strict is_lax/ );
156   for my $case ( split qr/\n/, $strict_lax_data ) {
157     my ($v, $strict, $lax) = split qr/\t+/, $case;
158     main::ok( $strict eq 'pass' ? is_strict($v) : ! is_strict($v), "is_strict($v) [$strict]" );
159     main::ok( $strict eq 'pass' ? version::is_strict($v) : ! version::is_strict($v), "version::is_strict($v) [$strict]" );
160     main::ok( $lax eq 'pass' ? is_lax($v) : ! is_lax($v), "is_lax($v) [$lax]" );
161     main::ok( $lax eq 'pass' ? version::is_lax($v) : ! version::is_lax($v), "version::is_lax($v) [$lax]" );
162   }
163 }
164
165 sub BaseTests {
166
167     my ($CLASS, $method, $qv_declare) = @_;
168     my $warning;
169     local $SIG{__WARN__} = sub { $warning = $_[0] };
170     
171     # Insert your test code below, the Test module is use()ed here so read
172     # its man page ( perldoc Test ) for help writing this test script.
173     
174     # Test bare number processing
175     diag "tests with bare numbers" unless $ENV{PERL_CORE};
176     $version = $CLASS->$method(5.005_03);
177     is ( "$version" , "5.00503" , '5.005_03 eq 5.00503' );
178     $version = $CLASS->$method(1.23);
179     is ( "$version" , "1.23" , '1.23 eq "1.23"' );
180     
181     # Test quoted number processing
182     diag "tests with quoted numbers" unless $ENV{PERL_CORE};
183     $version = $CLASS->$method("5.005_03");
184     is ( "$version" , "5.005_03" , '"5.005_03" eq "5.005_03"' );
185     $version = $CLASS->$method("v1.23");
186     is ( "$version" , "v1.23" , '"v1.23" eq "v1.23"' );
187     
188     # Test stringify operator
189     diag "tests with stringify" unless $ENV{PERL_CORE};
190     $version = $CLASS->$method("5.005");
191     is ( "$version" , "5.005" , '5.005 eq "5.005"' );
192     $version = $CLASS->$method("5.006.001");
193     is ( "$version" , "5.006.001" , '5.006.001 eq v5.6.1' );
194     unlike ($warning, qr/v-string without leading 'v' deprecated/, 'No leading v');
195     $version = $CLASS->$method("v1.2.3_4");
196     is ( "$version" , "v1.2.3_4" , 'alpha version 1.2.3_4 eq v1.2.3_4' );
197     
198     # test illegal formats
199     diag "test illegal formats" unless $ENV{PERL_CORE};
200     eval {my $version = $CLASS->$method("1.2_3_4")};
201     like($@, qr/multiple underscores/,
202         "Invalid version format (multiple underscores)");
203     
204     eval {my $version = $CLASS->$method("1.2_3.4")};
205     like($@, qr/underscores before decimal/,
206         "Invalid version format (underscores before decimal)");
207     
208     eval {my $version = $CLASS->$method("1_2")};
209     like($@, qr/alpha without decimal/,
210         "Invalid version format (alpha without decimal)");
211     
212     eval { $version = $CLASS->$method("1.2b3")};
213     like($@, qr/non-numeric data/,
214         "Invalid version format (non-numeric data)");
215
216     eval { $version = $CLASS->$method("-1.23")};
217     like($@, qr/negative version number/,
218         "Invalid version format (negative version number)");
219
220     # from here on out capture the warning and test independently
221     {
222     eval{$version = $CLASS->$method("99 and 44/100 pure")};
223
224     like($@, qr/non-numeric data/,
225         "Invalid version format (non-numeric data)");
226     
227     eval{$version = $CLASS->$method("something")};
228     like($@, qr/non-numeric data/,
229         "Invalid version format (non-numeric data)");
230     
231     # reset the test object to something reasonable
232     $version = $CLASS->$method("1.2.3");
233     
234     # Test boolean operator
235     ok ($version, 'boolean');
236     
237     # Test class membership
238     isa_ok ( $version, $CLASS );
239     
240     # Test comparison operators with self
241     diag "tests with self" unless $ENV{PERL_CORE};
242     is ( $version <=> $version, 0, '$version <=> $version == 0' );
243     ok ( $version == $version, '$version == $version' );
244     
245     # Test Numeric Comparison operators
246     # test first with non-object
247     $version = $CLASS->$method("5.006.001");
248     $new_version = "5.8.0";
249     diag "numeric tests with non-objects" unless $ENV{PERL_CORE};
250     ok ( $version == $version, '$version == $version' );
251     ok ( $version < $new_version, '$version < $new_version' );
252     ok ( $new_version > $version, '$new_version > $version' );
253     ok ( $version != $new_version, '$version != $new_version' );
254     
255     # now test with existing object
256     $new_version = $CLASS->$method($new_version);
257     diag "numeric tests with objects" unless $ENV{PERL_CORE};
258     ok ( $version < $new_version, '$version < $new_version' );
259     ok ( $new_version > $version, '$new_version > $version' );
260     ok ( $version != $new_version, '$version != $new_version' );
261     
262     # now test with actual numbers
263     diag "numeric tests with numbers" unless $ENV{PERL_CORE};
264     ok ( $version->numify() == 5.006001, '$version->numify() == 5.006001' );
265     ok ( $version->numify() <= 5.006001, '$version->numify() <= 5.006001' );
266     ok ( $version->numify() < 5.008, '$version->numify() < 5.008' );
267     #ok ( $version->numify() > v5.005_02, '$version->numify() > 5.005_02' );
268     
269     # test with long decimals
270     diag "Tests with extended decimal versions" unless $ENV{PERL_CORE};
271     $version = $CLASS->$method(1.002003);
272     ok ( $version == "1.2.3", '$version == "1.2.3"');
273     ok ( $version->numify == 1.002003, '$version->numify == 1.002003');
274     $version = $CLASS->$method("2002.09.30.1");
275     ok ( $version == "2002.9.30.1",'$version == 2002.9.30.1');
276     ok ( $version->numify == 2002.009030001,
277         '$version->numify == 2002.009030001');
278     
279     # now test with alpha version form with string
280     $version = $CLASS->$method("1.2.3");
281     $new_version = "1.2.3_4";
282     diag "numeric tests with alpha-style non-objects" unless $ENV{PERL_CORE};
283     ok ( $version < $new_version, '$version < $new_version' );
284     ok ( $new_version > $version, '$new_version > $version' );
285     ok ( $version != $new_version, '$version != $new_version' );
286     
287     $version = $CLASS->$method("1.2.4");
288     diag "numeric tests with alpha-style non-objects"
289         unless $ENV{PERL_CORE};
290     ok ( $version > $new_version, '$version > $new_version' );
291     ok ( $new_version < $version, '$new_version < $version' );
292     ok ( $version != $new_version, '$version != $new_version' );
293     
294     # now test with alpha version form with object
295     $version = $CLASS->$method("1.2.3");
296     $new_version = $CLASS->$method("1.2.3_4");
297     diag "tests with alpha-style objects" unless $ENV{PERL_CORE};
298     ok ( $version < $new_version, '$version < $new_version' );
299     ok ( $new_version > $version, '$new_version > $version' );
300     ok ( $version != $new_version, '$version != $new_version' );
301     ok ( !$version->is_alpha, '!$version->is_alpha');
302     ok ( $new_version->is_alpha, '$new_version->is_alpha');
303     
304     $version = $CLASS->$method("1.2.4");
305     diag "tests with alpha-style objects" unless $ENV{PERL_CORE};
306     ok ( $version > $new_version, '$version > $new_version' );
307     ok ( $new_version < $version, '$new_version < $version' );
308     ok ( $version != $new_version, '$version != $new_version' );
309     
310     $version = $CLASS->$method("1.2.3.4");
311     $new_version = $CLASS->$method("1.2.3_4");
312     diag "tests with alpha-style objects with same subversion"
313         unless $ENV{PERL_CORE};
314     ok ( $version > $new_version, '$version > $new_version' );
315     ok ( $new_version < $version, '$new_version < $version' );
316     ok ( $version != $new_version, '$version != $new_version' );
317     
318     diag "test implicit [in]equality" unless $ENV{PERL_CORE};
319     $version = $CLASS->$method("v1.2.3");
320     $new_version = $CLASS->$method("1.2.3.0");
321     ok ( $version == $new_version, '$version == $new_version' );
322     $new_version = $CLASS->$method("1.2.3_0");
323     ok ( $version == $new_version, '$version == $new_version' );
324     $new_version = $CLASS->$method("1.2.3.1");
325     ok ( $version < $new_version, '$version < $new_version' );
326     $new_version = $CLASS->$method("1.2.3_1");
327     ok ( $version < $new_version, '$version < $new_version' );
328     $new_version = $CLASS->$method("1.1.999");
329     ok ( $version > $new_version, '$version > $new_version' );
330     
331     # that which is not expressly permitted is forbidden
332     diag "forbidden operations" unless $ENV{PERL_CORE};
333     ok ( !eval { ++$version }, "noop ++" );
334     ok ( !eval { --$version }, "noop --" );
335     ok ( !eval { $version/1 }, "noop /" );
336     ok ( !eval { $version*3 }, "noop *" );
337     ok ( !eval { abs($version) }, "noop abs" );
338
339 SKIP: {
340     skip "version require'd instead of use'd, cannot test $qv_declare", 3
341         unless defined $qv_declare;
342     # test the $qv_declare() sub
343     diag "testing $qv_declare" unless $ENV{PERL_CORE};
344     $version = $CLASS->$qv_declare("1.2");
345     is ( "$version", "v1.2", $qv_declare.'("1.2") == "1.2.0"' );
346     $version = $CLASS->$qv_declare(1.2);
347     is ( "$version", "v1.2", $qv_declare.'(1.2) == "1.2.0"' );
348     isa_ok( $CLASS->$qv_declare('5.008'), $CLASS );
349 }
350
351     # test creation from existing version object
352     diag "create new from existing version" unless $ENV{PERL_CORE};
353     ok (eval {$new_version = $CLASS->$method($version)},
354             "new from existing object");
355     ok ($new_version == $version, "class->$method($version) identical");
356     $new_version = $version->$method(0);
357     isa_ok ($new_version, $CLASS );
358     is ($new_version, "0", "version->$method() doesn't clone");
359     $new_version = $version->$method("1.2.3");
360     is ($new_version, "1.2.3" , '$version->$method("1.2.3") works too');
361
362     # test the CVS revision mode
363     diag "testing CVS Revision" unless $ENV{PERL_CORE};
364     $version = new $CLASS qw$Revision: 1.2$;
365     ok ( $version == "1.2.0", 'qw$Revision: 1.2$ == 1.2.0' );
366     $version = new $CLASS qw$Revision: 1.2.3.4$;
367     ok ( $version == "1.2.3.4", 'qw$Revision: 1.2.3.4$ == 1.2.3.4' );
368     
369     # test the CPAN style reduced significant digit form
370     diag "testing CPAN-style versions" unless $ENV{PERL_CORE};
371     $version = $CLASS->$method("1.23_01");
372     is ( "$version" , "1.23_01", "CPAN-style alpha version" );
373     ok ( $version > 1.23, "1.23_01 > 1.23");
374     ok ( $version < 1.24, "1.23_01 < 1.24");
375
376     # test reformed UNIVERSAL::VERSION
377     diag "Replacement UNIVERSAL::VERSION tests" unless $ENV{PERL_CORE};
378
379     my $error_regex = $] < 5.006
380         ? 'version \d required'
381         : 'does not define \$t.{7}::VERSION';
382     
383     {
384         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
385         (my $package = basename($filename)) =~ s/\.pm$//;
386         print $fh "package $package;\n\$$package\::VERSION=0.58;\n1;\n";
387         close $fh;
388
389         $version = 0.58;
390         eval "use lib '.'; use $package $version";
391         unlike($@, qr/$package version $version/,
392                 'Replacement eval works with exact version');
393         
394         # test as class method
395         $new_version = $package->VERSION;
396         cmp_ok($new_version,'==',$version, "Called as class method");
397
398         eval "print Completely::Unknown::Module->VERSION";
399         if ( $] < 5.008 ) {
400             unlike($@, qr/$error_regex/,
401                 "Don't freak if the module doesn't even exist");
402         }
403         else {
404             unlike($@, qr/defines neither package nor VERSION/,
405                 "Don't freak if the module doesn't even exist");
406         }
407
408         # this should fail even with old UNIVERSAL::VERSION
409         $version += 0.01;
410         eval "use lib '.'; use $package $version";
411         like($@, qr/$package version $version/,
412                 'Replacement eval works with incremented version');
413         
414         $version =~ s/0+$//; #convert to string and remove trailing 0's
415         chop($version); # shorten by 1 digit, should still succeed
416         eval "use lib '.'; use $package $version";
417         unlike($@, qr/$package version $version/,
418                 'Replacement eval works with single digit');
419         
420         # this would fail with old UNIVERSAL::VERSION
421         $version += 0.1;
422         eval "use lib '.'; use $package $version";
423         like($@, qr/$package version $version/,
424                 'Replacement eval works with incremented digit');
425         unlink $filename;
426     }
427
428     { # dummy up some variously broken modules for testing
429         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
430         (my $package = basename($filename)) =~ s/\.pm$//;
431         print $fh "1;\n";
432         close $fh;
433
434         eval "use lib '.'; use $package 3;";
435         if ( $] < 5.008 ) {
436             like($@, qr/$error_regex/,
437                 'Replacement handles modules without package or VERSION'); 
438         }
439         else {
440             like($@, qr/defines neither package nor VERSION/,
441                 'Replacement handles modules without package or VERSION'); 
442         }
443         eval "use lib '.'; use $package; \$version = $package->VERSION";
444         unlike ($@, qr/$error_regex/,
445             'Replacement handles modules without package or VERSION'); 
446         ok (!defined($version), "Called as class method");
447         unlink $filename;
448     }
449     
450     { # dummy up some variously broken modules for testing
451         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
452         (my $package = basename($filename)) =~ s/\.pm$//;
453         print $fh "package $package;\n#look ma no VERSION\n1;\n";
454         close $fh;
455         eval "use lib '.'; use $package 3;";
456         like ($@, qr/$error_regex/,
457             'Replacement handles modules without VERSION'); 
458         eval "use lib '.'; use $package; print $package->VERSION";
459         unlike ($@, qr/$error_regex/,
460             'Replacement handles modules without VERSION'); 
461         unlink $filename;
462     }
463
464     { # dummy up some variously broken modules for testing
465         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
466         (my $package = basename($filename)) =~ s/\.pm$//;
467         print $fh "package $package;\n\@VERSION = ();\n1;\n";
468         close $fh;
469         eval "use lib '.'; use $package 3;";
470         like ($@, qr/$error_regex/,
471             'Replacement handles modules without VERSION'); 
472         eval "use lib '.'; use $package; print $package->VERSION";
473         unlike ($@, qr/$error_regex/,
474             'Replacement handles modules without VERSION'); 
475         unlink $filename;
476     }
477
478 SKIP:   {
479         skip 'Cannot test bare v-strings with Perl < 5.6.0', 4
480                 if $] < 5.006_000; 
481         diag "Tests with v-strings" unless $ENV{PERL_CORE};
482         $version = $CLASS->$method(1.2.3);
483         ok("$version" eq "v1.2.3", '"$version" eq 1.2.3');
484         $version = $CLASS->$method(1.0.0);
485         $new_version = $CLASS->$method(1);
486         ok($version == $new_version, '$version == $new_version');
487         skip "version require'd instead of use'd, cannot test declare", 1
488             unless defined $qv_declare;
489         $version = &$qv_declare(1.2.3);
490         ok("$version" eq "v1.2.3", 'v-string initialized $qv_declare()');
491     }
492
493 SKIP:   {
494         skip 'Cannot test bare alpha v-strings with Perl < 5.8.1', 2
495                 if $] lt 5.008_001; 
496         diag "Tests with bare alpha v-strings" unless $ENV{PERL_CORE};
497         $version = $CLASS->$method(v1.2.3_4);
498         is($version, "v1.2.3_4", '"$version" eq "v1.2.3_4"');
499         $version = $CLASS->$method(eval "v1.2.3_4");
500         is($version, "v1.2.3_4", '"$version" eq "v1.2.3_4" (from eval)');
501     }
502
503     diag "Tests with real-world (malformed) data" unless $ENV{PERL_CORE};
504
505     # trailing zero testing (reported by Andreas Koenig).
506     $version = $CLASS->$method("1");
507     ok($version->numify eq "1.000", "trailing zeros preserved");
508     $version = $CLASS->$method("1.0");
509     ok($version->numify eq "1.000", "trailing zeros preserved");
510     $version = $CLASS->$method("1.0.0");
511     ok($version->numify eq "1.000000", "trailing zeros preserved");
512     $version = $CLASS->$method("1.0.0.0");
513     ok($version->numify eq "1.000000000", "trailing zeros preserved");
514     
515     # leading zero testing (reported by Andreas Koenig).
516     $version = $CLASS->$method(".7");
517     ok($version->numify eq "0.700", "leading zero inferred");
518
519     # leading space testing (reported by Andreas Koenig).
520     $version = $CLASS->$method(" 1.7");
521     ok($version->numify eq "1.700", "leading space ignored");
522
523     # RT 19517 - deal with undef and 'undef' initialization
524     ok("$version" ne 'undef', "Undef version comparison #1");
525     ok("$version" ne undef, "Undef version comparison #2");
526     $version = $CLASS->$method('undef');
527     unlike($warning, qr/^Version string 'undef' contains invalid data/,
528         "Version string 'undef'");
529
530     $version = $CLASS->$method(undef);
531     like($warning, qr/^Use of uninitialized value/,
532         "Version string 'undef'");
533     ok($version == 'undef', "Undef version comparison #3");
534     ok($version ==  undef,  "Undef version comparison #4");
535     eval "\$version = \$CLASS->$method()"; # no parameter at all
536     unlike($@, qr/^Bizarre copy of CODE/, "No initializer at all");
537     ok($version == 'undef', "Undef version comparison #5");
538     ok($version ==  undef,  "Undef version comparison #6");
539
540     $version = $CLASS->$method(0.000001);
541     unlike($warning, qr/^Version string '1e-06' contains invalid data/,
542         "Very small version objects");
543     }
544
545 SKIP: {
546         my $warning;
547         local $SIG{__WARN__} = sub { $warning = $_[0] };
548         # dummy up a legal module for testing RT#19017
549         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
550         (my $package = basename($filename)) =~ s/\.pm$//;
551         print $fh <<"EOF";
552 package $package;
553 use $CLASS; \$VERSION = ${CLASS}->new('0.0.4');
554 1;
555 EOF
556         close $fh;
557
558         eval "use lib '.'; use $package 0.000008;";
559         like ($@, qr/^$package version 0.000008 required/,
560             "Make sure very small versions don't freak"); 
561         eval "use lib '.'; use $package 1;";
562         like ($@, qr/^$package version 1 required/,
563             "Comparing vs. version with no decimal"); 
564         eval "use lib '.'; use $package 1.;";
565         like ($@, qr/^$package version 1 required/,
566             "Comparing vs. version with decimal only"); 
567         if ( $] < 5.006_000 ) {
568             skip 'Cannot "use" extended versions with Perl < 5.6.0', 3; 
569         }
570         eval "use lib '.'; use $package v0.0.8;";
571         my $regex = "^$package version v0.0.8 required";
572         like ($@, qr/$regex/, "Make sure very small versions don't freak"); 
573
574         $regex =~ s/8/4/; # set for second test
575         eval "use lib '.'; use $package v0.0.4;";
576         unlike($@, qr/$regex/, 'Succeed - required == VERSION');
577         cmp_ok ( $package->VERSION, 'eq', '0.0.4', 'No undef warnings' );
578         unlink $filename;
579     }
580
581 SKIP: {
582     skip 'Cannot test "use base qw(version)"  when require is used', 3
583         unless defined $qv_declare;
584     my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
585     (my $package = basename($filename)) =~ s/\.pm$//;
586     print $fh <<"EOF";
587 package $package;
588 use base qw(version);
589 1;
590 EOF
591     close $fh;
592     # need to eliminate any other $qv_declare()'s
593     undef *{"main\::$qv_declare"};
594     ok(!defined(&{"main\::$qv_declare"}), "make sure we cleared $qv_declare() properly");
595     eval "use lib '.'; use $package qw/declare qv/;";
596     ok(defined(&{"main\::$qv_declare"}), "make sure we exported $qv_declare() properly");
597     isa_ok( &$qv_declare(1.2), $package);
598     unlink $filename;
599 }
600
601 SKIP: {
602         if ( $] < 5.006_000 ) {
603             skip 'Cannot "use" extended versions with Perl < 5.6.0', 3; 
604         }
605         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
606         (my $package = basename($filename)) =~ s/\.pm$//;
607         print $fh <<"EOF";
608 package $package;
609 \$VERSION = 1.0;
610 1;
611 EOF
612         close $fh;
613         eval "use lib '.'; use $package 1.001;";
614         like ($@, qr/^$package version 1.001 required/,
615             "User typed numeric so we error with numeric"); 
616         eval "use lib '.'; use $package v1.1.0;";
617         like ($@, qr/^$package version v1.1.0 required/,
618             "User typed extended so we error with extended"); 
619         unlink $filename;
620     }
621
622 SKIP: {
623         # test locale handling
624         my $warning;
625         local $SIG{__WARN__} = sub { $warning = $_[0] };
626
627 $DB::single = 1;
628         my $v = eval { $CLASS->$method('1,7') };
629 #       is( $@, "", 'Directly test comma as decimal compliance');
630
631         my $ver = 1.23;  # has to be floating point number
632         my $orig_loc = setlocale( LC_ALL );
633         my $loc;
634         while (<DATA>) {
635             chomp;
636             $loc = setlocale( LC_ALL, $_);
637             last if localeconv()->{decimal_point} eq ',';
638         }
639         skip 'Cannot test locale handling without a comma locale', 4
640             unless ( $loc and ($ver eq '1,23') );
641
642         diag ("Testing locale handling with $loc") unless $ENV{PERL_CORE};
643
644         $v = $CLASS->$method($ver);
645         unlike($warning, qr/Version string '1,23' contains invalid data/,
646             "Process locale-dependent floating point");
647         is ($v, "1.23", "Locale doesn't apply to version objects");
648         ok ($v == $ver, "Comparison to locale floating point");
649
650         setlocale( LC_ALL, $orig_loc); # reset this before possible skip
651         skip 'Cannot test RT#46921 with Perl < 5.008', 1
652             if ($] < 5.008);
653         skip 'Cannot test RT#46921 with pure Perl module', 1
654             if exists $INC{'version/vpp.pm'};
655         my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
656         (my $package = basename($filename)) =~ s/\.pm$//;
657         print $fh <<"EOF";
658 package $package;
659 use POSIX qw(locale_h);
660 \$^W = 1;
661 use $CLASS;
662 setlocale (LC_ALL, '$loc');
663 use $CLASS ;
664 eval "use Socket 1.7";
665 setlocale( LC_ALL, '$orig_loc');
666 1;
667 EOF
668         close $fh;
669
670         eval "use lib '.'; use $package;";
671         unlike($warning, qr"Version string '1,7' contains invalid data",
672             'Handle locale action-at-a-distance');
673     }
674
675     eval 'my $v = $CLASS->$method("1._1");';
676     unlike($@, qr/^Invalid version format \(alpha with zero width\)/,
677         "Invalid version format 1._1");
678
679     {
680         my $warning;
681         local $SIG{__WARN__} = sub { $warning = $_[0] };
682         eval 'my $v = $CLASS->$method(~0);';
683         unlike($@, qr/Integer overflow in version/, "Too large version");
684         like($warning, qr/Integer overflow in version/, "Too large version");
685     }
686
687     {
688         # http://rt.cpan.org/Public/Bug/Display.html?id=30004
689         my $v1 = $CLASS->$method("v0.1_1");
690         (my $alpha1 = Dumper($v1)) =~ s/.+'alpha' => ([^,]+),.+/$1/ms;
691         my $v2 = $CLASS->$method($v1);
692         (my $alpha2 = Dumper($v2)) =~ s/.+'alpha' => ([^,]+),.+/$1/ms;
693         is $alpha2, $alpha1, "Don't fall for Data::Dumper's tricks";
694     }
695
696     {
697         # http://rt.perl.org/rt3/Ticket/Display.html?id=56606
698         my $badv = bless { version => [1,2,3] }, "version";
699         is $badv, '1.002003', "Deal with badly serialized versions from YAML";  
700         my $badv2 = bless { qv => 1, version => [1,2,3] }, "version";
701         is $badv2, 'v1.2.3', "Deal with badly serialized versions from YAML ";  
702     }
703 SKIP: {
704         if ( $] < 5.006_000 ) {
705             skip 'No v-string support at all < 5.6.0', 2; 
706         }
707         # https://rt.cpan.org/Ticket/Display.html?id=49348
708         my $v = $CLASS->$method("420");
709         is "$v", "420", 'Correctly guesses this is not a v-string';
710         $v = $CLASS->$method(4.2.0);
711         is "$v", 'v4.2.0', 'Correctly guess that this is a v-string';
712     }
713 SKIP: {
714         if ( $] < 5.006_000 ) {
715             skip 'No v-string support at all < 5.6.0', 4; 
716         }
717         # https://rt.cpan.org/Ticket/Display.html?id=50347
718         # Check that the qv() implementation does not change
719
720         ok $CLASS->$method(1.2.3) < $CLASS->$method(1.2.3.1), 'Compare 3 and 4 digit v-strings' ;
721         ok $CLASS->$method(v1.2.3) < $CLASS->$method(v1.2.3.1), 'Compare 3 and 4 digit v-strings, leaving v';
722         ok $CLASS->$method("1.2.3") < $CLASS->$method("1.2.3.1"), 'Compare 3 and 4 digit v-strings, quoted';
723         ok $CLASS->$method("v1.2.3") < $CLASS->$method("v1.2.3.1"), 'Compare 3 and 4 digit v-strings, quoted leading v';
724     }
725 }
726
727 1;
728
729 __DATA__
730 af_ZA
731 af_ZA.utf8
732 an_ES
733 an_ES.utf8
734 az_AZ.utf8
735 be_BY
736 be_BY.utf8
737 bg_BG
738 bg_BG.utf8
739 br_FR
740 br_FR@euro
741 br_FR.utf8
742 bs_BA
743 bs_BA.utf8
744 ca_ES
745 ca_ES@euro
746 ca_ES.utf8
747 cs_CZ
748 cs_CZ.utf8
749 da_DK
750 da_DK.utf8
751 de_AT
752 de_AT@euro
753 de_AT.utf8
754 de_BE
755 de_BE@euro
756 de_BE.utf8
757 de_DE
758 de_DE@euro
759 de_DE.utf8
760 de_LU
761 de_LU@euro
762 de_LU.utf8
763 el_GR
764 el_GR.utf8
765 en_DK
766 en_DK.utf8
767 es_AR
768 es_AR.utf8
769 es_BO
770 es_BO.utf8
771 es_CL
772 es_CL.utf8
773 es_CO
774 es_CO.utf8
775 es_EC
776 es_EC.utf8
777 es_ES
778 es_ES@euro
779 es_ES.utf8
780 es_PY
781 es_PY.utf8
782 es_UY
783 es_UY.utf8
784 es_VE
785 es_VE.utf8
786 et_EE
787 et_EE.iso885915
788 et_EE.utf8
789 eu_ES
790 eu_ES@euro
791 eu_ES.utf8
792 fi_FI
793 fi_FI@euro
794 fi_FI.utf8
795 fo_FO
796 fo_FO.utf8
797 fr_BE
798 fr_BE@euro
799 fr_BE.utf8
800 fr_CA
801 fr_CA.utf8
802 fr_CH
803 fr_CH.utf8
804 fr_FR
805 fr_FR@euro
806 fr_FR.utf8
807 fr_LU
808 fr_LU@euro
809 fr_LU.utf8
810 gl_ES
811 gl_ES@euro
812 gl_ES.utf8
813 hr_HR
814 hr_HR.utf8
815 hu_HU
816 hu_HU.utf8
817 id_ID
818 id_ID.utf8
819 is_IS
820 is_IS.utf8
821 it_CH
822 it_CH.utf8
823 it_IT
824 it_IT@euro
825 it_IT.utf8
826 ka_GE
827 ka_GE.utf8
828 kk_KZ
829 kk_KZ.utf8
830 kl_GL
831 kl_GL.utf8
832 lt_LT
833 lt_LT.utf8
834 lv_LV
835 lv_LV.utf8
836 mk_MK
837 mk_MK.utf8
838 mn_MN
839 mn_MN.utf8
840 nb_NO
841 nb_NO.utf8
842 nl_BE
843 nl_BE@euro
844 nl_BE.utf8
845 nl_NL
846 nl_NL@euro
847 nl_NL.utf8
848 nn_NO
849 nn_NO.utf8
850 no_NO
851 no_NO.utf8
852 oc_FR
853 oc_FR.utf8
854 pl_PL
855 pl_PL.utf8
856 pt_BR
857 pt_BR.utf8
858 pt_PT
859 pt_PT@euro
860 pt_PT.utf8
861 ro_RO
862 ro_RO.utf8
863 ru_RU
864 ru_RU.koi8r
865 ru_RU.utf8
866 ru_UA
867 ru_UA.utf8
868 se_NO
869 se_NO.utf8
870 sh_YU
871 sh_YU.utf8
872 sk_SK
873 sk_SK.utf8
874 sl_SI
875 sl_SI.utf8
876 sq_AL
877 sq_AL.utf8
878 sr_CS
879 sr_CS.utf8
880 sv_FI
881 sv_FI@euro
882 sv_FI.utf8
883 sv_SE
884 sv_SE.iso885915
885 sv_SE.utf8
886 tg_TJ
887 tg_TJ.utf8
888 tr_TR
889 tr_TR.utf8
890 tt_RU.utf8
891 uk_UA
892 uk_UA.utf8
893 vi_VN
894 vi_VN.tcvn
895 wa_BE
896 wa_BE@euro
897 wa_BE.utf8
898