mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 03:20:56 -06:00
Remove jsTypings/semver.ts, add unit tests and logging
This commit is contained in:
parent
79d7f371bb
commit
b9afdadf71
@ -3671,6 +3671,14 @@
|
||||
"category": "Error",
|
||||
"code": 6205
|
||||
},
|
||||
"'package.json' has invalid version '{0}' in 'typesVersions' field.": {
|
||||
"category": "Message",
|
||||
"code": 6206
|
||||
},
|
||||
"'package.json' does not have a 'typesVersions' entry that matches version '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6207
|
||||
},
|
||||
|
||||
"Projects to reference": {
|
||||
"category": "Message",
|
||||
|
||||
@ -127,7 +127,14 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function getPackageJsonTypesVersionsOverride(typesVersions: MapLike<string>) {
|
||||
const typeScriptVersion = Version.parse(versionMajorMinor);
|
||||
return getPackageJsonTypesVersionsOverrideWithTrace(typesVersions, /*state*/ undefined);
|
||||
}
|
||||
|
||||
let typeScriptVersion: Version | undefined;
|
||||
|
||||
function getPackageJsonTypesVersionsOverrideWithTrace(typesVersions: MapLike<string>, state: ModuleResolutionState | undefined) {
|
||||
if (!typeScriptVersion) typeScriptVersion = new Version(versionMajorMinor);
|
||||
|
||||
let bestVersion: Version | undefined;
|
||||
let bestVersionKey: string | undefined;
|
||||
for (const key in typesVersions) {
|
||||
@ -135,12 +142,15 @@ namespace ts {
|
||||
|
||||
const keyVersion = Version.tryParse(key);
|
||||
if (keyVersion === undefined) {
|
||||
if (state && state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_has_invalid_version_0_in_typesVersions_field, key);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// match the greatest version less than the current TypeScript version
|
||||
if (keyVersion.compareTo(typeScriptVersion) <= 0
|
||||
&& (bestVersion === undefined || keyVersion.compareTo(bestVersion) > 0)) {
|
||||
if (keyVersion.compareTo(bestVersion) > 0 &&
|
||||
keyVersion.compareTo(typeScriptVersion) <= 0) {
|
||||
bestVersion = keyVersion;
|
||||
bestVersionKey = key;
|
||||
}
|
||||
@ -169,22 +179,25 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = getPackageJsonTypesVersionsOverride(typesVersions);
|
||||
const result = getPackageJsonTypesVersionsOverrideWithTrace(typesVersions, state);
|
||||
if (!result) {
|
||||
return undefined;
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, versionMajorMinor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const { version: bestVersionKey, directory: bestVersionPath } = result;
|
||||
if (!isString(bestVersionPath)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersion['${bestVersionKey}']`, "string", typeof bestVersionPath);
|
||||
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "string", typeof bestVersionPath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.traceEnabled) {
|
||||
const path = normalizePath(combinePaths(baseDirectory, bestVersionPath));
|
||||
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, `typesVersion['${bestVersionKey}']`, bestVersionPath, path);
|
||||
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, `typesVersions['${bestVersionKey}']`, bestVersionPath, path);
|
||||
}
|
||||
|
||||
return bestVersionPath;
|
||||
|
||||
@ -1,48 +1,49 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
// Per https://semver.org/#spec-item-2:
|
||||
//
|
||||
// https://semver.org/#spec-item-2
|
||||
// > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
|
||||
// > integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor
|
||||
// > version, and Z is the patch version. Each element MUST increase numerically.
|
||||
//
|
||||
// NOTE: We differ here in that we allow X and X.Y, with missing parts having the default
|
||||
// value of `0`.
|
||||
const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:(\+[a-z0-9-.]+))?)?)?$/i;
|
||||
const versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
|
||||
|
||||
// Per https://semver.org/#spec-item-9:
|
||||
//
|
||||
// https://semver.org/#spec-item-9
|
||||
// > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated
|
||||
// > identifiers immediately following the patch version. Identifiers MUST comprise only ASCII
|
||||
// > 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;
|
||||
|
||||
// Per https://semver.org/#spec-item-10:
|
||||
//
|
||||
// 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;
|
||||
|
||||
// Per https://semver.org/#spec-item-9:
|
||||
//
|
||||
// https://semver.org/#spec-item-9
|
||||
// > Numeric identifiers MUST NOT include leading zeroes.
|
||||
const numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
|
||||
|
||||
/**
|
||||
* Describes a precise semantic version number, per https://semver.org
|
||||
* Describes a precise semantic version number, https://semver.org
|
||||
*/
|
||||
export class Version {
|
||||
static readonly zero = new Version(0);
|
||||
|
||||
readonly major: number;
|
||||
readonly minor: number;
|
||||
readonly patch: number;
|
||||
readonly prerelease: ReadonlyArray<string>;
|
||||
readonly build: ReadonlyArray<string>;
|
||||
|
||||
constructor(major: number, minor = 0, patch = 0, prerelease = "", build = "") {
|
||||
constructor(text: string);
|
||||
constructor(major: number, minor?: number, patch?: number, prerelease?: string, build?: string);
|
||||
constructor(major: number | string, minor = 0, patch = 0, prerelease = "", build = "") {
|
||||
if (typeof major === "string") {
|
||||
const result = Debug.assertDefined(tryParseComponents(major), "Invalid version");
|
||||
({ major, minor, patch, prerelease, build } = result);
|
||||
}
|
||||
|
||||
Debug.assert(major >= 0, "Invalid argument: major");
|
||||
Debug.assert(minor >= 0, "Invalid argument: minor");
|
||||
Debug.assert(patch >= 0, "Invalid argument: patch");
|
||||
@ -51,104 +52,102 @@ namespace ts {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.prerelease = prerelease === "" ? emptyArray : prerelease.split(".");
|
||||
this.build = build === "" ? emptyArray : build.split(".");
|
||||
}
|
||||
|
||||
static parse(text: string) {
|
||||
return Debug.assertDefined(this.tryParse(text));
|
||||
this.prerelease = prerelease ? prerelease.split(".") : emptyArray;
|
||||
this.build = build ? build.split(".") : emptyArray;
|
||||
}
|
||||
|
||||
static tryParse(text: string) {
|
||||
const match = versionRegExp.exec(text);
|
||||
if (!match) return undefined;
|
||||
const result = tryParseComponents(text);
|
||||
if (!result) return undefined;
|
||||
|
||||
const [, major, minor = 0, patch = 0, prerelease, build] = match;
|
||||
if (prerelease && !prereleaseRegExp.test(prerelease)) return undefined;
|
||||
if (build && !buildRegExp.test(build)) return undefined;
|
||||
return new Version(+major, +minor, +patch, prerelease, build);
|
||||
const { major, minor, patch, prerelease, build } = result;
|
||||
return new Version(major, minor, patch, prerelease, build);
|
||||
}
|
||||
|
||||
static compare(left: Version | undefined, right: Version | undefined, compareBuildMetadata?: boolean) {
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
compareTo(other: Version | undefined) {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence is determined by the first difference when comparing each of these
|
||||
// > identifiers from left to right as follows: Major, minor, and patch versions are
|
||||
// > always compared numerically.
|
||||
//
|
||||
// > When major, minor, and patch are equal, a pre-release version has lower
|
||||
// > precedence than a normal version.
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence for two pre-release versions with the same major, minor, and patch version
|
||||
// > MUST be determined by comparing each dot separated identifier from left to right until
|
||||
// > a difference is found [...]
|
||||
//
|
||||
// Per https://semver.org/#spec-item-10:
|
||||
//
|
||||
// > Build metadata SHOULD be ignored when determining version precedence.
|
||||
if (left === right) return Comparison.EqualTo;
|
||||
if (left === undefined) return Comparison.LessThan;
|
||||
if (right === undefined) return Comparison.GreaterThan;
|
||||
return compareValues(left.major, right.major)
|
||||
|| compareValues(left.minor, right.minor)
|
||||
|| compareValues(left.patch, right.patch)
|
||||
|| compareVersionFragments(left.prerelease, right.prerelease, /*compareNumericIdentifiers*/ true)
|
||||
|| (compareBuildMetadata ? compareVersionFragments(left.build, right.build, /*compareNumericIdentifiers*/ false) : Comparison.EqualTo);
|
||||
}
|
||||
|
||||
compareTo(other: Version, compareBuildMetadata?: boolean) {
|
||||
return Version.compare(this, other, compareBuildMetadata);
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Build metadata does not figure into precedence
|
||||
if (this === other) return Comparison.EqualTo;
|
||||
if (other === undefined) return Comparison.GreaterThan;
|
||||
return compareValues(this.major, other.major)
|
||||
|| compareValues(this.minor, other.minor)
|
||||
|| compareValues(this.patch, other.patch)
|
||||
|| comparePrerelaseIdentifiers(this.prerelease, other.prerelease);
|
||||
}
|
||||
|
||||
toString() {
|
||||
let result = `${this.major}.${this.minor}.${this.patch}`;
|
||||
if (this.prerelease) result += `-${this.prerelease.join(".")}`;
|
||||
if (this.build) result += `+${this.build.join(".")}`;
|
||||
if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`;
|
||||
if (some(this.build)) result += `+${this.build.join(".")}`;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function compareVersionFragments(left: ReadonlyArray<string>, right: ReadonlyArray<string>, compareNumericIdentifiers: boolean) {
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
function tryParseComponents(text: string) {
|
||||
const match = versionRegExp.exec(text);
|
||||
if (!match) return undefined;
|
||||
|
||||
const [, major, minor = "0", patch = "0", prerelease = "", build = ""] = match;
|
||||
if (prerelease && !prereleaseRegExp.test(prerelease)) return undefined;
|
||||
if (build && !buildRegExp.test(build)) return undefined;
|
||||
return {
|
||||
major: parseInt(major, 10),
|
||||
minor: parseInt(minor, 10),
|
||||
patch: parseInt(patch, 10),
|
||||
prerelease,
|
||||
build
|
||||
};
|
||||
}
|
||||
|
||||
function comparePrerelaseIdentifiers(left: ReadonlyArray<string>, right: ReadonlyArray<string>) {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > When major, minor, and patch are equal, a pre-release version has lower precedence
|
||||
// > than a normal version.
|
||||
if (left === right) return Comparison.EqualTo;
|
||||
if (left.length === 0) return right.length === 0 ? Comparison.EqualTo : Comparison.GreaterThan;
|
||||
if (right.length === 0) return Comparison.LessThan;
|
||||
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence for two pre-release versions with the same major, minor, and patch version
|
||||
// > MUST be determined by comparing each dot separated identifier from left to right until
|
||||
// > a difference is found
|
||||
// > a difference is found [...]
|
||||
const length = Math.min(left.length, right.length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
const leftIdentifier = left[i];
|
||||
const rightIdentifier = right[i];
|
||||
if (leftIdentifier === rightIdentifier) continue;
|
||||
|
||||
const leftIsNumeric = compareNumericIdentifiers && numericIdentifierRegExp.test(leftIdentifier);
|
||||
const rightIsNumeric = compareNumericIdentifiers && numericIdentifierRegExp.test(rightIdentifier);
|
||||
const leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier);
|
||||
const rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
|
||||
if (leftIsNumeric || rightIsNumeric) {
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Numeric identifiers always have lower precedence than non-numeric identifiers.
|
||||
if (leftIsNumeric !== rightIsNumeric) return leftIsNumeric ? Comparison.LessThan : Comparison.GreaterThan;
|
||||
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > identifiers consisting of only digits are compared numerically
|
||||
const result = compareValues(+leftIdentifier, +rightIdentifier);
|
||||
if (result) return result;
|
||||
}
|
||||
else {
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > identifiers with letters or hyphens are compared lexically in ASCII sort order.
|
||||
const result = compareStringsCaseSensitive(leftIdentifier, rightIdentifier);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Per https://semver.org/#spec-item-11:
|
||||
//
|
||||
// https://semver.org/#spec-item-11
|
||||
// > A larger set of pre-release fields has a higher precedence than a smaller set, if all
|
||||
// > of the preceding identifiers are equal.
|
||||
return compareValues(left.length, right.length);
|
||||
|
||||
@ -21,13 +21,13 @@ namespace ts.JsTyping {
|
||||
|
||||
export interface CachedTyping {
|
||||
typingLocation: string;
|
||||
version: Semver;
|
||||
version: Version;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike<string>) {
|
||||
const availableVersion = Semver.parse(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
|
||||
return !availableVersion.greaterThan(cachedTyping.version);
|
||||
const availableVersion = new Version(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!);
|
||||
return availableVersion.compareTo(cachedTyping.version) <= 0;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
function stringToInt(str: string): number {
|
||||
const n = parseInt(str, 10);
|
||||
if (isNaN(n)) {
|
||||
throw new Error(`Error in parseInt(${JSON.stringify(str)})`);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const isPrereleaseRegex = /^(.*)-next.\d+/;
|
||||
const prereleaseSemverRegex = /^(\d+)\.(\d+)\.0-next.(\d+)$/;
|
||||
const semverRegex = /^(\d+)\.(\d+)\.(\d+)$/;
|
||||
|
||||
export class Semver {
|
||||
static parse(semver: string): Semver {
|
||||
const isPrerelease = isPrereleaseRegex.test(semver);
|
||||
const result = Semver.tryParse(semver, isPrerelease);
|
||||
if (!result) {
|
||||
throw new Error(`Unexpected semver: ${semver} (isPrerelease: ${isPrerelease})`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static fromRaw({ major, minor, patch, isPrerelease }: Semver): Semver {
|
||||
return new Semver(major, minor, patch, isPrerelease);
|
||||
}
|
||||
|
||||
// This must parse the output of `versionString`.
|
||||
private static tryParse(semver: string, isPrerelease: boolean): Semver | undefined {
|
||||
// Per the semver spec <http://semver.org/#spec-item-2>:
|
||||
// "A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers, and MUST NOT contain leading zeroes."
|
||||
const rgx = isPrerelease ? prereleaseSemverRegex : semverRegex;
|
||||
const match = rgx.exec(semver);
|
||||
return match ? new Semver(stringToInt(match[1]), stringToInt(match[2]), stringToInt(match[3]), isPrerelease) : undefined;
|
||||
}
|
||||
|
||||
private constructor(
|
||||
readonly major: number, readonly minor: number, readonly patch: number,
|
||||
/**
|
||||
* If true, this is `major.minor.0-next.patch`.
|
||||
* If false, this is `major.minor.patch`.
|
||||
*/
|
||||
readonly isPrerelease: boolean) { }
|
||||
|
||||
get versionString(): string {
|
||||
return this.isPrerelease ? `${this.major}.${this.minor}.0-next.${this.patch}` : `${this.major}.${this.minor}.${this.patch}`;
|
||||
}
|
||||
|
||||
equals(sem: Semver): boolean {
|
||||
return this.major === sem.major && this.minor === sem.minor && this.patch === sem.patch && this.isPrerelease === sem.isPrerelease;
|
||||
}
|
||||
|
||||
greaterThan(sem: Semver): boolean {
|
||||
return this.major > sem.major || this.major === sem.major
|
||||
&& (this.minor > sem.minor || this.minor === sem.minor
|
||||
&& (!this.isPrerelease && sem.isPrerelease || this.isPrerelease === sem.isPrerelease
|
||||
&& this.patch > sem.patch));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,6 @@
|
||||
"files": [
|
||||
"shared.ts",
|
||||
"types.ts",
|
||||
"jsTyping.ts",
|
||||
"semver.ts"
|
||||
"jsTyping.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -73,6 +73,7 @@
|
||||
"unittests/publicApi.ts",
|
||||
"unittests/reuseProgramStructure.ts",
|
||||
"unittests/session.ts",
|
||||
"unittests/semver.ts",
|
||||
"unittests/symbolWalker.ts",
|
||||
"unittests/telemetry.ts",
|
||||
"unittests/textChanges.ts",
|
||||
|
||||
94
src/testRunner/unittests/semver.ts
Normal file
94
src/testRunner/unittests/semver.ts
Normal file
@ -0,0 +1,94 @@
|
||||
namespace ts {
|
||||
describe("semver", () => {
|
||||
describe("Version", () => {
|
||||
function assertVersion(version: Version, [major, minor, patch, prerelease, build]: [number, number, number, string[]?, string[]?]) {
|
||||
assert.strictEqual(version.major, major);
|
||||
assert.strictEqual(version.minor, minor);
|
||||
assert.strictEqual(version.patch, patch);
|
||||
assert.deepEqual(version.prerelease, prerelease || emptyArray);
|
||||
assert.deepEqual(version.build, build || emptyArray);
|
||||
}
|
||||
describe("new", () => {
|
||||
it("text", () => {
|
||||
assertVersion(new Version("1.2.3-pre.4+build.5"), [1, 2, 3, ["pre", "4"], ["build", "5"]]);
|
||||
});
|
||||
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), [1, 2, 3]);
|
||||
assertVersion(new Version(1, 2), [1, 2, 0]);
|
||||
assertVersion(new Version(1), [1, 0, 0]);
|
||||
});
|
||||
});
|
||||
it("toString", () => {
|
||||
assert.strictEqual(new Version(1, 2, 3, "pre.4", "build.5").toString(), "1.2.3-pre.4+build.5");
|
||||
assert.strictEqual(new Version(1, 2, 3, "pre.4").toString(), "1.2.3-pre.4");
|
||||
assert.strictEqual(new Version(1, 2, 3, /*prerelease*/ undefined, "build.5").toString(), "1.2.3+build.5");
|
||||
assert.strictEqual(new Version(1, 2, 3).toString(), "1.2.3");
|
||||
assert.strictEqual(new Version(1, 2).toString(), "1.2.0");
|
||||
assert.strictEqual(new Version(1).toString(), "1.0.0");
|
||||
});
|
||||
it("compareTo", () => {
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence is determined by the first difference when comparing each of these
|
||||
// > identifiers from left to right as follows: Major, minor, and patch versions are
|
||||
// > always compared numerically.
|
||||
assert.strictEqual(new Version("1.0.0").compareTo(new Version("2.0.0")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.1.0")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.1")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("2.0.0").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.1.0").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.1").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.0")), Comparison.EqualTo);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > When major, minor, and patch are equal, a pre-release version has lower
|
||||
// > precedence than a normal version.
|
||||
assert.strictEqual(new Version("1.0.0").compareTo(new Version("1.0.0-pre")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.1-pre").compareTo(new Version("1.0.0")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-pre").compareTo(new Version("1.0.0")), Comparison.LessThan);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > identifiers consisting of only digits are compared numerically
|
||||
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-1")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-1").compareTo(new Version("1.0.0-0")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-2").compareTo(new Version("1.0.0-10")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-10").compareTo(new Version("1.0.0-2")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-0")), Comparison.EqualTo);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > identifiers with letters or hyphens are compared lexically in ASCII sort order.
|
||||
assert.strictEqual(new Version("1.0.0-a").compareTo(new Version("1.0.0-b")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-a-2").compareTo(new Version("1.0.0-a-10")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-b").compareTo(new Version("1.0.0-a")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-a").compareTo(new Version("1.0.0-a")), Comparison.EqualTo);
|
||||
assert.strictEqual(new Version("1.0.0-A").compareTo(new Version("1.0.0-a")), Comparison.LessThan);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Numeric identifiers always have lower precedence than non-numeric identifiers.
|
||||
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-alpha")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-0")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-0").compareTo(new Version("1.0.0-0")), Comparison.EqualTo);
|
||||
assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-alpha")), Comparison.EqualTo);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > A larger set of pre-release fields has a higher precedence than a smaller set, if all
|
||||
// > of the preceding identifiers are equal.
|
||||
assert.strictEqual(new Version("1.0.0-alpha").compareTo(new Version("1.0.0-alpha.0")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-alpha.0").compareTo(new Version("1.0.0-alpha")), Comparison.GreaterThan);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Precedence for two pre-release versions with the same major, minor, and patch version
|
||||
// > MUST be determined by comparing each dot separated identifier from left to right until
|
||||
// > a difference is found [...]
|
||||
assert.strictEqual(new Version("1.0.0-a.0.b.1").compareTo(new Version("1.0.0-a.0.b.2")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-a.0.b.1").compareTo(new Version("1.0.0-b.0.a.1")), Comparison.LessThan);
|
||||
assert.strictEqual(new Version("1.0.0-a.0.b.2").compareTo(new Version("1.0.0-a.0.b.1")), Comparison.GreaterThan);
|
||||
assert.strictEqual(new Version("1.0.0-b.0.a.1").compareTo(new Version("1.0.0-a.0.b.1")), Comparison.GreaterThan);
|
||||
|
||||
// https://semver.org/#spec-item-11
|
||||
// > Build metadata does not figure into precedence
|
||||
assert.strictEqual(new Version("1.0.0+build").compareTo(new Version("1.0.0")), Comparison.EqualTo);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -1322,7 +1322,7 @@ namespace ts.projectSystem {
|
||||
content: ""
|
||||
};
|
||||
const host = createServerHost([f, node]);
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: Semver.parse("1.3.0") } });
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: new Version("1.3.0") } });
|
||||
const registry = createTypesRegistry("node");
|
||||
const logger = trackingLogger();
|
||||
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], registry);
|
||||
@ -1344,7 +1344,7 @@ namespace ts.projectSystem {
|
||||
content: ""
|
||||
};
|
||||
const host = createServerHost([f, node]);
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: Semver.parse("1.3.0") } });
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({ node: { typingLocation: node.path, version: new Version("1.3.0") } });
|
||||
const logger = trackingLogger();
|
||||
const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(<Path>f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], emptyMap);
|
||||
assert.deepEqual(logger.finish(), [
|
||||
@ -1401,8 +1401,8 @@ namespace ts.projectSystem {
|
||||
};
|
||||
const host = createServerHost([app]);
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({
|
||||
node: { typingLocation: node.path, version: Semver.parse("1.3.0") },
|
||||
commander: { typingLocation: commander.path, version: Semver.parse("1.0.0") }
|
||||
node: { typingLocation: node.path, version: new Version("1.3.0") },
|
||||
commander: { typingLocation: commander.path, version: new Version("1.0.0") }
|
||||
});
|
||||
const registry = createTypesRegistry("node", "commander");
|
||||
const logger = trackingLogger();
|
||||
@ -1427,7 +1427,7 @@ namespace ts.projectSystem {
|
||||
};
|
||||
const host = createServerHost([app]);
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({
|
||||
node: { typingLocation: node.path, version: Semver.parse("1.0.0") }
|
||||
node: { typingLocation: node.path, version: new Version("1.0.0") }
|
||||
});
|
||||
const registry = createTypesRegistry("node");
|
||||
registry.delete(`ts${versionMajorMinor}`);
|
||||
@ -1458,8 +1458,8 @@ namespace ts.projectSystem {
|
||||
};
|
||||
const host = createServerHost([app]);
|
||||
const cache = createMapFromTemplate<JsTyping.CachedTyping>({
|
||||
node: { typingLocation: node.path, version: Semver.parse("1.3.0-next.0") },
|
||||
commander: { typingLocation: commander.path, version: Semver.parse("1.3.0-next.0") }
|
||||
node: { typingLocation: node.path, version: new Version("1.3.0-next.0") },
|
||||
commander: { typingLocation: commander.path, version: new Version("1.3.0-next.0") }
|
||||
});
|
||||
const registry = createTypesRegistry("node", "commander");
|
||||
registry.get("node")![`ts${versionMajorMinor}`] = "1.3.0-next.1";
|
||||
|
||||
@ -252,8 +252,11 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
const info = getProperty(npmLock.dependencies, key);
|
||||
const version = info && info.version;
|
||||
const semver = Semver.parse(version!); // TODO: GH#18217
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: semver };
|
||||
if (!version) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: new Version(version) };
|
||||
this.packageNameToTypingLocation.set(packageName, newTyping);
|
||||
}
|
||||
}
|
||||
@ -356,7 +359,7 @@ namespace ts.server.typingsInstaller {
|
||||
|
||||
// packageName is guaranteed to exist in typesRegistry by filterTypings
|
||||
const distTags = this.typesRegistry.get(packageName)!;
|
||||
const newVersion = Semver.parse(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]);
|
||||
const newVersion = new Version(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]);
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion };
|
||||
this.packageNameToTypingLocation.set(packageName, newTyping);
|
||||
installedTypingFiles.push(typingFile);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"======== Resolving module 'ext' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' does not have a 'typings' field.",
|
||||
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.",
|
||||
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/index.d.ts@1.0.0'.",
|
||||
@ -21,7 +21,7 @@
|
||||
"======== Resolving module 'ext/other' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.",
|
||||
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.ts' does not exist.",
|
||||
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.tsx' does not exist.",
|
||||
@ -33,7 +33,7 @@
|
||||
"Directory 'node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Loading module 'ext/other' from 'node_modules' folder, target file type 'JavaScript'.",
|
||||
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.",
|
||||
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.js' does not exist.",
|
||||
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.jsx' does not exist.",
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"======== Resolving module 'ext' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' does not have a 'typings' field.",
|
||||
"'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.",
|
||||
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/index.d.ts@1.0.0'.",
|
||||
@ -21,7 +21,7 @@
|
||||
"======== Resolving module 'ext/other' from 'tests/cases/conformance/moduleResolution/main.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'NodeJs'.",
|
||||
"Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"'package.json' has 'typesVersion['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.",
|
||||
"Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.",
|
||||
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.ts' does not exist.",
|
||||
"File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.tsx' does not exist.",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user