diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts index 76d4cf2d65e7a..7c4a0ce8177ea 100644 --- a/src/compiler/semver.ts +++ b/src/compiler/semver.ts @@ -15,12 +15,14 @@ namespace ts { // > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers // > MUST NOT include leading zeroes. const prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i; + const prereleasePartRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)$/i; // https://semver.org/#spec-item-10 // > Build metadata MAY be denoted by appending a plus sign and a series of dot separated // > identifiers immediately following the patch or pre-release version. Identifiers MUST // > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. const buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i; + const buildPartRegExp = /^[a-z0-9-]+$/i; // https://semver.org/#spec-item-9 // > Numeric identifiers MUST NOT include leading zeroes. @@ -30,7 +32,7 @@ namespace ts { * Describes a precise semantic version number, https://semver.org */ export class Version { - static readonly zero = new Version(0, 0, 0); + static readonly zero = new Version(0, 0, 0, ["0"]); readonly major: number; readonly minor: number; @@ -39,8 +41,8 @@ namespace ts { readonly build: readonly string[]; constructor(text: string); - constructor(major: number, minor?: number, patch?: number, prerelease?: string, build?: string); - constructor(major: number | string, minor = 0, patch = 0, prerelease = "", build = "") { + constructor(major: number, minor?: number, patch?: number, prerelease?: string | readonly string[], build?: string | readonly string[]); + constructor(major: number | string, minor = 0, patch = 0, prerelease: string | readonly string[] = "", build: string | readonly string[] = "") { if (typeof major === "string") { const result = Debug.checkDefined(tryParseComponents(major), "Invalid version"); ({ major, minor, patch, prerelease, build } = result); @@ -49,13 +51,18 @@ namespace ts { Debug.assert(major >= 0, "Invalid argument: major"); Debug.assert(minor >= 0, "Invalid argument: minor"); Debug.assert(patch >= 0, "Invalid argument: patch"); - Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease"); - Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build"); + + const prereleaseArray = prerelease ? isArray(prerelease) ? prerelease : prerelease.split(".") : emptyArray; + const buildArray = build ? isArray(build) ? build : build.split(".") : emptyArray; + + Debug.assert(every(prereleaseArray, s => prereleasePartRegExp.test(s)), "Invalid argument: prerelease"); + Debug.assert(every(buildArray, s => buildPartRegExp.test(s)), "Invalid argument: build"); + this.major = major; this.minor = minor; this.patch = patch; - this.prerelease = prerelease ? prerelease.split(".") : emptyArray; - this.build = build ? build.split(".") : emptyArray; + this.prerelease = prereleaseArray; + this.build = buildArray; } static tryParse(text: string) { @@ -96,6 +103,17 @@ namespace ts { } } + with(fields: { major?: number, minor?: number, patch?: number, prerelease?: string | readonly string[], build?: string | readonly string[] }) { + const { + major = this.major, + minor = this.minor, + patch = this.patch, + prerelease = this.prerelease, + build = this.build + } = fields; + return new Version(major, minor, patch, prerelease, build); + } + toString() { let result = `${this.major}.${this.minor}.${this.patch}`; if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`; @@ -184,6 +202,10 @@ namespace ts { return undefined; } + /** + * Tests whether a version matches the range. This is equivalent to `satisfies(version, range, { includePrerelease: true })`. + * in `node-semver`. + */ test(version: Version | string) { if (typeof version === "string") version = new Version(version); return testDisjunction(version, this._alternatives); @@ -311,20 +333,22 @@ namespace ts { break; case "<": case ">=": - comparators.push(createComparator(operator, version)); + comparators.push( + isWildcard(minor) || isWildcard(patch) ? createComparator(operator, version.with({ prerelease: "0" })) : + createComparator(operator, version)); break; case "<=": case ">": comparators.push( - isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) : - isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) : + isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major").with({ prerelease: "0" })) : + isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor").with({ prerelease: "0" })) : createComparator(operator, version)); break; case "=": case undefined: if (isWildcard(minor) || isWildcard(patch)) { - comparators.push(createComparator(">=", version)); - comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor"))); + comparators.push(createComparator(">=", version.with({ prerelease: "0" }))); + comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor").with({ prerelease: "0" }))); } else { comparators.push(createComparator("=", version)); @@ -389,4 +413,4 @@ namespace ts { function formatComparator(comparator: Comparator) { return `${comparator.operator}${comparator.operand}`; } -} +} \ No newline at end of file diff --git a/src/testRunner/unittests/semver.ts b/src/testRunner/unittests/semver.ts index 2e6a61fbad87d..272704c8d0366 100644 --- a/src/testRunner/unittests/semver.ts +++ b/src/testRunner/unittests/semver.ts @@ -1,29 +1,6 @@ namespace ts { import theory = Utils.theory; describe("unittests:: semver", () => { - describe("VersionRange", () => { - function assertVersionRange(version: string, good: string[], bad: string[]): () => void { - return () => { - const range = VersionRange.tryParse(version)!; - assert(range); - for (const g of good) { - assert.isTrue(range.test(g), g); - } - for (const b of bad) { - assert.isFalse(range.test(b), b); - } - }; - } - it("< works", assertVersionRange("<3.8.0", ["3.6", "3.7"], ["3.8", "3.9", "4.0"])); - it("<= works", assertVersionRange("<=3.8.0", ["3.6", "3.7", "3.8"], ["3.9", "4.0"])); - it("> works", assertVersionRange(">3.8.0", ["3.9", "4.0"], ["3.6", "3.7", "3.8"])); - it(">= works", assertVersionRange(">=3.8.0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); - - it("< works with prerelease", assertVersionRange("<3.8.0-0", ["3.6", "3.7"], ["3.8", "3.9", "4.0"])); - it("<= works with prerelease", assertVersionRange("<=3.8.0-0", ["3.6", "3.7"], ["3.8", "3.9", "4.0"])); - it("> works with prerelease", assertVersionRange(">3.8.0-0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); - it(">= works with prerelease", assertVersionRange(">=3.8.0-0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); - }); describe("Version", () => { function assertVersion(version: Version, [major, minor, patch, prerelease, build]: [number, number, number, string[]?, string[]?]) { assert.strictEqual(version.major, major); @@ -38,6 +15,7 @@ namespace ts { }); it("parts", () => { assertVersion(new Version(1, 2, 3, "pre.4", "build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]); + assertVersion(new Version(1, 2, 3, ["pre", "4"], ["build", "5"]), [1, 2, 3, ["pre", "4"], ["build", "5"]]); assertVersion(new Version(1, 2, 3), [1, 2, 3]); assertVersion(new Version(1, 2), [1, 2, 0]); assertVersion(new Version(1), [1, 0, 0]); @@ -120,129 +98,826 @@ namespace ts { }); }); describe("VersionRange", () => { - function assertRange(rangeText: string, versionText: string, inRange = true) { + it("major wildcard types treated the same", () => { + const versionStrings = [ + "", + "*", + "*.*", + "*.*.*", + "x", + "x.x", + "x.x.x", + "X", + "X.X", + "X.X.X", + ]; + for (let i = 0; i < versionStrings.length; i++) { + for (let j = i + 1; j < versionStrings.length; j++) { + const left = new VersionRange(versionStrings[i]); + const right = new VersionRange(versionStrings[j]); + assert.strictEqual(left.toString(), right.toString()); + } + } + }); + + it("minor wildcard types treated the same", () => { + const versionStrings = [ + "1.*", + "1.*.*", + "1.x", + "1.x.x", + "1.X", + "1.X.X", + ]; + for (let i = 0; i < versionStrings.length; i++) { + for (let j = i + 1; j < versionStrings.length; j++) { + const left = new VersionRange(versionStrings[i]); + const right = new VersionRange(versionStrings[j]); + assert.strictEqual(left.toString(), right.toString()); + } + } + }); + + it("patch wildcard types treated the same", () => { + const versionStrings = [ + "1.2.*", + "1.2.x", + "1.2.X", + ]; + for (let i = 0; i < versionStrings.length; i++) { + for (let j = i + 1; j < versionStrings.length; j++) { + const left = new VersionRange(versionStrings[i]); + const right = new VersionRange(versionStrings[j]); + assert.strictEqual(left.toString(), right.toString()); + } + } + }); + + function assertVersionRange(version: string, good: string[], bad: string[]): () => void { + return () => { + const range = VersionRange.tryParse(version)!; + assert(range); + for (const g of good) { + assert.isTrue(range.test(g), g); + } + for (const b of bad) { + assert.isFalse(range.test(b), b); + } + }; + } + + it("< works", assertVersionRange("<3.8.0", ["3.6", "3.7"], ["3.8", "3.9", "4.0"])); + it("<= works", assertVersionRange("<=3.8.0", ["3.6", "3.7", "3.8"], ["3.9", "4.0"])); + it("> works", assertVersionRange(">3.8.0", ["3.9", "4.0"], ["3.6", "3.7", "3.8"])); + it(">= works", assertVersionRange(">=3.8.0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); + + it("< works with prerelease", assertVersionRange("<3.8.0-0", ["3.6", "3.7"], ["3.8", "3.9", "4.0"])); + it("<= works with prerelease", assertVersionRange("<=3.8.0-0", ["3.6", "3.7"], ["3.8", "3.9", "4.0"])); + it("> works with prerelease", assertVersionRange(">3.8.0-0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); + it(">= works with prerelease", assertVersionRange(">=3.8.0-0", ["3.8", "3.9", "4.0"], ["3.6", "3.7"])); + + function assertRange(rangeText: string, versionText: string, inRange: boolean) { const range = new VersionRange(rangeText); const version = new Version(versionText); assert.strictEqual(range.test(version), inRange, `Expected version '${version}' ${inRange ? `to be` : `to not be`} in range '${rangeText}' (${range})`); } + theory("comparators", assertRange, [ - ["", "1.0.0"], - ["*", "1.0.0"], - ["1", "1.0.0"], + // empty (matches everything) + ["", "2.0.0", true], + ["", "2.0.0-0", true], + ["", "1.1.0", true], + ["", "1.1.0-0", true], + ["", "1.0.1", true], + ["", "1.0.1-0", true], + ["", "1.0.0", true], + ["", "1.0.0-0", true], + ["", "0.0.0", true], + ["", "0.0.0-0", true], + + // wildcard major (matches everything) + ["*", "2.0.0", true], + ["*", "2.0.0-0", true], + ["*", "1.1.0", true], + ["*", "1.1.0-0", true], + ["*", "1.0.1", true], + ["*", "1.0.1-0", true], + ["*", "1.0.0", true], + ["*", "1.0.0-0", true], + ["*", "0.0.0", true], + ["*", "0.0.0-0", true], + + // wildcard minor ["1", "2.0.0", false], - ["1.0", "1.0.0"], + ["1", "2.0.0-0", false], + ["1", "1.1.0", true], + ["1", "1.1.0-0", true], + ["1", "1.0.1", true], + ["1", "1.0.1-0", true], + ["1", "1.0.0", true], + ["1", "1.0.0-0", true], + ["1", "0.0.0", false], + ["1", "0.0.0-0", false], + + // wildcard patch + ["1.1", "2.0.0", false], + ["1.1", "2.0.0-0", false], + ["1.1", "1.1.0", true], + ["1.1", "1.1.0-0", true], + ["1.1", "1.0.1", false], + ["1.1", "1.0.1-0", false], + ["1.1", "1.0.0", false], + ["1.1", "1.0.0-0", false], + ["1.1", "0.0.0", false], + ["1.1", "0.0.0-0", false], + ["1.0", "2.0.0", false], + ["1.0", "2.0.0-0", false], ["1.0", "1.1.0", false], - ["1.0.0", "1.0.0"], + ["1.0", "1.1.0-0", false], + ["1.0", "1.0.1", true], + ["1.0", "1.0.1-0", true], + ["1.0", "1.0.0", true], + ["1.0", "1.0.0-0", true], + ["1.0", "0.0.0", false], + ["1.0", "0.0.0-0", false], + + // exact + ["1.1.0", "2.0.0", false], + ["1.1.0", "2.0.0-0", false], + ["1.1.0", "1.1.0", true], + ["1.1.0", "1.1.0-0", false], + ["1.1.0", "1.0.1", false], + ["1.1.0", "1.0.1-0", false], + ["1.1.0", "1.0.0-0", false], + ["1.1.0", "1.0.0", false], + ["1.1.0", "0.0.0", false], + ["1.1.0", "0.0.0-0", false], + ["1.1.0-0", "2.0.0", false], + ["1.1.0-0", "2.0.0-0", false], + ["1.1.0-0", "1.1.0", false], + ["1.1.0-0", "1.1.0-0", true], + ["1.1.0-0", "1.0.1", false], + ["1.1.0-0", "1.0.1-0", false], + ["1.1.0-0", "1.0.0-0", false], + ["1.1.0-0", "1.0.0", false], + ["1.1.0-0", "0.0.0", false], + ["1.1.0-0", "0.0.0-0", false], + ["1.0.1", "2.0.0", false], + ["1.0.1", "2.0.0-0", false], + ["1.0.1", "1.1.0", false], + ["1.0.1", "1.1.0-0", false], + ["1.0.1", "1.0.1", true], + ["1.0.1", "1.0.1-0", false], + ["1.0.1", "1.0.0-0", false], + ["1.0.1", "1.0.0", false], + ["1.0.1", "0.0.0", false], + ["1.0.1", "0.0.0-0", false], + ["1.0.1-0", "2.0.0", false], + ["1.0.1-0", "2.0.0-0", false], + ["1.0.1-0", "1.1.0", false], + ["1.0.1-0", "1.1.0-0", false], + ["1.0.1-0", "1.0.1", false], + ["1.0.1-0", "1.0.1-0", true], + ["1.0.1-0", "1.0.0-0", false], + ["1.0.1-0", "1.0.0", false], + ["1.0.1-0", "0.0.0", false], + ["1.0.1-0", "0.0.0-0", false], + ["1.0.0", "2.0.0", false], + ["1.0.0", "2.0.0-0", false], + ["1.0.0", "1.1.0", false], + ["1.0.0", "1.1.0-0", false], ["1.0.0", "1.0.1", false], - ["1.*", "1.0.0"], - ["1.*", "2.0.0", false], - ["1.x", "1.0.0"], - ["1.x", "2.0.0", false], - ["=1", "1.0.0"], - ["=1", "1.1.0"], - ["=1", "1.0.1"], - ["=1.0", "1.0.0"], - ["=1.0", "1.0.1"], - ["=1.0.0", "1.0.0"], - ["=*", "0.0.0"], - ["=*", "1.0.0"], - [">1", "2"], - [">1.0", "1.1"], - [">1.0.0", "1.0.1"], - [">1.0.0", "1.0.1-pre"], - [">*", "0.0.0", false], + ["1.0.0", "1.0.1-0", false], + ["1.0.0", "1.0.0-0", false], + ["1.0.0", "1.0.0", true], + ["1.0.0", "0.0.0", false], + ["1.0.0", "0.0.0-0", false], + ["1.0.0-0", "2.0.0", false], + ["1.0.0-0", "2.0.0-0", false], + ["1.0.0-0", "1.1.0", false], + ["1.0.0-0", "1.1.0-0", false], + ["1.0.0-0", "1.0.1", false], + ["1.0.0-0", "1.0.1-0", false], + ["1.0.0-0", "1.0.0", false], + ["1.0.0-0", "1.0.0-0", true], + + // = wildcard major (matches everything) + ["=*", "2.0.0", true], + ["=*", "2.0.0-0", true], + ["=*", "1.1.0", true], + ["=*", "1.1.0-0", true], + ["=*", "1.0.1", true], + ["=*", "1.0.1-0", true], + ["=*", "1.0.0", true], + ["=*", "1.0.0-0", true], + ["=*", "0.0.0", true], + ["=*", "0.0.0-0", true], + + // = wildcard minor + ["=1", "2.0.0", false], + ["=1", "2.0.0-0", false], + ["=1", "1.1.0", true], + ["=1", "1.1.0-0", true], + ["=1", "1.0.1", true], + ["=1", "1.0.1-0", true], + ["=1", "1.0.0", true], + ["=1", "1.0.0-0", true], + ["=1", "0.0.0", false], + ["=1", "0.0.0-0", false], + + // = wildcard patch + ["=1.1", "2.0.0", false], + ["=1.1", "2.0.0-0", false], + ["=1.1", "1.1.0", true], + ["=1.1", "1.1.0-0", true], + ["=1.1", "1.0.1", false], + ["=1.1", "1.0.1-0", false], + ["=1.1", "1.0.0", false], + ["=1.1", "1.0.0-0", false], + ["=1.1", "0.0.0", false], + ["=1.1", "0.0.0-0", false], + ["=1.0", "2.0.0", false], + ["=1.0", "2.0.0-0", false], + ["=1.0", "1.1.0", false], + ["=1.0", "1.1.0-0", false], + ["=1.0", "1.0.1", true], + ["=1.0", "1.0.1-0", true], + ["=1.0", "1.0.0", true], + ["=1.0", "1.0.0-0", true], + ["=1.0", "0.0.0", false], + ["=1.0", "0.0.0-0", false], + + // = exact + ["=1.1.0", "2.0.0", false], + ["=1.1.0", "2.0.0-0", false], + ["=1.1.0", "1.1.0", true], + ["=1.1.0", "1.1.0-0", false], + ["=1.1.0", "1.0.1", false], + ["=1.1.0", "1.0.1-0", false], + ["=1.1.0", "1.0.0-0", false], + ["=1.1.0", "1.0.0", false], + ["=1.1.0", "0.0.0", false], + ["=1.1.0", "0.0.0-0", false], + ["=1.1.0-0", "2.0.0", false], + ["=1.1.0-0", "2.0.0-0", false], + ["=1.1.0-0", "1.1.0", false], + ["=1.1.0-0", "1.1.0-0", true], + ["=1.1.0-0", "1.0.1", false], + ["=1.1.0-0", "1.0.1-0", false], + ["=1.1.0-0", "1.0.0-0", false], + ["=1.1.0-0", "1.0.0", false], + ["=1.1.0-0", "0.0.0", false], + ["=1.1.0-0", "0.0.0-0", false], + ["=1.0.1", "2.0.0", false], + ["=1.0.1", "2.0.0-0", false], + ["=1.0.1", "1.1.0", false], + ["=1.0.1", "1.1.0-0", false], + ["=1.0.1", "1.0.1", true], + ["=1.0.1", "1.0.1-0", false], + ["=1.0.1", "1.0.0-0", false], + ["=1.0.1", "1.0.0", false], + ["=1.0.1", "0.0.0", false], + ["=1.0.1", "0.0.0-0", false], + ["=1.0.1-0", "2.0.0", false], + ["=1.0.1-0", "2.0.0-0", false], + ["=1.0.1-0", "1.1.0", false], + ["=1.0.1-0", "1.1.0-0", false], + ["=1.0.1-0", "1.0.1", false], + ["=1.0.1-0", "1.0.1-0", true], + ["=1.0.1-0", "1.0.0-0", false], + ["=1.0.1-0", "1.0.0", false], + ["=1.0.1-0", "0.0.0", false], + ["=1.0.1-0", "0.0.0-0", false], + ["=1.0.0", "2.0.0", false], + ["=1.0.0", "2.0.0-0", false], + ["=1.0.0", "1.1.0", false], + ["=1.0.0", "1.1.0-0", false], + ["=1.0.0", "1.0.1", false], + ["=1.0.0", "1.0.1-0", false], + ["=1.0.0", "1.0.0-0", false], + ["=1.0.0", "1.0.0", true], + ["=1.0.0", "0.0.0", false], + ["=1.0.0", "0.0.0-0", false], + ["=1.0.0-0", "2.0.0", false], + ["=1.0.0-0", "2.0.0-0", false], + ["=1.0.0-0", "1.1.0", false], + ["=1.0.0-0", "1.1.0-0", false], + ["=1.0.0-0", "1.0.1", false], + ["=1.0.0-0", "1.0.1-0", false], + ["=1.0.0-0", "1.0.0", false], + ["=1.0.0-0", "1.0.0-0", true], + + // > wildcard major (matches nothing) + [">*", "2.0.0", false], + [">*", "2.0.0-0", false], + [">*", "1.1.0", false], + [">*", "1.1.0-0", false], + [">*", "1.0.1", false], + [">*", "1.0.1-0", false], [">*", "1.0.0", false], - [">=1", "1.0.0"], - [">=1.0", "1.0.0"], - [">=1.0.0", "1.0.0"], - [">=1.0.0", "1.0.1-pre"], - [">=*", "0.0.0"], - [">=*", "1.0.0"], - ["<2", "1.0.0"], - ["<2.1", "2.0.0"], - ["<2.0.1", "2.0.0"], - ["<2.0.0", "2.0.0-pre"], - ["<*", "0.0.0", false], + [">*", "1.0.0-0", false], + [">*", "0.0.0", false], + [">*", "0.0.0-0", false], + + // > wildcard minor + [">1", "2.0.0", true], + [">1", "2.0.0-0", true], + [">1", "1.1.0", false], + [">1", "1.1.0-0", false], + [">1", "1.0.1", false], + [">1", "1.0.1-0", false], + [">1", "1.0.0", false], + [">1", "1.0.0-0", false], + [">1", "0.0.0", false], + [">1", "0.0.0-0", false], + + // > wildcard patch + [">1.1", "2.0.0", true], + [">1.1", "2.0.0-0", true], + [">1.1", "1.1.0", false], + [">1.1", "1.1.0-0", false], + [">1.1", "1.0.1", false], + [">1.1", "1.0.1-0", false], + [">1.1", "1.0.0", false], + [">1.1", "1.0.0-0", false], + [">1.1", "0.0.0", false], + [">1.1", "0.0.0-0", false], + [">1.0", "2.0.0", true], + [">1.0", "2.0.0-0", true], + [">1.0", "1.1.0", true], + [">1.0", "1.1.0-0", true], + [">1.0", "1.0.1", false], + [">1.0", "1.0.1-0", false], + [">1.0", "1.0.0", false], + [">1.0", "1.0.0-0", false], + [">1.0", "0.0.0", false], + [">1.0", "0.0.0-0", false], + + // > exact + [">1.1.0", "2.0.0", true], + [">1.1.0", "2.0.0-0", true], + [">1.1.0", "1.1.0", false], + [">1.1.0", "1.1.0-0", false], + [">1.1.0", "1.0.1", false], + [">1.1.0", "1.0.1-0", false], + [">1.1.0", "1.0.0", false], + [">1.1.0", "1.0.0-0", false], + [">1.1.0", "0.0.0", false], + [">1.1.0", "0.0.0-0", false], + [">1.1.0-0", "2.0.0", true], + [">1.1.0-0", "2.0.0-0", true], + [">1.1.0-0", "1.1.0", true], + [">1.1.0-0", "1.1.0-0", false], + [">1.1.0-0", "1.0.1", false], + [">1.1.0-0", "1.0.1-0", false], + [">1.1.0-0", "1.0.0", false], + [">1.1.0-0", "1.0.0-0", false], + [">1.1.0-0", "0.0.0", false], + [">1.1.0-0", "0.0.0-0", false], + [">1.0.1", "2.0.0", true], + [">1.0.1", "2.0.0-0", true], + [">1.0.1", "1.1.0", true], + [">1.0.1", "1.1.0-0", true], + [">1.0.1", "1.0.1", false], + [">1.0.1", "1.0.1-0", false], + [">1.0.1", "1.0.0", false], + [">1.0.1", "1.0.0-0", false], + [">1.0.1", "0.0.0", false], + [">1.0.1", "0.0.0-0", false], + [">1.0.1-0", "2.0.0", true], + [">1.0.1-0", "2.0.0-0", true], + [">1.0.1-0", "1.1.0", true], + [">1.0.1-0", "1.1.0-0", true], + [">1.0.1-0", "1.0.1", true], + [">1.0.1-0", "1.0.1-0", false], + [">1.0.1-0", "1.0.0", false], + [">1.0.1-0", "1.0.0-0", false], + [">1.0.1-0", "0.0.0", false], + [">1.0.1-0", "0.0.0-0", false], + [">1.0.0", "2.0.0", true], + [">1.0.0", "2.0.0-0", true], + [">1.0.0", "1.1.0", true], + [">1.0.0", "1.1.0-0", true], + [">1.0.0", "1.0.1", true], + [">1.0.0", "1.0.1-0", true], + [">1.0.0", "1.0.0", false], + [">1.0.0", "1.0.0-0", false], + [">1.0.0", "0.0.0", false], + [">1.0.0", "0.0.0-0", false], + [">1.0.0-0", "2.0.0", true], + [">1.0.0-0", "2.0.0-0", true], + [">1.0.0-0", "1.1.0", true], + [">1.0.0-0", "1.1.0-0", true], + [">1.0.0-0", "1.0.1", true], + [">1.0.0-0", "1.0.1-0", true], + [">1.0.0-0", "1.0.0", true], + [">1.0.0-0", "1.0.0-0", false], + [">1.0.0-0", "0.0.0", false], + [">1.0.0-0", "0.0.0-0", false], + + // >= wildcard major (matches everything) + [">=*", "2.0.0", true], + [">=*", "2.0.0-0", true], + [">=*", "1.1.0", true], + [">=*", "1.1.0-0", true], + [">=*", "1.0.1", true], + [">=*", "1.0.1-0", true], + [">=*", "1.0.0", true], + [">=*", "1.0.0-0", true], + [">=*", "0.0.0", true], + [">=*", "0.0.0-0", true], + + // >= wildcard minor + [">=1", "2.0.0", true], + [">=1", "2.0.0-0", true], + [">=1", "1.1.0", true], + [">=1", "1.1.0-0", true], + [">=1", "1.0.1", true], + [">=1", "1.0.1-0", true], + [">=1", "1.0.0", true], + [">=1", "1.0.0-0", true], + [">=1", "0.0.0", false], + [">=1", "0.0.0-0", false], + + // >= wildcard patch + [">=1.1", "2.0.0", true], + [">=1.1", "2.0.0-0", true], + [">=1.1", "1.1.0", true], + [">=1.1", "1.1.0-0", true], + [">=1.1", "1.0.1", false], + [">=1.1", "1.0.1-0", false], + [">=1.1", "1.0.0", false], + [">=1.1", "1.0.0-0", false], + [">=1.1", "0.0.0", false], + [">=1.1", "0.0.0-0", false], + [">=1.0", "2.0.0", true], + [">=1.0", "2.0.0-0", true], + [">=1.0", "1.1.0", true], + [">=1.0", "1.1.0-0", true], + [">=1.0", "1.0.1", true], + [">=1.0", "1.0.1-0", true], + [">=1.0", "1.0.0", true], + [">=1.0", "1.0.0-0", true], + [">=1.0", "0.0.0", false], + [">=1.0", "0.0.0-0", false], + + // >= exact + [">=1.1.0", "2.0.0", true], + [">=1.1.0", "2.0.0-0", true], + [">=1.1.0", "1.1.0", true], + [">=1.1.0", "1.1.0-0", false], + [">=1.1.0", "1.0.1", false], + [">=1.1.0", "1.0.1-0", false], + [">=1.1.0", "1.0.0", false], + [">=1.1.0", "1.0.0-0", false], + [">=1.1.0", "0.0.0", false], + [">=1.1.0", "0.0.0-0", false], + [">=1.1.0-0", "2.0.0", true], + [">=1.1.0-0", "2.0.0-0", true], + [">=1.1.0-0", "1.1.0", true], + [">=1.1.0-0", "1.1.0-0", true], + [">=1.1.0-0", "1.0.1", false], + [">=1.1.0-0", "1.0.1-0", false], + [">=1.1.0-0", "1.0.0", false], + [">=1.1.0-0", "1.0.0-0", false], + [">=1.1.0-0", "0.0.0", false], + [">=1.1.0-0", "0.0.0-0", false], + [">=1.0.1", "2.0.0", true], + [">=1.0.1", "2.0.0-0", true], + [">=1.0.1", "1.1.0", true], + [">=1.0.1", "1.1.0-0", true], + [">=1.0.1", "1.0.1", true], + [">=1.0.1", "1.0.1-0", false], + [">=1.0.1", "1.0.0", false], + [">=1.0.1", "1.0.0-0", false], + [">=1.0.1", "0.0.0", false], + [">=1.0.1", "0.0.0-0", false], + [">=1.0.1-0", "2.0.0", true], + [">=1.0.1-0", "2.0.0-0", true], + [">=1.0.1-0", "1.1.0", true], + [">=1.0.1-0", "1.1.0-0", true], + [">=1.0.1-0", "1.0.1", true], + [">=1.0.1-0", "1.0.1-0", true], + [">=1.0.1-0", "1.0.0", false], + [">=1.0.1-0", "1.0.0-0", false], + [">=1.0.1-0", "0.0.0", false], + [">=1.0.1-0", "0.0.0-0", false], + [">=1.0.0", "2.0.0", true], + [">=1.0.0", "2.0.0-0", true], + [">=1.0.0", "1.1.0", true], + [">=1.0.0", "1.1.0-0", true], + [">=1.0.0", "1.0.1", true], + [">=1.0.0", "1.0.1-0", true], + [">=1.0.0", "1.0.0", true], + [">=1.0.0", "1.0.0-0", false], + [">=1.0.0", "0.0.0", false], + [">=1.0.0", "0.0.0-0", false], + [">=1.0.0-0", "2.0.0", true], + [">=1.0.0-0", "2.0.0-0", true], + [">=1.0.0-0", "1.1.0", true], + [">=1.0.0-0", "1.1.0-0", true], + [">=1.0.0-0", "1.0.1", true], + [">=1.0.0-0", "1.0.1-0", true], + [">=1.0.0-0", "1.0.0", true], + [">=1.0.0-0", "1.0.0-0", true], + [">=1.0.0-0", "0.0.0", false], + [">=1.0.0-0", "0.0.0-0", false], + + // < wildcard major (matches nothing) + ["<*", "2.0.0", false], + ["<*", "2.0.0-0", false], + ["<*", "1.1.0", false], + ["<*", "1.1.0-0", false], + ["<*", "1.0.1", false], + ["<*", "1.0.1-0", false], ["<*", "1.0.0", false], - ["<=2", "2.0.0"], - ["<=2.1", "2.1.0"], - ["<=2.0.1", "2.0.1"], - ["<=*", "0.0.0"], - ["<=*", "1.0.0"], + ["<*", "1.0.0-0", false], + ["<*", "0.0.0", false], + ["<*", "0.0.0-0", false], + + // < wildcard minor + ["<1", "2.0.0", false], + ["<1", "2.0.0-0", false], + ["<1", "1.1.0", false], + ["<1", "1.1.0-0", false], + ["<1", "1.0.1", false], + ["<1", "1.0.1-0", false], + ["<1", "1.0.0", false], + ["<1", "1.0.0-0", false], + ["<1", "0.0.0", true], + ["<1", "0.0.0-0", true], + + // < wildcard patch + ["<1.1", "2.0.0", false], + ["<1.1", "2.0.0-0", false], + ["<1.1", "1.1.0", false], + ["<1.1", "1.1.0-0", false], + ["<1.1", "1.0.1", true], + ["<1.1", "1.0.1-0", true], + ["<1.1", "1.0.0", true], + ["<1.1", "1.0.0-0", true], + ["<1.1", "0.0.0", true], + ["<1.1", "0.0.0-0", true], + ["<1.0", "2.0.0", false], + ["<1.0", "2.0.0-0", false], + ["<1.0", "1.1.0", false], + ["<1.0", "1.1.0-0", false], + ["<1.0", "1.0.1", false], + ["<1.0", "1.0.1-0", false], + ["<1.0", "1.0.0", false], + ["<1.0", "1.0.0-0", false], + ["<1.0", "0.0.0", true], + ["<1.0", "0.0.0-0", true], + + // < exact + ["<1.1.0", "2.0.0", false], + ["<1.1.0", "2.0.0-0", false], + ["<1.1.0", "1.1.0", false], + ["<1.1.0", "1.1.0-0", true], + ["<1.1.0", "1.0.1", true], + ["<1.1.0", "1.0.1-0", true], + ["<1.1.0", "1.0.0", true], + ["<1.1.0", "1.0.0-0", true], + ["<1.1.0", "0.0.0", true], + ["<1.1.0", "0.0.0-0", true], + ["<1.1.0-0", "2.0.0", false], + ["<1.1.0-0", "2.0.0-0", false], + ["<1.1.0-0", "1.1.0", false], + ["<1.1.0-0", "1.1.0-0", false], + ["<1.1.0-0", "1.0.1", true], + ["<1.1.0-0", "1.0.1-0", true], + ["<1.1.0-0", "1.0.0", true], + ["<1.1.0-0", "1.0.0-0", true], + ["<1.1.0-0", "0.0.0", true], + ["<1.1.0-0", "0.0.0-0", true], + ["<1.0.1", "2.0.0", false], + ["<1.0.1", "2.0.0-0", false], + ["<1.0.1", "1.1.0", false], + ["<1.0.1", "1.1.0-0", false], + ["<1.0.1", "1.0.1", false], + ["<1.0.1", "1.0.1-0", true], + ["<1.0.1", "1.0.0", true], + ["<1.0.1", "1.0.0-0", true], + ["<1.0.1", "0.0.0", true], + ["<1.0.1", "0.0.0-0", true], + ["<1.0.1-0", "2.0.0", false], + ["<1.0.1-0", "2.0.0-0", false], + ["<1.0.1-0", "1.1.0", false], + ["<1.0.1-0", "1.1.0-0", false], + ["<1.0.1-0", "1.0.1", false], + ["<1.0.1-0", "1.0.1-0", false], + ["<1.0.1-0", "1.0.0", true], + ["<1.0.1-0", "1.0.0-0", true], + ["<1.0.1-0", "0.0.0", true], + ["<1.0.1-0", "0.0.0-0", true], + ["<1.0.0", "2.0.0", false], + ["<1.0.0", "2.0.0-0", false], + ["<1.0.0", "1.1.0", false], + ["<1.0.0", "1.1.0-0", false], + ["<1.0.0", "1.0.1", false], + ["<1.0.0", "1.0.1-0", false], + ["<1.0.0", "1.0.0", false], + ["<1.0.0", "1.0.0-0", true], + ["<1.0.0", "0.0.0", true], + ["<1.0.0", "0.0.0-0", true], + ["<1.0.0-0", "2.0.0", false], + ["<1.0.0-0", "2.0.0-0", false], + ["<1.0.0-0", "1.1.0", false], + ["<1.0.0-0", "1.1.0-0", false], + ["<1.0.0-0", "1.0.1", false], + ["<1.0.0-0", "1.0.1-0", false], + ["<1.0.0-0", "1.0.0", false], + ["<1.0.0-0", "1.0.0-0", false], + ["<1.0.0-0", "0.0.0", true], + ["<1.0.0-0", "0.0.0-0", true], + + // <= wildcard major (matches everything) + ["<=*", "2.0.0", true], + ["<=*", "2.0.0-0", true], + ["<=*", "1.1.0", true], + ["<=*", "1.1.0-0", true], + ["<=*", "1.0.1", true], + ["<=*", "1.0.1-0", true], + ["<=*", "1.0.0", true], + ["<=*", "1.0.0-0", true], + ["<=*", "0.0.0", true], + ["<=*", "0.0.0-0", true], + + // <= wildcard minor + ["<=1", "2.0.0", false], + ["<=1", "2.0.0-0", false], + ["<=1", "1.1.0", true], + ["<=1", "1.1.0-0", true], + ["<=1", "1.0.1", true], + ["<=1", "1.0.1-0", true], + ["<=1", "1.0.0", true], + ["<=1", "1.0.0-0", true], + ["<=1", "0.0.0", true], + ["<=1", "0.0.0-0", true], + + // <= wildcard patch + ["<=1.1", "2.0.0", false], + ["<=1.1", "2.0.0-0", false], + ["<=1.1", "1.1.0", true], + ["<=1.1", "1.1.0-0", true], + ["<=1.1", "1.0.1", true], + ["<=1.1", "1.0.1-0", true], + ["<=1.1", "1.0.0", true], + ["<=1.1", "1.0.0-0", true], + ["<=1.1", "0.0.0", true], + ["<=1.1", "0.0.0-0", true], + ["<=1.0", "2.0.0", false], + ["<=1.0", "2.0.0-0", false], + ["<=1.0", "1.1.0", false], + ["<=1.0", "1.1.0-0", false], + ["<=1.0", "1.0.1", true], + ["<=1.0", "1.0.1-0", true], + ["<=1.0", "1.0.0", true], + ["<=1.0", "1.0.0-0", true], + ["<=1.0", "0.0.0", true], + ["<=1.0", "0.0.0-0", true], + + // <= exact + ["<=1.1.0", "2.0.0", false], + ["<=1.1.0", "2.0.0-0", false], + ["<=1.1.0", "1.1.0", true], + ["<=1.1.0", "1.1.0-0", true], + ["<=1.1.0", "1.0.1", true], + ["<=1.1.0", "1.0.1-0", true], + ["<=1.1.0", "1.0.0", true], + ["<=1.1.0", "1.0.0-0", true], + ["<=1.1.0", "0.0.0", true], + ["<=1.1.0", "0.0.0-0", true], + ["<=1.1.0-0", "2.0.0", false], + ["<=1.1.0-0", "2.0.0-0", false], + ["<=1.1.0-0", "1.1.0", false], + ["<=1.1.0-0", "1.1.0-0", true], + ["<=1.1.0-0", "1.0.1", true], + ["<=1.1.0-0", "1.0.1-0", true], + ["<=1.1.0-0", "1.0.0", true], + ["<=1.1.0-0", "1.0.0-0", true], + ["<=1.1.0-0", "0.0.0", true], + ["<=1.1.0-0", "0.0.0-0", true], + ["<=1.0.1", "2.0.0", false], + ["<=1.0.1", "2.0.0-0", false], + ["<=1.0.1", "1.1.0", false], + ["<=1.0.1", "1.1.0-0", false], + ["<=1.0.1", "1.0.1", true], + ["<=1.0.1", "1.0.1-0", true], + ["<=1.0.1", "1.0.0", true], + ["<=1.0.1", "1.0.0-0", true], + ["<=1.0.1", "0.0.0", true], + ["<=1.0.1", "0.0.0-0", true], + ["<=1.0.1-0", "2.0.0", false], + ["<=1.0.1-0", "2.0.0-0", false], + ["<=1.0.1-0", "1.1.0", false], + ["<=1.0.1-0", "1.1.0-0", false], + ["<=1.0.1-0", "1.0.1", false], + ["<=1.0.1-0", "1.0.1-0", true], + ["<=1.0.1-0", "1.0.0", true], + ["<=1.0.1-0", "1.0.0-0", true], + ["<=1.0.1-0", "0.0.0", true], + ["<=1.0.1-0", "0.0.0-0", true], + ["<=1.0.0", "2.0.0", false], + ["<=1.0.0", "2.0.0-0", false], + ["<=1.0.0", "1.1.0", false], + ["<=1.0.0", "1.1.0-0", false], + ["<=1.0.0", "1.0.1", false], + ["<=1.0.0", "1.0.1-0", false], + ["<=1.0.0", "1.0.0", true], + ["<=1.0.0", "1.0.0-0", true], + ["<=1.0.0", "0.0.0", true], + ["<=1.0.0", "0.0.0-0", true], + ["<=1.0.0-0", "2.0.0", false], + ["<=1.0.0-0", "2.0.0-0", false], + ["<=1.0.0-0", "1.1.0", false], + ["<=1.0.0-0", "1.1.0-0", false], + ["<=1.0.0-0", "1.0.1", false], + ["<=1.0.0-0", "1.0.1-0", false], + ["<=1.0.0-0", "1.0.0", false], + ["<=1.0.0-0", "1.0.0-0", true], + ["<=1.0.0-0", "0.0.0", true], + ["<=1.0.0-0", "0.0.0-0", true], + + // https://github.com/microsoft/TypeScript/issues/50909 + [">4.8", "4.9.0-beta", true], + [">=4.9", "4.9.0-beta", true], + ["<4.9", "4.9.0-beta", false], + ["<=4.8", "4.9.0-beta", false], ]); theory("conjunctions", assertRange, [ - [">1.0.0 <2.0.0", "1.0.1"], + [">1.0.0 <2.0.0", "1.0.1", true], [">1.0.0 <2.0.0", "2.0.0", false], [">1.0.0 <2.0.0", "1.0.0", false], - [">1 >2", "3.0.0"], + [">1 >2", "3.0.0", true], ]); theory("disjunctions", assertRange, [ - [">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "1.0.0"], + [">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "1.0.0", true], [">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "2.0.0", false], - [">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "3.0.0"], + [">=1.0.0 <2.0.0 || >=3.0.0 <4.0.0", "3.0.0", true], ]); theory("hyphen", assertRange, [ - ["1.0.0 - 2.0.0", "1.0.0"], - ["1.0.0 - 2.0.0", "2.0.0"], + ["1.0.0 - 2.0.0", "1.0.0", true], + ["1.0.0 - 2.0.0", "2.0.0", true], ["1.0.0 - 2.0.0", "3.0.0", false], ]); theory("tilde", assertRange, [ - ["~0", "0.0.0"], - ["~0", "0.1.0"], - ["~0", "0.1.2"], - ["~0", "0.1.9"], + ["~0", "0.0.0", true], + ["~0", "0.1.0", true], + ["~0", "0.1.2", true], + ["~0", "0.1.9", true], ["~0", "1.0.0", false], - ["~0.1", "0.1.0"], - ["~0.1", "0.1.2"], - ["~0.1", "0.1.9"], + ["~0.1", "0.1.0", true], + ["~0.1", "0.1.2", true], + ["~0.1", "0.1.9", true], ["~0.1", "0.2.0", false], - ["~0.1.2", "0.1.2"], - ["~0.1.2", "0.1.9"], + ["~0.1.2", "0.1.2", true], + ["~0.1.2", "0.1.9", true], ["~0.1.2", "0.2.0", false], - ["~1", "1.0.0"], - ["~1", "1.2.0"], - ["~1", "1.2.3"], - ["~1", "1.2.0"], - ["~1", "1.2.3"], + ["~1", "1.0.0", true], + ["~1", "1.2.0", true], + ["~1", "1.2.3", true], + ["~1", "1.2.0", true], + ["~1", "1.2.3", true], ["~1", "0.0.0", false], ["~1", "2.0.0", false], - ["~1.2", "1.2.0"], - ["~1.2", "1.2.3"], + ["~1.2", "1.2.0", true], + ["~1.2", "1.2.3", true], ["~1.2", "1.1.0", false], ["~1.2", "1.3.0", false], - ["~1.2.3", "1.2.3"], - ["~1.2.3", "1.2.9"], + ["~1.2.3", "1.2.3", true], + ["~1.2.3", "1.2.9", true], ["~1.2.3", "1.1.0", false], ["~1.2.3", "1.3.0", false], ]); theory("caret", assertRange, [ - ["^0", "0.0.0"], - ["^0", "0.1.0"], - ["^0", "0.9.0"], - ["^0", "0.1.2"], - ["^0", "0.1.9"], + ["^0", "0.0.0", true], + ["^0", "0.1.0", true], + ["^0", "0.9.0", true], + ["^0", "0.1.2", true], + ["^0", "0.1.9", true], ["^0", "1.0.0", false], - ["^0.1", "0.1.0"], - ["^0.1", "0.1.2"], - ["^0.1", "0.1.9"], - ["^0.1.2", "0.1.2"], - ["^0.1.2", "0.1.9"], + ["^0.1", "0.1.0", true], + ["^0.1", "0.1.2", true], + ["^0.1", "0.1.9", true], + ["^0.1.2", "0.1.2", true], + ["^0.1.2", "0.1.9", true], ["^0.1.2", "0.0.0", false], ["^0.1.2", "0.2.0", false], ["^0.1.2", "1.0.0", false], - ["^1", "1.0.0"], - ["^1", "1.2.0"], - ["^1", "1.2.3"], - ["^1", "1.9.0"], + ["^1", "1.0.0", true], + ["^1", "1.2.0", true], + ["^1", "1.2.3", true], + ["^1", "1.9.0", true], ["^1", "0.0.0", false], ["^1", "2.0.0", false], - ["^1.2", "1.2.0"], - ["^1.2", "1.2.3"], - ["^1.2", "1.9.0"], + ["^1.2", "1.2.0", true], + ["^1.2", "1.2.3", true], + ["^1.2", "1.9.0", true], ["^1.2", "1.1.0", false], ["^1.2", "2.0.0", false], - ["^1.2.3", "1.2.3"], - ["^1.2.3", "1.9.0"], + ["^1.2.3", "1.2.3", true], + ["^1.2.3", "1.9.0", true], ["^1.2.3", "1.2.2", false], ["^1.2.3", "2.0.0", false], ]);