/t/base.t

http://github.com/theory/semver · Perl · 262 lines · 255 code · 4 blank · 3 comment · 0 complexity · b6175fd548b7f47120dc2ff0856137e6 MD5 · raw file

  1. #!/usr/bin/env perl -w
  2. use strict;
  3. use warnings;
  4. use Test::More tests => 576;
  5. #use Test::More 'no_plan';
  6. my $CLASS;
  7. BEGIN {
  8. $CLASS = 'SemVer';
  9. use_ok $CLASS or die;
  10. }
  11. can_ok $CLASS, qw(
  12. new
  13. declare
  14. parse
  15. normal
  16. numify
  17. is_alpha
  18. is_qv
  19. vcmp
  20. );
  21. # Try the basics.
  22. isa_ok my $version = $CLASS->new('0.1.0'), $CLASS, 'An instance';
  23. isa_ok $SemVer::VERSION, $CLASS, q{SemVer's own $VERSION};
  24. for my $v (qw(
  25. 1.2.2
  26. 0.2.2
  27. 1.2.2
  28. 0.0.0
  29. 0.1.999
  30. 9999.9999999.823823
  31. 1.0.0beta1
  32. 1.0.0beta2
  33. 1.0.0
  34. 0.0.0rc1
  35. v1.2.2
  36. 999993333.0.0
  37. )) {
  38. isa_ok my $semver =$CLASS->new($v), $CLASS, "new($v)";
  39. my $str = $v =~ /^v/ ? substr $v, 1 : $v;
  40. is "$semver", $str, qq{$v should stringify to "$str"};
  41. is $semver->normal, $str, qq{$v should normalize to "$str"};
  42. ok $v =~ /0\.0\.0/ ? !$semver : !!$semver, "$v should be true";
  43. ok $semver->is_qv, "$v should be dotted-decimal";
  44. my $is_alpha = $semver->is_alpha;
  45. if ($v =~ /[.]\d+[a-z]/) {
  46. ok $is_alpha, "$v should be alpha";
  47. } else {
  48. ok !$is_alpha, "$v should not be alpha";
  49. }
  50. }
  51. local $@;
  52. eval { $CLASS->new('') };
  53. ok $@, 'Empty string should be an invalid version';
  54. for my $bv (qw(
  55. 1.2
  56. 0
  57. 0.0
  58. 1.2b
  59. 1.b
  60. 1.04.0
  61. 1.65.r2
  62. )) {
  63. local $@;
  64. eval { $CLASS->new($bv) };
  65. like $@, qr{Invalid semantic version string format: "$bv"},
  66. qq{"$bv" should be an invalid semver};
  67. }
  68. # Try a vstring.
  69. isa_ok $version = $CLASS->new(v2.3.2), $CLASS, 'vstring version';
  70. is $version->stringify, 'v2.3.2', 'vestring should stringify with "v"';
  71. is $version->normal, '2.3.2', 'vstring should normalize without "v"';
  72. # Try a shorter vstring.
  73. isa_ok $version = $CLASS->new(v2.3), $CLASS, 'vstring version';
  74. is $version->stringify, 'v2.3', 'short vestring should stringify with "v"';
  75. is $version->normal, '2.3.0', 'short vstring should normalize without required 0';
  76. # Try another SemVer.
  77. isa_ok my $cloned = $CLASS->new($version), $CLASS, 'Cloned SemVer';
  78. is $cloned->stringify, $version->stringify, 'Cloned stringify like original';
  79. is $cloned->normal, $version->normal, 'Cloned should normalize like original';
  80. # Try a SemVer with alpha.
  81. isa_ok $version = $CLASS->new('2.3.2b1'), $CLASS, 'new version';
  82. isa_ok $cloned = $CLASS->new($version), $CLASS, 'Second cloned SemVer';
  83. is $cloned->stringify, $version->stringify, 'Second cloned stringify like original';
  84. is $cloned->normal, $version->normal, 'Second cloned should normalize like original';
  85. # Numify should die
  86. local $@;
  87. eval { $version->numify };
  88. like $@, qr{Semantic versions cannot be numified},
  89. 'Should get error from numify()';
  90. # Now do some comparisons. Start with equivalents.
  91. for my $spec (
  92. [ '1.2.2', '1.2.2' ],
  93. [ '1.2.23', '1.2.23' ],
  94. [ '0.0.0', '0.0.0' ],
  95. [ '999.888.7777', '999.888.7777' ],
  96. [ '0.1.2beta3', '0.1.2beta3' ],
  97. [ '1.0.0rc-1', '1.0.0RC-1' ],
  98. ) {
  99. my $l = $CLASS->new($spec->[0]);
  100. my $r = $CLASS->new($spec->[1]);
  101. is $l->vcmp($r), 0, "$l->vcmp($r) == 0";
  102. is $l <=> $r, 0, "$l <=> $r == 0";
  103. is $r <=> $l, 0, "$r <=> $l == 0";
  104. cmp_ok $l, '==', $r, "$l == $r";
  105. cmp_ok $l, '==', $r, "$l == $r";
  106. cmp_ok $l, '<=', $r, "$l <= $r";
  107. cmp_ok $l, '>=', $r, "$l >= $r";
  108. is $l cmp $r, 0, "$l cmp $r == 0";
  109. is $r cmp $l, 0, "$r cmp $l == 0";
  110. cmp_ok $l, 'eq', $r, "$l eq $r";
  111. cmp_ok $l, 'eq', $r, "$l eq $r";
  112. cmp_ok $l, 'le', $r, "$l le $r";
  113. cmp_ok $l, 'ge', $r, "$l ge $r";
  114. }
  115. # Test not equal.
  116. for my $spec (
  117. ['1.2.2', '1.2.3'],
  118. ['0.0.1', '1.0.0'],
  119. ['1.0.1', '1.1.0'],
  120. ['1.1.1', '1.1.0'],
  121. ['1.2.3b', '1.2.3'],
  122. ['1.2.3', '1.2.3b'],
  123. ['1.2.3a', '1.2.3b'],
  124. ['1.2.3aaaaaaa1', '1.2.3aaaaaaa2'],
  125. ) {
  126. my $l = $CLASS->new($spec->[0]);
  127. my $r = $CLASS->new($spec->[1]);
  128. cmp_ok $l->vcmp($r), '!=', 0, "$l->vcmp($r) != 0";
  129. cmp_ok $l, '!=', $r, "$l != $r";
  130. cmp_ok $l, 'ne', $r, "$l ne $r";
  131. }
  132. # Test >, >=, <, and <=.
  133. for my $spec (
  134. ['2.2.2', '1.1.1'],
  135. ['2.2.2', '2.1.1'],
  136. ['2.2.2', '2.2.1'],
  137. ['2.2.2b', '2.2.1'],
  138. ['2.2.2', '2.2.2b'],
  139. ['2.2.2c', '2.2.2b'],
  140. ['2.2.2rc-2', '2.2.2RC-1'],
  141. ['0.9.10', '0.9.9'],
  142. ) {
  143. my $l = $CLASS->new($spec->[0]);
  144. my $r = $CLASS->new($spec->[1]);
  145. cmp_ok $l->vcmp($r), '>', 0, "$l->vcmp($r) > 0";
  146. cmp_ok $r->vcmp($l), '<', 0, "$r->vcmp($l) < 0";
  147. cmp_ok $l, '>', $r, "$l > $r";
  148. cmp_ok $l, '>=', $r, "$l >= $r";
  149. cmp_ok $r, '<', $l, "$r < $l";
  150. cmp_ok $r, '<=', $l, "$r <= $l";
  151. cmp_ok $l, 'gt', $r, "$l gt $r";
  152. cmp_ok $l, 'ge', $r, "$l ge $r";
  153. cmp_ok $r, 'lt', $l, "$r lt $l";
  154. cmp_ok $r, 'le', $l, "$r le $l";
  155. }
  156. # Compare to version objects.
  157. my $semver = $CLASS->new('1.2.0');
  158. for my $v (qw(
  159. 1.002
  160. 1.2.0
  161. v1.002
  162. v1.2.0
  163. )) {
  164. my $version = version->new($v);
  165. ok $semver == $version, "$semver == $version";
  166. }
  167. # Compare to strings.
  168. for my $v (qw(
  169. 1.2.0
  170. v1.2.0
  171. )) {
  172. my $semver = $CLASS->new($v);
  173. cmp_ok $semver, '==', $v, qq{$semver == "$v"};
  174. cmp_ok $v, '==', $semver, qq{"$v" == $semver};
  175. cmp_ok $semver, 'eq', $v, qq{$semver eq "$v"};
  176. cmp_ok $v, 'eq', $semver, qq{"$v" eq $semver};
  177. }
  178. # Test declare() and parse.
  179. for my $spec (
  180. ['1.2.2', '1.2.2'],
  181. ['01.2.2', '1.2.2'],
  182. ['1.02.2', '1.2.2'],
  183. ['1.2.02', '1.2.2'],
  184. ['1.2.02b', '1.2.2b'],
  185. ['1.2.02beta-3 ', '1.2.2beta-3'],
  186. ['1.02.02rc1', '1.2.2rc1'],
  187. ['1.0', '1.0.0'],
  188. ['1.1', '1.1.0', '1.100.0'],
  189. [ 1.1, '1.1.0', '1.100.0'],
  190. ['1.1b1', '1.1.0b1', '1.100.0b1'],
  191. ['1.2.b1', '1.2.0b1'],
  192. ['1b', '1.0.0b'],
  193. ['9.0beta4', '9.0.0beta4'],
  194. [' 012.2.2', '12.2.2'],
  195. ['99999998', '99999998.0.0'],
  196. ['1.02_30', '1.23.0'],
  197. [1.02_30, '1.23.0'],
  198. [3.4, '3.4.0', '3.400.0'],
  199. [3.04, '3.4.0', '3.40.0' ],
  200. ['3.04', '3.4.0', '3.40.0' ],
  201. [v3.4, '3.4.0' ],
  202. [9, '9.0.0' ],
  203. ['9', '9.0.0' ],
  204. ['0', '0.0.0' ],
  205. [0, '0.0.0' ],
  206. ['0rc1', '0.0.0rc1' ],
  207. ) {
  208. my $r = $CLASS->new($spec->[1]);
  209. isa_ok my $l = SemVer->declare($spec->[0]), $CLASS, "Declared $spec->[0]";
  210. my $string = Scalar::Util::isvstring($spec->[0])
  211. ? join '.', map { ord } split // => $spec->[0] : $spec->[0];
  212. $string =~ s/^\s+//;
  213. $string =~ s/\s+$//;
  214. $string += 0 if $string =~ s/_//g;
  215. my $vstring = $string =~ /^\d+[.][^.]+$/ ? "v$string" : $string;
  216. is $l->stringify, $vstring, qq{... And it should stringify to "$vstring"};
  217. is $l->normal, $spec->[1], qq{... And it should normalize to "$spec->[1]"};
  218. # Compare the non-semantic version string to the semantic one.
  219. cmp_ok $spec->[0], '==', $r, qq{$r == "$spec->[0]"};
  220. if ($spec->[0] && $spec->[0] !~ /^[a-z]/ && $spec->[0] !~ /[.]{2}/) {
  221. my $exp = $spec->[2] || $spec->[1];
  222. isa_ok $l = SemVer->parse($spec->[0]), $CLASS, "Parsed $spec->[0]";
  223. $string = "v$string" if Scalar::Util::isvstring($spec->[0]);
  224. $string =~ s/_//;
  225. is $l->stringify, $string, "... And it should stringify to $string";
  226. is $l->normal, $exp, "... And it should normalize to $exp";
  227. # Try with the parsed version.
  228. $r = $CLASS->new($spec->[2]) if $spec->[2];
  229. cmp_ok $l, '==', $r, qq{$l == $r} unless $string =~ /_/;
  230. }
  231. # Try creating as a version object and cloning.
  232. if ($spec->[0] !~ /[a-z]/i) {
  233. isa_ok my $v = version->parse($spec->[0]), 'version', "base version $spec->[0]";
  234. isa_ok my $sv = SemVer->new($v), 'SemVer', "SemVer from base version $spec->[0]";
  235. is $sv->stringify, $string, qq{... And it should stringify to "$vstring"};
  236. is $sv->normal, $l->normal, '... And it should normalize to "' . $l->normal . '"';
  237. }
  238. }