compare.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. const assert = require('assert');
  2. const compare = require('..');
  3. const cmp = {
  4. '1': '>',
  5. '0': '=',
  6. '-1': '<',
  7. };
  8. const runTests = (dataSet) => {
  9. dataSet.forEach(([v1, v2, expected]) => {
  10. it(`${v1} ${cmp[expected]} ${v2}`, () => assert.equal(compare(v1, v2), expected));
  11. });
  12. };
  13. describe('compare versions', () => {
  14. describe('single-segment versions', () => {
  15. runTests([
  16. ['10', '9', 1],
  17. ['10', '10', 0],
  18. ['9', '10', -1],
  19. ]);
  20. });
  21. describe('two-segment versions', () => {
  22. runTests([
  23. ['10.8', '10.4', 1],
  24. ['10.1', '10.1', 0],
  25. ['10.1', '10.2', -1],
  26. ]);
  27. });
  28. describe('three-segment versions', () => {
  29. runTests([
  30. ['10.1.8', '10.0.4', 1],
  31. ['10.0.1', '10.0.1', 0],
  32. ['10.1.1', '10.2.2', -1],
  33. ]);
  34. });
  35. describe('four-segment versions - https://www.chromium.org/developers/version-numbers', () => {
  36. runTests([
  37. ['1.0.0.0', '1', 0],
  38. ['1.0.0.0', '1.0', 0],
  39. ['1.0.0.0', '1.0.0', 0],
  40. ['1.0.0.0', '1.0.0.0', 0],
  41. ['1.2.3.4', '1.2.3.4', 0],
  42. ['1.2.3.4', '1.2.3.04', 0],
  43. ['v1.2.3.4', '01.2.3.4', 0],
  44. ['1.2.3.4', '1.2.3.5', -1],
  45. ['1.2.3.5', '1.2.3.4', 1],
  46. ['1.0.0.0-alpha', '1.0.0-alpha', 0],
  47. ['1.0.0.0-alpha', '1.0.0.0-beta', -1],
  48. ]);
  49. });
  50. it('should compare versions with different number of digits in same group', () => {
  51. assert.equal(compare('11.0.10', '11.0.2'), 1);
  52. assert.equal(compare('11.0.2', '11.0.10'), -1);
  53. });
  54. it('should compare versions with different number of digits in different groups', () => {
  55. assert.equal(compare('11.1.10', '11.0'), 1);
  56. });
  57. it('should compare versions with different number of digits', () => {
  58. assert.equal(compare('1.1.1', '1'), 1);
  59. assert.equal(compare('1.0.0', '1'), 0);
  60. assert.equal(compare('1.0', '1.4.1'), -1);
  61. });
  62. describe('pre-release versions - https://semver.org/#spec-item-9', () => {
  63. runTests([
  64. ['1.0.0-alpha.1', '1.0.0-alpha', 1],
  65. ['1.0.0-alpha', '1.0.0-alpha.1', -1],
  66. ['1.0.0-alpha.1', '1.0.0-alpha.beta', -1],
  67. ['1.0.0-alpha.beta', '1.0.0-beta', -1],
  68. ['1.0.0-beta', '1.0.0-beta.2', -1],
  69. ['1.0.0-beta.2', '1.0.0-beta.11', -1],
  70. ['1.0.0-beta.11', '1.0.0-rc.1', -1],
  71. ['1.0.0-rc.1', '1.0.0', -1],
  72. ['1.0.0-alpha', '1', -1],
  73. ]);
  74. });
  75. describe('ignore build metadata - https://semver.org/#spec-item-10', () => {
  76. runTests([
  77. ['1.4.0-build.3928', '1.4.0-build.3928+sha.a8d9d4f', 0],
  78. ['1.4.0-build.3928+sha.b8dbdb0', '1.4.0-build.3928+sha.a8d9d4f', 0],
  79. ['1.0.0-alpha+001', '1.0.0-alpha', 0],
  80. ['1.0.0-beta+exp.sha.5114f85', '1.0.0-beta+exp.sha.999999', 0],
  81. ['1.0.0+20130313144700', '1.0.0', 0],
  82. ['1.0.0+20130313144700', '2.0.0', -1],
  83. ['1.0.0+20130313144700', '1.0.1+11234343435', -1],
  84. ['1.0.1+1', '1.0.1+2', 0],
  85. ['1.0.0+a-a', '1.0.0+a-b', 0],
  86. ]);
  87. });
  88. describe('ignore leading `v`', () => {
  89. runTests([
  90. ['v1.0.0', '1.0.0', 0],
  91. ['v1.0.0', 'v1.0.0', 0],
  92. ['v1.0.0', 'v1.0.0', 0],
  93. ['v1.0.0-alpha', '1.0.0-alpha', 0],
  94. ]);
  95. });
  96. describe('ignore leading `0`', () => {
  97. runTests([
  98. ['01.0.0', '1', 0],
  99. ['01.0.0', '1.0.0', 0],
  100. ['1.01.0', '1.01.0', 0],
  101. ['1.0.03', '1.0.3', 0],
  102. ['1.0.03-alpha', '1.0.3-alpha', 0],
  103. ['v01.0.0', '1.0.0', 0],
  104. ['v01.0.0', '2.0.0', -1],
  105. ]);
  106. });
  107. describe('invalid input', () => {
  108. [
  109. [42, /Invalid argument expected string/],
  110. [{}, /Invalid argument expected string/],
  111. [[], /Invalid argument expected string/],
  112. [() => undefined, /Invalid argument expected string/],
  113. ['6.3.', /Invalid argument not valid semver/],
  114. ['1.2.3a', /Invalid argument not valid semver/],
  115. ['1.2.-3a', /Invalid argument not valid semver/],
  116. ].forEach(([v1, exception]) => {
  117. it(`should throw on ${v1}`, () => {
  118. assert.throws(() => { compare(v1, v1); }, exception);
  119. });
  120. });
  121. });
  122. runTests([
  123. ['0.1.20', '0.1.5', 1],
  124. ['0.6.1-1', '0.6.1-0', 1],
  125. ['0.7.x', '0.6.0', 1],
  126. ['0.7.x', '0.6.0-asdf', 1],
  127. ['0.7.x', '0.6.2', 1],
  128. ['0.7.x', '0.7.0-asdf', 1],
  129. ['1', '0.0.0-beta', 1],
  130. ['1', '0.2.3', 1],
  131. ['1', '0.2.4', 1],
  132. ['1', '1.0.0-0', 1],
  133. ['1', '1.0.0-beta', 1],
  134. ['1.0', '0.0.0', 1],
  135. ['1.0', '0.1.0', 1],
  136. ['1.0', '0.1.2', 1],
  137. ['1.0.0', '0.0.0', 1],
  138. ['1.0.0', '0.0.1', 1],
  139. ['1.0.0', '0.2.3', 1],
  140. ['1.0.0-beta.2', '1.0.0-beta.1', 1],
  141. ['1.2.*', '1.1.3', 1],
  142. ['1.2.*', '1.1.9999', 1],
  143. ['1.2.2', '1.2.1', 1],
  144. ['1.2.x', '1.0.0', 1],
  145. ['1.2.x', '1.1.0', 1],
  146. ['1.2.x', '1.1.3', 1],
  147. ['2', '1.0.0', 1],
  148. ['2', '1.0.0-beta', 1],
  149. ['2', '1.9999.9999', 1],
  150. ['2.*.*', '1.0.1', 1],
  151. ['2.*.*', '1.1.3', 1],
  152. ['2.0.0', '1.0.0', 1],
  153. ['2.0.0', '1.1.1', 1],
  154. ['2.0.0', '1.2.9', 1],
  155. ['2.0.0', '1.9999.9999', 1],
  156. ['2.3', '2.2.1', 1],
  157. ['2.3', '2.2.2', 1],
  158. ['2.4', '2.3.0', 1],
  159. ['2.4', '2.3.5', 1],
  160. ['2.x.x', '1.0.0', 1],
  161. ['2.x.x', '1.1.3', 1],
  162. ['3.2.1', '2.3.2', 1],
  163. ['3.2.1', '3.2.0', 1],
  164. ['v0.5.4-pre', '0.5.4-alpha', 1],
  165. ['v3.2.1', 'v2.3.2', 1],
  166. ]);
  167. });