Skip to content

Commit

Permalink
Treat strings with underscores as decimal numbers.
Browse files Browse the repository at this point in the history
Also, "Acknowledgements" is a word.
  • Loading branch information
theory committed Sep 13, 2010
1 parent e1fa27b commit ff68af4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 32 deletions.
53 changes: 29 additions & 24 deletions lib/SemVer.pm
Expand Up @@ -59,7 +59,7 @@ sub declare {

(my $v = $ival) =~ s/($OPTIONAL_EXTRA_PART*)[[:space:]]*$//;
my $extra = $1;
$v =~ s/_//g; # ignore underscores.
$v += 0 if $v =~ s/_//g; # ignore underscores.
my $self = $class->SUPER::declare($v);
$self->{extra} = $extra;
return $self;
Expand All @@ -72,26 +72,24 @@ sub parse {

(my $v = $ival) =~ s/($OPTIONAL_EXTRA_PART*)[[:space:]]*$//;
my $extra = $1;
$v += 0 if $v =~ s/_//g; # ignore underscores.
my $self = $class->SUPER::parse($v);
$self->{extra} = $extra;
return $self;
}

sub stringify {
my $self = shift;
return $self->SUPER::stringify . ($self->{extra} || '');
my $str = $self->SUPER::stringify;
# Deal with cloned version.
$str += 0 if $str =~ s/_//g; # ignore underscores.
return $str . ($self->{extra} || '');
}

sub normal {
my $self = shift;
(my $norm = $self->SUPER::normal) =~ s/^v//;
if ($norm =~ s/_//g) {
# Seems messed up. Should have three parts and no leading 0s.
$norm = do {
no warnings;
join '.', map { int $_ } ( split /[.]/ => $norm )[0..2];
};
}
$norm =~ s/_/./g;
return $norm . ($self->{extra} || '');
}

Expand Down Expand Up @@ -165,21 +163,28 @@ If you need something more flexible, use C<declare()>. And if you need
something more comparable with what L<version> expects, try C<parse()>.
Compare how these constructors deal with various version strings:
Argument | new | declare | parse
-------------+------------+-------------------------
'1.0.0' | 1.0.0 | 1.0.0 | 1.0.0
'5.5.2b1' | 5.5.2b1 | 5.5.2b1 | 5.5.2b1
'1.0' | <error> | 1.0.0 | 1.0.0
' 012.2.2' | <error> | 12.2.2 | 12.2.2
'1.1' | <error> | 1.1.0 | 1.100.0
1.1 | <error> | 1.1.0 | 1.100.0
'1.1b1' | <error> | 1.1.0b1 | 1.100.0b1
'1.2.b1' | <error> | 1.2.0b1 | 1.2.0b1
'9.0beta4' | <error> | 9.0.0beta4 | 9.0.0beta4
'9' | <error> | 9.0.0 | 9.0.0
'1b' | <error> | 1.0.0b | 1.0.0b
0 | <error> | 0.0.0 | 0.0.0
'0rc1' | <error> | 0.0.0rc1 | 0.0.0rc1
Argument | new | declare | parse
-------------+---- ----+-------------------------
'1.0.0' | 1.0.0 | 1.0.0 | 1.0.0
'5.5.2b1' | 5.5.2b1 | 5.5.2b1 | 5.5.2b1
'1.0' | <error> | 1.0.0 | 1.0.0
' 012.2.2' | <error> | 12.2.2 | 12.2.2
'1.1' | <error> | 1.1.0 | 1.100.0
1.1 | <error> | 1.1.0 | 1.100.0
'1.1b1' | <error> | 1.1.0b1 | 1.100.0b1
'1.2.b1' | <error> | 1.2.0b1 | 1.2.0b1
'9.0beta4' | <error> | 9.0.0beta4 | 9.0.0beta4
'9' | <error> | 9.0.0 | 9.0.0
'1b' | <error> | 1.0.0b | 1.0.0b
0 | <error> | 0.0.0 | 0.0.0
'0rc1' | <error> | 0.0.0rc1 | 0.0.0rc1
'1.02_30' | <error> | 1.23.0 | 1.23.0
1.02_30 | <error> | 1.23.0 | 1.23.0
Note that, unlike in L<version>, the C<declare> and C<parse> methods ignore
underscores. That is, version strings with underscores are treated as decimal
numbers. Hence, the last two examples yield exactly the same semantic
versions.
As with L<version> objects, the comparison and stringification operators are
all overloaded, so that you can compare semantic versions. You can also
Expand Down
17 changes: 9 additions & 8 deletions t/base.t
Expand Up @@ -2,7 +2,7 @@

use strict;
use warnings;
use Test::More tests => 573;
use Test::More tests => 575;
#use Test::More 'no_plan';

my $CLASS;
Expand Down Expand Up @@ -212,7 +212,7 @@ for my $spec (
['9.0beta4', '9.0.0beta4'],
[' 012.2.2', '12.2.2'],
['99999998', '99999998.0.0'],
['1.02_30', '1.230.0'],
['1.02_30', '1.23.0'],
[1.02_30, '1.23.0'],
[3.4, '3.4.0', '3.400.0'],
[3.04, '3.4.0', '3.40.0' ],
Expand All @@ -230,20 +230,21 @@ for my $spec (
? join '.', map { ord } split // => $spec->[0] : $spec->[0];
$string =~ s/^\s+//;
$string =~ s/\s+$//;
$string += 0 if $string =~ s/_//g;
my $vstring = $string =~ /^\d+[.][^.]+$/ ? "v$string" : $string;
$vstring =~ s/_//g;
is $l->stringify, $vstring, qq{... And it should stringify to "$vstring"};
is $l->normal, $spec->[1], qq{... And it should normalize to "$spec->[1]"};

# Compare the non-semantic version string to the semantic one.
cmp_ok $spec->[0], '==', $r, qq{$r == "$spec->[0]"} unless $string =~ /_/;
cmp_ok $spec->[0], '==', $r, qq{$r == "$spec->[0]"};

if ($spec->[0] && $spec->[0] !~ /^[a-z]/ && $spec->[0] !~ /[.]{2}/) {
my $exp = $spec->[2] || $spec->[1];
isa_ok $l = SemVer->parse($spec->[0]), $CLASS, "Parsed $spec->[0]";
$string = "v$string" if Scalar::Util::isvstring($spec->[0]);
$string =~ s/_//;
is $l->stringify, $string, "... And it should stringify to $string";
is $l->normal, $exp , "... And it should normalize to $exp";
is $l->normal, $exp, "... And it should normalize to $exp";

# Try with the parsed version.
$r = $CLASS->new($spec->[2]) if $spec->[2];
Expand All @@ -253,8 +254,8 @@ for my $spec (
# Try creating as a version object and cloning.
if ($spec->[0] !~ /[a-z]/i) {
isa_ok my $v = version->parse($spec->[0]), 'version', "base version $spec->[0]";
isa_ok my $sv = SemVer->new($v), 'SemVer', "SemVer from base version $spec->[0]";
is $sv->stringify, $string, qq{... And it should stringify to "$vstring"};
is $sv->normal, $l->normal, '... And it should normalize to "' . $l->normal . '"';
isa_ok my $sv = SemVer->new($v), 'SemVer', "SemVer from base version $spec->[0]";
is $sv->stringify, $string, qq{... And it should stringify to "$vstring"};
is $sv->normal, $l->normal, '... And it should normalize to "' . $l->normal . '"';
}
}
1 change: 1 addition & 0 deletions t/pod-spelling.t
Expand Up @@ -14,3 +14,4 @@ Versioning
invocant
numified
versioning
Acknowledgements

0 comments on commit ff68af4

Please sign in to comment.