Comparing version 1.0.3 to 1.0.4
{ "name" : "semver" | ||
, "version" : "1.0.3" | ||
, "version" : "1.0.4" | ||
, "description" : "The semantic version parser used by npm." | ||
, "main" : "semver.js" | ||
, "scripts" : { "test" : "node semver.js" } | ||
, "devDependencies": { "tap" : "0.x" } | ||
, "repository" : "git://github.com/isaacs/node-semver.git" | ||
, "bin" : { "semver" : "./bin/semver" } } |
@@ -87,1 +87,33 @@ # semver | ||
`||` (which implies "or"). | ||
## Functions | ||
* valid(v): Return the parsed version, or null if it's not valid. | ||
### Comparison | ||
* gt(v1, v2): `v1 > v2` | ||
* gte(v1, v2): `v1 >= v2` | ||
* lt(v1, v2): `v1 < v2` | ||
* lte(v1, v2): `v1 <= v2` | ||
* eq(v1, v2): `v1 == v2` This is true if they're logically equivalent, | ||
even if they're not the exact same string. You already know how to | ||
compare strings. | ||
* neq(v1, v2): `v1 != v2` The opposite of eq. | ||
* cmp(v1, comparator, v2): Pass in a comparison string, and it'll call | ||
the corresponding function above. `"==="` and `"!=="` do simple | ||
string comparison, but are included for completeness. Throws if an | ||
invalid comparison string is provided. | ||
* compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if | ||
v2 is greater. Sorts in ascending order if passed to Array.sort(). | ||
* rcompare(v1, v2): The reverse of compare. Sorts an array of versions | ||
in descending order when passed to Array.sort(). | ||
### Ranges | ||
* validRange(range): Return the valid range or null if it's not valid | ||
* satisfies(version, range): Return true if the version satisfies the | ||
range. | ||
* maxSatisfying(versions, range): Return the highest version in the list | ||
that satisfies the range, or null if none of them do. |
132
semver.js
@@ -6,3 +6,3 @@ | ||
var semver = "[v=]*([0-9]+)" // major | ||
var semver = "\\s*[v=]*\\s*([0-9]+)" // major | ||
+ "\\.([0-9]+)" // minor | ||
@@ -34,3 +34,9 @@ + "\\.([0-9]+)" // patch | ||
exports.gt = gt | ||
exports.gte = gte | ||
exports.lt = lt | ||
exports.lte = lte | ||
exports.eq = eq | ||
exports.neq = neq | ||
exports.cmp = cmp | ||
exports.valid = valid | ||
@@ -46,5 +52,7 @@ exports.validPackage = validPackage | ||
} | ||
function valid (version) { | ||
return exports.parse(version) && version.trim().replace(/^[v=]+/, '') | ||
} | ||
function validPackage (version) { | ||
@@ -103,2 +111,3 @@ return version.match(expressions.parsePackage) && version.trim() | ||
} | ||
function replaceXRange (version) { | ||
@@ -198,6 +207,28 @@ return version.trim().replace(expressions.parseXRange, | ||
function compare (v1, v2) { | ||
return v1 === v2 ? 0 : gt(v1, v2) ? 1 : -1 | ||
var g = gt(v1, v2) | ||
return g === null ? 0 : g ? 1 : -1 | ||
} | ||
function rcompare (v1, v2) { | ||
return compare(v2, v1) | ||
} | ||
function lt (v1, v2) { return gt(v2, v1) } | ||
function gte (v1, v2) { return !lt(v1, v2) } | ||
function lte (v1, v2) { return !gt(v1, v2) } | ||
function eq (v1, v2) { return gt(v1, v2) === null } | ||
function neq (v1, v2) { return gt(v1, v2) !== null } | ||
function cmp (v1, c, v2) { | ||
switch (c) { | ||
case ">": return gt(v1, v2) | ||
case "<": return lt(v1, v2) | ||
case ">=": return gte(v1, v2) | ||
case "<=": return lte(v1, v2) | ||
case "==": return eq(v1, v2) | ||
case "!=": return neq(v1, v2) | ||
case "===": return v1 === v2 | ||
case "!==": return v1 !== v2 | ||
default: throw new Error("Y U NO USE VALID COMPARATOR!? "+c) | ||
} | ||
} | ||
@@ -222,8 +253,19 @@ // return v1 > v2 | ||
, tag2 = v2[5] || "" | ||
return !!tag2 && (!tag1 || tag1 > tag2) | ||
// kludge: null means they were equal. falsey, and detectable. | ||
// embarrassingly overclever, though, I know. | ||
return tag1 === tag2 ? null | ||
: !tag1 ? true | ||
: !tag2 ? false | ||
: tag1 > tag2 | ||
} | ||
if (module === require.main) { // tests below | ||
var assert = require("assert") | ||
var tap = require("tap") | ||
, test = tap.test | ||
tap.plan(4) | ||
test("comparison tests", function (t) { | ||
; [ ["0.0.0", "0.0.0foo"] | ||
@@ -252,10 +294,73 @@ , ["0.0.1", "0.0.0"] | ||
, ["1.2.3-5", "1.2.3-4"] | ||
, ["1.2.3-5-foo", "1.2.3-5-Foo"] | ||
].forEach(function (v) { | ||
assert.ok(gt(v[0], v[1]), "gt('"+v[0]+"', '"+v[1]+"')") | ||
assert.ok(lt(v[1], v[0]), "lt('"+v[1]+"', '"+v[0]+"')") | ||
assert.ok(!gt(v[1], v[0]), "!gt('"+v[1]+"', '"+v[0]+"')") | ||
assert.ok(!lt(v[0], v[1]), "!lt('"+v[0]+"', '"+v[1]+"')") | ||
var v0 = v[0] | ||
, v1 = v[1] | ||
t.ok(gt(v0, v1), "gt('"+v0+"', '"+v1+"')") | ||
t.ok(lt(v1, v0), "lt('"+v1+"', '"+v0+"')") | ||
t.ok(!gt(v1, v0), "!gt('"+v1+"', '"+v0+"')") | ||
t.ok(!lt(v0, v1), "!lt('"+v0+"', '"+v1+"')") | ||
t.ok(eq(v0, v0), "eq('"+v0+"', '"+v0+"')") | ||
t.ok(eq(v1, v1), "eq('"+v1+"', '"+v1+"')") | ||
t.ok(neq(v0, v1), "neq('"+v0+"', '"+v1+"')") | ||
t.ok(cmp(v1, "==", v1), "cmp("+v1+"=="+v1+")") | ||
t.ok(cmp(v0, ">=", v1), "cmp("+v0+"<="+v1+")") | ||
t.ok(cmp(v1, "<=", v0), "cmp("+v1+">="+v0+")") | ||
t.ok(cmp(v0, "!=", v1), "cmp("+v0+"!="+v1+")") | ||
}) | ||
t.end() | ||
}) | ||
test("equality tests", function (t) { | ||
; [ ["1.2.3", "v1.2.3"] | ||
, ["1.2.3", "=1.2.3"] | ||
, ["1.2.3", "v 1.2.3"] | ||
, ["1.2.3", "= 1.2.3"] | ||
, ["1.2.3", " v1.2.3"] | ||
, ["1.2.3", " =1.2.3"] | ||
, ["1.2.3", " v 1.2.3"] | ||
, ["1.2.3", " = 1.2.3"] | ||
, ["1.2.3-0", "v1.2.3-0"] | ||
, ["1.2.3-0", "=1.2.3-0"] | ||
, ["1.2.3-0", "v 1.2.3-0"] | ||
, ["1.2.3-0", "= 1.2.3-0"] | ||
, ["1.2.3-0", " v1.2.3-0"] | ||
, ["1.2.3-0", " =1.2.3-0"] | ||
, ["1.2.3-0", " v 1.2.3-0"] | ||
, ["1.2.3-0", " = 1.2.3-0"] | ||
, ["1.2.3-01", "v1.2.3-1"] | ||
, ["1.2.3-01", "=1.2.3-1"] | ||
, ["1.2.3-01", "v 1.2.3-1"] | ||
, ["1.2.3-01", "= 1.2.3-1"] | ||
, ["1.2.3-01", " v1.2.3-1"] | ||
, ["1.2.3-01", " =1.2.3-1"] | ||
, ["1.2.3-01", " v 1.2.3-1"] | ||
, ["1.2.3-01", " = 1.2.3-1"] | ||
, ["1.2.3beta", "v1.2.3beta"] | ||
, ["1.2.3beta", "=1.2.3beta"] | ||
, ["1.2.3beta", "v 1.2.3beta"] | ||
, ["1.2.3beta", "= 1.2.3beta"] | ||
, ["1.2.3beta", " v1.2.3beta"] | ||
, ["1.2.3beta", " =1.2.3beta"] | ||
, ["1.2.3beta", " v 1.2.3beta"] | ||
, ["1.2.3beta", " = 1.2.3beta"] | ||
].forEach(function (v) { | ||
var v0 = v[0] | ||
, v1 = v[1] | ||
t.ok(eq(v0, v1), "eq('"+v0+"', '"+v1+"')") | ||
t.ok(!neq(v0, v1), "!neq('"+v0+"', '"+v1+"')") | ||
t.ok(cmp(v0, "==", v1), "cmp("+v0+"=="+v1+")") | ||
t.ok(!cmp(v0, "!=", v1), "!cmp("+v0+"!="+v1+")") | ||
t.ok(!cmp(v0, "===", v1), "!cmp("+v0+"==="+v1+")") | ||
t.ok(cmp(v0, "!==", v1), "cmp("+v0+"!=="+v1+")") | ||
t.ok(!gt(v0, v1), "!gt('"+v0+"', '"+v1+"')") | ||
t.ok(gte(v0, v1), "gte('"+v0+"', '"+v1+"')") | ||
t.ok(!lt(v0, v1), "!lt('"+v0+"', '"+v1+"')") | ||
t.ok(lte(v0, v1), "lte('"+v0+"', '"+v1+"')") | ||
}) | ||
t.end() | ||
}) | ||
test("range tests", function (t) { | ||
; [ ["1.0.0 - 2.0.0", "1.2.3"] | ||
@@ -317,7 +422,8 @@ , ["1.0.0", "1.0.0"] | ||
].forEach(function (v) { | ||
assert.ok(satisfies(v[1], v[0]), v[0]+" satisfied by "+v[1]) | ||
t.ok(satisfies(v[1], v[0]), v[0]+" satisfied by "+v[1]) | ||
}) | ||
t.end() | ||
}) | ||
// negative tests | ||
test("negative range tests", function (t) { | ||
; [ ["1.0.0 - 2.0.0", "2.2.3"] | ||
@@ -357,5 +463,7 @@ , ["1.0.0", "1.0.1"] | ||
].forEach(function (v) { | ||
assert.ok(!satisfies(v[1], v[0]), v[0]+" not satisfied by "+v[1]) | ||
t.ok(!satisfies(v[1], v[0]), v[0]+" not satisfied by "+v[1]) | ||
}) | ||
t.end() | ||
}) | ||
} |
19492
429
119
1