From 7397fb11c4cbc651a2d0be5180a003fecd46716e Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 19 Jan 2018 14:10:06 -0800 Subject: [PATCH] Fix lint and test errors and add tests --- src/harness/unittests/typingsInstaller.ts | 64 ++++++++++++++++++- .../typingsInstaller/typingsInstaller.ts | 4 +- src/services/semver.ts | 2 +- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 33f3544bde8..b5265c5e5f2 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -1300,7 +1300,7 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f, node]); - const cache = createMapFromTemplate({ node: { typingLocation: node.path, version: new Semver(1, 3, 0, /*isPrerelease*/ false) } }); + const cache = createMapFromTemplate({ node: { typingLocation: node.path, version: Semver.parse("1.3.0") } }); const registry = createTypesRegistry("node"); const logger = trackingLogger(); const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], registry); @@ -1358,8 +1358,8 @@ namespace ts.projectSystem { }; const host = createServerHost([app]); const cache = createMapFromTemplate({ - node: { typingLocation: node.path, version: new Semver(1, 3, 0, /*isPrerelease*/ false) }, - commander: { typingLocation: commander.path, version: new Semver(1, 0, 0, /*isPrerelease*/ false) } + node: { typingLocation: node.path, version: Semver.parse("1.3.0") }, + commander: { typingLocation: commander.path, version: Semver.parse("1.0.0") } }); const registry = createTypesRegistry("node", "commander"); const logger = trackingLogger(); @@ -1371,6 +1371,64 @@ namespace ts.projectSystem { assert.deepEqual(result.cachedTypingPaths, [node.path]); assert.deepEqual(result.newTypingNames, ["commander"]); }); + + it("should install expired typings with prerelease version of tsserver", () => { + const app = { + path: "/a/app.js", + content: "" + }; + const cachePath = "/a/cache/"; + const node = { + path: cachePath + "node_modules/@types/node/index.d.ts", + content: "export let y: number" + }; + const host = createServerHost([app]); + const cache = createMapFromTemplate({ + node: { typingLocation: node.path, version: Semver.parse("1.0.0") } + }); + const registry = createTypesRegistry("node"); + registry.delete(`ts${ts.versionMajorMinor}`); + const logger = trackingLogger(); + const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(app.path), emptySafeList, cache, { enable: true }, ["http"], registry); + assert.deepEqual(logger.finish(), [ + 'Inferred typings from unresolved imports: ["node"]', + 'Result: {"cachedTypingPaths":[],"newTypingNames":["node"],"filesToWatch":["/a/bower_components","/a/node_modules"]}', + ]); + assert.deepEqual(result.cachedTypingPaths, []); + assert.deepEqual(result.newTypingNames, ["node"]); + }); + + + it("prerelease typings are properly handled", () => { + const app = { + path: "/a/app.js", + content: "" + }; + const cachePath = "/a/cache/"; + const commander = { + path: cachePath + "node_modules/@types/commander/index.d.ts", + content: "export let x: number" + }; + const node = { + path: cachePath + "node_modules/@types/node/index.d.ts", + content: "export let y: number" + }; + const host = createServerHost([app]); + const cache = createMapFromTemplate({ + node: { typingLocation: node.path, version: Semver.parse("1.3.0-next.0") }, + commander: { typingLocation: commander.path, version: Semver.parse("1.3.0-next.0") } + }); + const registry = createTypesRegistry("node", "commander"); + registry.get("node")[`ts${ts.versionMajorMinor}`] = "1.3.0-next.1"; + const logger = trackingLogger(); + const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(app.path), emptySafeList, cache, { enable: true }, ["http", "commander"], registry); + assert.deepEqual(logger.finish(), [ + 'Inferred typings from unresolved imports: ["node","commander"]', + 'Result: {"cachedTypingPaths":[],"newTypingNames":["node","commander"],"filesToWatch":["/a/bower_components","/a/node_modules"]}', + ]); + assert.deepEqual(result.cachedTypingPaths, []); + assert.deepEqual(result.newTypingNames, ["node", "commander"]); + }); }); describe("telemetry events", () => { diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index fa31384a453..09c0e76e8d0 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -311,7 +311,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${ts.versionMajorMinor}`] || distTags["latest"]); + const newVersion = Semver.parse(distTags[`ts${ts.versionMajorMinor}`] || distTags[latestDistTag]); const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion }; this.packageNameToTypingLocation.set(packageName, newTyping); installedTypingFiles.push(typingFile); @@ -407,4 +407,6 @@ namespace ts.server.typingsInstaller { export function typingsName(packageName: string): string { return `@types/${packageName}@ts${versionMajorMinor}`; } + + const latestDistTag = "latest"; } \ No newline at end of file diff --git a/src/services/semver.ts b/src/services/semver.ts index b16d6041529..3415ff9176f 100644 --- a/src/services/semver.ts +++ b/src/services/semver.ts @@ -23,7 +23,7 @@ namespace ts { } // This must parse the output of `versionString`. - static tryParse(semver: string, isPrerelease: boolean): Semver | undefined { + private static tryParse(semver: string, isPrerelease: boolean): Semver | undefined { // Per the semver spec : // "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 ? /^(\d+)\.(\d+)\.0-next.(\d+)$/ : /^(\d+)\.(\d+)\.(\d+)$/;