/
githubmirror
/
webpack
Обзор
Документация
Войти
/
githubmirror
/
webpack
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/SemVer.unittest.js
631 строка
12 KB
Alexander Akait
refactor: strict types for the test suite (#21147)
09 июн 2026, 20:15
Не верифицирован
09 июн 2026, 20:15
9bd0b91
Код
Авторство
О чём код?
"use strict"; const { parseRange, parseVersion, parseVersionRuntimeCode, rangeToString, rangeToStringRuntimeCode, satisfy, satisfyRuntimeCode, versionLt, versionLtRuntimeCode } = require("../lib/util/semver"); describe("SemVer", () => { const createRuntimeFunction = ( /** @type {(helpers: unknown) => string} */ runtimeCodeFunction ) => { const runtimeFunction = runtimeCodeFunction({ basicFunction: ( /** @type {string} */ args, /** @type {string[]} */ body ) => `(${args}) => {\n${body.join("\n")}\n}`, supportsArrowFunction: () => true }); const functionName = /** @type {RegExpMatchArray} */ ( runtimeFunction.match(/^var (\w+)/) )[1]; return eval( `(function (...args) { ${runtimeFunction}; return ${functionName}(...args); })` ); }; for (const [name, fn] of [ ["normal", parseVersion], [ "runtime", createRuntimeFunction( /** @type {(helpers: unknown) => string} */ ( /** @type {unknown} */ (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 no-sparse-arrays */ expect(fn("1.2.3-alpha.beta-42")).toEqual([ 1, 2, 3, , "alpha", "beta-42" ]); expect(fn("1.2.3-beta.1.alpha.0+5343")).toEqual([ 1, 2, 3, , "beta", 1, "alpha", 0, [], 5343 ]); /* eslint-enable no-sparse-arrays */ 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( /** @type {(helpers: unknown) => string} */ ( /** @type {unknown} */ (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", () => { /** @type {Record<string, string[]>} */ const cases = { "5 || 6 || 7.x.x": ["5.x.x || 6.x || 7"], "1 - 2": ["1 - 2"], "=3": [ "3", "v3", "3.x", "3.X", "3.x.x", "3.*", "3.*.*", "^3", "^3.x", "= 3" ], "=3.0": ["3.0", "v3.0", "3.0.x", "3.0.X", "3.0.*", "~3.0", "= 3.0"], "^3.4": ["^3.4.*", "^ 3.4"], "3.4 - 6.5": [">=3.4 <=6.5", ">= 3.4 <= 6.5"], "<=3.4": ["<3.4 || =3.4", "<= 3.4"], ">3.4": [">=3.4 !3.4", "> 3.4"], "1.2.3-alpha.x.x": ["1.2.3-alpha", "1.2.3-alpha+build.25"], "1.2.3-NaN": ["1.2.3-NaN"] }; 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", () => { /** @type {Record<string | number, string>} */ 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( /** @type {(helpers: unknown) => string} */ ( /** @type {unknown} */ (rangeToStringRuntimeCode) ) ) ] ]) { it(`should ${key} stringify to ${expected} (${name})`, () => { expect(fn(parseRange(key))).toEqual(expected); }); } } }); describe("satisfies", () => { /** @type {Record<string, string[]>} */ 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": [ "1", "1.1", "1.2", "1.2.1", "1.0.1", "1.1.1", "1.3.0", "!2.0.0", "!2.3.4", "!1.0.0-beta", "!1.1.0-beta" ], ">=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": [ "2.0.0", "2.1.0", "2.1.1", "2.2.0", "!1.0.0", "2.0.1", "2.1.2", "2.3.0", "!3.0.0", "!3.6.8", "!2.0.0-beta", "!2.1.0-beta" ], "~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( /** @type {(helpers: unknown) => string} */ ( /** @type {unknown} */ (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); }); } } } }); } }); });