550 lines
10 KiB
JavaScript
550 lines
10 KiB
JavaScript
"use strict";
|
|
|
|
const {
|
|
parseVersion,
|
|
parseVersionRuntimeCode,
|
|
versionLt,
|
|
versionLtRuntimeCode,
|
|
parseRange,
|
|
rangeToString,
|
|
rangeToStringRuntimeCode,
|
|
satisfy,
|
|
satisfyRuntimeCode
|
|
} = require("../lib/util/semver");
|
|
|
|
describe("SemVer", () => {
|
|
const createRuntimeFunction = runtimeCodeFunction => {
|
|
const runtimeFunction = runtimeCodeFunction({
|
|
basicFunction: (args, body) => `(${args}) => {\n${body.join("\n")}\n}`,
|
|
supportsArrowFunction: () => true
|
|
});
|
|
const functionName = runtimeFunction.match(/^var (\w+)/)[1];
|
|
return eval(
|
|
`(function (...args) { ${runtimeFunction}; return ${functionName}(...args); })`
|
|
);
|
|
};
|
|
|
|
for (const [name, fn] of [
|
|
["normal", parseVersion],
|
|
["runtime", createRuntimeFunction(parseVersionRuntimeCode)]
|
|
]) {
|
|
it(`should parseVersion correctly (${name})`, () => {
|
|
expect(fn("1")).toEqual([1]);
|
|
expect(fn("1.2.3")).toEqual([1, 2, 3]);
|
|
expect(fn("1.2.3.4.999")).toEqual([1, 2, 3, 4, 999]);
|
|
// eslint-disable-next-line no-sparse-arrays
|
|
expect(fn("1.2.3-beta")).toEqual([1, 2, 3, , "beta"]);
|
|
// eslint-disable-next-line no-sparse-arrays
|
|
expect(fn("1.2.3-beta.1.2")).toEqual([1, 2, 3, , "beta", 1, 2]);
|
|
// eslint-disable-next-line no-sparse-arrays
|
|
expect(fn("1.2.3-alpha.beta-42")).toEqual([
|
|
1,
|
|
2,
|
|
3,
|
|
,
|
|
"alpha",
|
|
"beta-42"
|
|
]);
|
|
// eslint-disable-next-line no-sparse-arrays
|
|
expect(fn("1.2.3-beta.1.alpha.0+5343")).toEqual([
|
|
1,
|
|
2,
|
|
3,
|
|
,
|
|
"beta",
|
|
1,
|
|
"alpha",
|
|
0,
|
|
[],
|
|
5343
|
|
]);
|
|
expect(fn("1.2.3+5343.beta+1")).toEqual([1, 2, 3, [], 5343, "beta+1"]);
|
|
expect(fn("1.2.3+5343.beta+1")).toEqual([1, 2, 3, [], 5343, "beta+1"]);
|
|
});
|
|
}
|
|
|
|
describe("versionLt", () => {
|
|
const cases = [
|
|
"1 < 2",
|
|
"99 < 100",
|
|
"1 < 1.2",
|
|
"1 < 1.2.3",
|
|
"1.2 < 1.2.3",
|
|
"1.2.2 < 1.2.3",
|
|
"1.1.3 < 1.2.0",
|
|
"1.1.3 < 2.0.0",
|
|
"1.1.3 < 2",
|
|
"1.1.3 < 2.0",
|
|
"1.2.3 < 1.2.3+0",
|
|
"1.2.3+23 < 1.2.3+123",
|
|
"1.2+2 < 1.2.3+1",
|
|
"1.2.3-beta < 1.2.3",
|
|
"1.2.3 < 1.2.4-beta",
|
|
"1.2.3 < 1.3.0-beta",
|
|
"1.2.3 < 2.0.0-beta",
|
|
"1.2.3-alpha < 1.2.3-beta",
|
|
"1.2.3-beta < 1.2.3.1",
|
|
"1.2.3-beta < 1.2.3-beta.0",
|
|
"1.2.3-beta.0 < 1.2.3-beta.1",
|
|
"1.2.3-0 < 1.2.3-beta",
|
|
"1.2.3-beta < 1.2.3-beta+123",
|
|
"1.2.3-beta+123 < 1.2.3-beta+234",
|
|
"1.2.3-beta+99 < 1.2.3-beta+111",
|
|
"1.2.3-beta < 1.2.3+1",
|
|
"1.0.0-alpha < 1.0.0-alpha.1",
|
|
"1.0.0-alpha.1 < 1.0.0-alpha.beta",
|
|
"1.0.0-alpha.beta < 1.0.0-beta",
|
|
"1.0.0-beta < 1.0.0-beta.2",
|
|
"1.0.0-beta.2 < 1.0.0-beta.11",
|
|
"1.0.0-beta.11 < 1.0.0-rc.1",
|
|
"1.0.0-rc.1 < 1.0.0",
|
|
"2.2 < 2.beta",
|
|
"2.2 < 2.beta.1",
|
|
"2.2.1 < 2.beta.1",
|
|
"2.2.1 < 2.beta",
|
|
"2.2.3 < 2.beta.1",
|
|
"2.alpha < 2.beta",
|
|
"2.alpha.1 < 2.beta",
|
|
"2.alpha.1 < 2.beta.1",
|
|
"2.alpha < 2.beta.1"
|
|
];
|
|
for (const c of cases) {
|
|
const parts = c.split(" < ");
|
|
const a = parts[0];
|
|
const b = parts[1];
|
|
|
|
for (const [name, fn] of [
|
|
["normal", versionLt],
|
|
["runtime", createRuntimeFunction(versionLtRuntimeCode)]
|
|
]) {
|
|
it(`${c} (${name})`, () => {
|
|
expect(fn(a, a)).toBe(false);
|
|
expect(fn(b, b)).toBe(false);
|
|
expect(fn(a, b)).toBe(true);
|
|
expect(fn(b, a)).toBe(false);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
describe("parseRange", () => {
|
|
const cases = {
|
|
"=3": ["3", "v3", "3.x", "3.X", "3.x.x", "3.*", "3.*.*", "^3", "^3.x"],
|
|
"=3.0": ["3.0", "v3.0", "3.0.x", "3.0.X", "3.0.*", "~3.0"],
|
|
"^3.4": ["^3.4.*"],
|
|
"3.4 - 6.5": [">=3.4 <=6.5"],
|
|
"<=3.4": ["<3.4 || =3.4"],
|
|
">3.4": [">=3.4 !3.4"]
|
|
};
|
|
for (const key of Object.keys(cases)) {
|
|
describe(key, () => {
|
|
for (const c of cases[key])
|
|
it(`should be equal ${c}`, () => {
|
|
expect(parseRange(c)).toEqual(parseRange(key));
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
describe("rangeToString", () => {
|
|
const cases = {
|
|
"*": "*",
|
|
1: "^1",
|
|
1.2: "~1.2",
|
|
"1.2.3": "=1.2.3",
|
|
"^1.2.3": "^1.2.3",
|
|
"~1.2.3": "~1.2.3",
|
|
"0.0.1": "=0.0.1",
|
|
"^0.0.1": "=0.0.1",
|
|
"^0.1.2": "~0.1.2",
|
|
"~0.0.1": "~0.0.1",
|
|
"~0.1.2": "~0.1.2",
|
|
">=1.2.3": ">=1.2.3",
|
|
"1.2.3-beta.25": "=1.2.3-beta.25",
|
|
"1.2.3-beta.25+12.34": "=1.2.3-beta.25",
|
|
"1.2.3+12.34": "=1.2.3",
|
|
">=1.2.3-beta.25": ">=1.2.3-beta.25",
|
|
">=1.2.3-beta.25+12.34": ">=1.2.3-beta.25",
|
|
">=1.2.3+12.34": ">=1.2.3",
|
|
"<1.2.3-beta.25": "<1.2.3-beta.25",
|
|
"<1.2.3-beta.25+12.34": "<1.2.3-beta.25",
|
|
"<1.2.3+12.34": "<1.2.3",
|
|
"1.2.3 - 3.2.1": ">=1.2.3 (<3.2.1 || =3.2.1)",
|
|
">3.4": ">=3.4 not(~3.4)",
|
|
"1 || 2 || 3": "^1 || ^2 || ^3",
|
|
"1.2.3 - 3.2.1 || >3 <=4 || 1":
|
|
">=1.2.3 (<3.2.1 || =3.2.1) || >=3 not(^3) (<4 || ^4) || ^1"
|
|
};
|
|
|
|
for (const key of Object.keys(cases)) {
|
|
const expected = cases[key];
|
|
|
|
for (const [name, fn] of [
|
|
["normal", rangeToString],
|
|
["runtime", createRuntimeFunction(rangeToStringRuntimeCode)]
|
|
]) {
|
|
it(`should ${key} stringify to ${expected} (${name})`, () => {
|
|
expect(fn(parseRange(key))).toEqual(expected);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
describe("satisfies", () => {
|
|
const cases = {
|
|
// table cases
|
|
">=1": [
|
|
"1",
|
|
"2",
|
|
"!1-beta",
|
|
"!2-beta",
|
|
"1.2",
|
|
"!1.2-beta",
|
|
"2.2",
|
|
"!2.2-beta",
|
|
"1.beta",
|
|
"!1.beta-beta",
|
|
"!2.beta-beta"
|
|
],
|
|
">=1-beta": [
|
|
"1",
|
|
"2",
|
|
"1-beta",
|
|
"1-gamma",
|
|
"!1-alpha",
|
|
"!2-beta",
|
|
"1.2",
|
|
"!1.2-beta",
|
|
"2.2",
|
|
"!2.2-beta",
|
|
"1.beta",
|
|
"!1.beta-beta",
|
|
"2.beta",
|
|
"!2.beta-beta"
|
|
],
|
|
">=1.2": [
|
|
"!1",
|
|
"2",
|
|
"!1-beta",
|
|
"!2-beta",
|
|
"!1.1",
|
|
"1.2",
|
|
"1.3",
|
|
"2.1",
|
|
"2.2",
|
|
"2.3",
|
|
"1.beta",
|
|
"2.beta"
|
|
],
|
|
"~1.2": [
|
|
"!1",
|
|
"!2",
|
|
"!10",
|
|
"!1-beta",
|
|
"!2-beta",
|
|
"!1.1",
|
|
"1.2",
|
|
"!1.3",
|
|
"!1.20"
|
|
],
|
|
">=1.beta": [
|
|
"!1",
|
|
"2",
|
|
"!1-beta",
|
|
"!2-beta",
|
|
"!1.2",
|
|
"2.2",
|
|
"!1.0",
|
|
"!1.100",
|
|
"!1.alpha",
|
|
"1.beta",
|
|
"1.gamma",
|
|
"2.beta"
|
|
],
|
|
// fixed cases
|
|
2: [
|
|
"2",
|
|
"2.0.0",
|
|
"2.99.99",
|
|
"!2.3.4-beta",
|
|
"!2.3.4-beta.1",
|
|
"!2.3.4-beta+123",
|
|
"2.3.4+123",
|
|
"!1",
|
|
"!1.2.3",
|
|
"!3",
|
|
"!3.4.5"
|
|
],
|
|
"1.2.3-beta.1.2+33.44": [
|
|
"1.2.3-beta.1.2+33.44",
|
|
"1.2.3-beta.1.2+22",
|
|
"1.2.3-beta.1.2+0",
|
|
"1.2.3-beta.1.2",
|
|
"1.2.3-beta.1.2+33.44.55",
|
|
"!1.2.3-beta.1.2.3+33.44",
|
|
"!1.2.3.4-beta.1.2+33.44",
|
|
"1.2.3-beta.1.2+33",
|
|
"1.2.3-beta.1.2",
|
|
"!1.2.3-beta",
|
|
"!1.2-beta.1.2+33.44",
|
|
"!1.2.3+33.44",
|
|
"!1.2.3",
|
|
"!1"
|
|
],
|
|
"1.2.3+33.44": [
|
|
"1.2.3+33.44",
|
|
"!1.2.4+33.44",
|
|
"1.2.3+22",
|
|
"1.2.3+33.55",
|
|
"!1.2.3-beta+33.44",
|
|
"1.2.3+33.44.55",
|
|
"1.2.3+33",
|
|
"!1.2+33.44",
|
|
"!1.2.3.4+33.44",
|
|
"1.2.3",
|
|
"!1.2.4",
|
|
"!1.3",
|
|
"!1",
|
|
"!2"
|
|
],
|
|
"1.2.3-beta.1.2": [
|
|
"1.2.3-beta.1.2",
|
|
"1.2.3-beta.1.2+33",
|
|
"!1.2.3-beta.1.2.3",
|
|
"!1.2.3.4-beta.1.2",
|
|
"!1.2.3-beta",
|
|
"!1.2-beta.1.2",
|
|
"!1.2.3+33",
|
|
"!1.2.3",
|
|
"!1"
|
|
],
|
|
"^2.3.4": [
|
|
"2.3.4",
|
|
"2.3.5",
|
|
"2.4.0",
|
|
"!3.3.4",
|
|
"!1.5.6",
|
|
"!2.3.3",
|
|
"!2.3.4-beta",
|
|
"!2.3.5-beta",
|
|
"2.3.4.test",
|
|
"2.3.test",
|
|
"!2.3-test",
|
|
"2.3.4+33",
|
|
"2.3.5+33",
|
|
"2.4.0+33",
|
|
"2.3.4.5",
|
|
"2.3.beta",
|
|
"2.3.beta.1",
|
|
"2.beta"
|
|
],
|
|
"^2.beta.4": [
|
|
"2.beta.4",
|
|
"!2.3.4",
|
|
"2.beta.alpha",
|
|
"2.beta.alpha+gamma",
|
|
"!2.beta-4"
|
|
],
|
|
"~2.3.4": [
|
|
"2.3.4",
|
|
"2.3.5",
|
|
"!2.4.0",
|
|
"!3.3.4",
|
|
"!1.5.6",
|
|
"!2.3.3",
|
|
"!2.3.4-beta",
|
|
"!2.3.5-beta",
|
|
"2.3.4.test",
|
|
"2.3.test",
|
|
"!2.3-test",
|
|
"2.3.4+33",
|
|
"2.3.5+33",
|
|
"!2.4.0+33",
|
|
"2.3.4.5"
|
|
],
|
|
"~1.2.0-beta": [
|
|
"1.2.0-beta",
|
|
"1.2.0-beta+1",
|
|
"1.2.0-rc.0",
|
|
"1.2.0",
|
|
"1.2.1",
|
|
"!1.2.0-alpha",
|
|
"!1.2.0-0",
|
|
"!1.2.0-100",
|
|
"!1.2.1-beta",
|
|
"!1.3.0-beta",
|
|
"!1.3.0"
|
|
],
|
|
"!2.3": [
|
|
"!2.3",
|
|
"!2.3.4",
|
|
"2.2",
|
|
"2.2.2",
|
|
"2.4",
|
|
"2.4.4",
|
|
"2.3-beta",
|
|
"2.3.4-beta"
|
|
],
|
|
"<2.3": [
|
|
"!2.3",
|
|
"!2.3.4",
|
|
"2",
|
|
"2.2",
|
|
"2.2.1",
|
|
"1.5",
|
|
"0.1",
|
|
"!2.2-beta",
|
|
"!2.3-beta",
|
|
"!2.3-0"
|
|
],
|
|
"<4.5-beta.14": [
|
|
"4.5-beta.13",
|
|
"!4.5-beta.14",
|
|
"!4.5-beta.15",
|
|
"!4.5-beta.14.1",
|
|
"4.5-beta.13.1",
|
|
"4.5-beta.13+15",
|
|
"!4.5-beta.14+15",
|
|
"4.5-0",
|
|
"4.5-100",
|
|
"4.5-alpha",
|
|
"!4.5-gamma"
|
|
],
|
|
"2.3 - 4.5": [
|
|
"2.3",
|
|
"2.4",
|
|
"!2.3-beta",
|
|
"4.5",
|
|
"3.0.0",
|
|
"!3.5.7-beta.1",
|
|
"4.4",
|
|
"4.5",
|
|
"4.5.1",
|
|
"!4.5.2-beta",
|
|
"4.5+123"
|
|
],
|
|
">7.8-beta.4": [
|
|
"!7.8-beta.3",
|
|
"!7.8-beta.4",
|
|
"!7.8-beta.4+55",
|
|
"7.8-beta.4.1",
|
|
"7.8-beta.5",
|
|
"7.8-beta.5.1",
|
|
"7.8-gamma",
|
|
"!7.8-alpha",
|
|
"7.8",
|
|
"7.8.0",
|
|
"7.8.1",
|
|
"7.9",
|
|
"8.1",
|
|
"10"
|
|
],
|
|
"^0.0.3": [
|
|
"!0.0.2",
|
|
"0.0.3",
|
|
"!0.0.4",
|
|
"!0.1.0",
|
|
"!0.1.3",
|
|
"!1.1.3",
|
|
"!1.0.0"
|
|
],
|
|
"^0.3.3": [
|
|
"!0.0.3",
|
|
"!0.3.2",
|
|
"0.3.3",
|
|
"0.3.4",
|
|
"!0.4.0",
|
|
"!0.4.3",
|
|
"!0.5.10",
|
|
"!1.0.0",
|
|
"!1.3.3"
|
|
],
|
|
">=1.0.0+42": [
|
|
"1.0.0+42",
|
|
"!1.0+42",
|
|
"!1.0+43",
|
|
"1.0.0+43",
|
|
"1.0.0+5",
|
|
"1.0.0+100",
|
|
"2.0.0+10",
|
|
"1.0.0",
|
|
"!1.0.0-beta"
|
|
],
|
|
"<1.0.1+42": [
|
|
"!1.0.1+42",
|
|
"!1.0.1+43",
|
|
"!1.0.1+9",
|
|
"!1.0.1+5",
|
|
"!1.0.1+100",
|
|
"!2.0.0+10",
|
|
"!1.0.1",
|
|
"1.0.0",
|
|
"1.0.0+0",
|
|
"1.0.0+9999",
|
|
"0.5.0",
|
|
"!1.0.1-beta"
|
|
],
|
|
"=1.0.0+42": [
|
|
"1.0.0+42",
|
|
"!1.0+42",
|
|
"1.0.0+43",
|
|
"1.0.0+9",
|
|
"1.0.0+5",
|
|
"1.0.0+100",
|
|
"!2.0.0+10",
|
|
"1.0.0",
|
|
"!0.5.0",
|
|
"!1.0.0-beta"
|
|
],
|
|
"!1.0.1+42": [
|
|
"!1.0.1+42",
|
|
"!1.0.1+43",
|
|
"!1.0.1+9",
|
|
"!1.0.1+5",
|
|
"!1.0.1+100",
|
|
"2.0.0+10",
|
|
"!1.0.1",
|
|
"1.0.0",
|
|
"1.0.2",
|
|
"0.5.0",
|
|
"1.0.1-beta"
|
|
],
|
|
"*": [
|
|
"0.0.0",
|
|
"0.0.1",
|
|
"0.1.0",
|
|
"1.0.0",
|
|
"!1.0.0-beta",
|
|
"!1.0.0-beta.1",
|
|
"1.0.0+55"
|
|
]
|
|
};
|
|
|
|
for (const range of Object.keys(cases)) {
|
|
describe(range, () => {
|
|
it(`should be able to parse ${range}`, () => {
|
|
parseRange(range);
|
|
});
|
|
for (const item of cases[range]) {
|
|
for (const [name, fn] of [
|
|
["normal", satisfy],
|
|
["runtime", createRuntimeFunction(satisfyRuntimeCode)]
|
|
]) {
|
|
if (item.startsWith("!")) {
|
|
it(`should not be satisfied by ${item.slice(
|
|
1
|
|
)} (${name})`, () => {
|
|
expect(fn(parseRange(range), item.slice(1))).toBe(false);
|
|
});
|
|
} else {
|
|
it(`should be satisfied by ${item} (${name})`, () => {
|
|
expect(fn(parseRange(range), item)).toBe(true);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|