Skip to content

Commit ddaf1c7

Browse files
committed
Add test where source file as well as module resolution cache is shared with change in effective type roots
1 parent 9cbcf01 commit ddaf1c7

10 files changed

+1186
-13
lines changed

src/testRunner/tests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ import "./unittests/tsbuild/resolveJsonModule";
9595
import "./unittests/tsbuild/roots";
9696
import "./unittests/tsbuild/sample";
9797
import "./unittests/tsbuild/transitiveReferences";
98+
import "./unittests/tsbuild/typeReferenceDirectives";
9899
import "./unittests/tsbuildWatch/configFileErrors";
99100
import "./unittests/tsbuildWatch/demo";
100101
import "./unittests/tsbuildWatch/libraryResolution";

src/testRunner/unittests/helpers/tsserver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ function patchHostTimeouts(
489489
export interface TestSessionOptions extends ts.server.SessionOptions {
490490
logger: Logger;
491491
allowNonBaseliningLogger?: boolean;
492+
disableAutomaticTypingAcquisition?: boolean;
492493
}
493494

494495
export type TestSessionRequest<T extends ts.server.protocol.Request> = Pick<T, "command" | "arguments">;
@@ -543,7 +544,7 @@ export class TestSession extends ts.server.Session {
543544

544545
export function createSession(host: TestServerHost, opts: Partial<TestSessionOptions> = {}) {
545546
const logger = opts.logger || createHasErrorMessageLogger();
546-
if (opts.typingsInstaller === undefined) {
547+
if (!opts.disableAutomaticTypingAcquisition && opts.typingsInstaller === undefined) {
547548
opts.typingsInstaller = new TestTypingsInstaller(host.getHostSpecificPath("/a/data/"), /*throttleLimit*/ 5, host, logger);
548549
}
549550

@@ -556,7 +557,6 @@ export function createSession(host: TestServerHost, opts: Partial<TestSessionOpt
556557
cancellationToken: ts.server.nullCancellationToken,
557558
useSingleInferredProject: false,
558559
useInferredProjectPerProjectRoot: false,
559-
typingsInstaller: undefined!, // TODO: GH#18217
560560
byteLength: Buffer.byteLength,
561561
hrtime: process.hrtime,
562562
logger,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {
2+
dedent,
3+
} from "../../_namespaces/Utils";
4+
import {
5+
verifyTsc,
6+
} from "../helpers/tsc";
7+
import {
8+
appendText,
9+
loadProjectFromFiles,
10+
} from "../helpers/vfs";
11+
12+
describe("unittests:: tsbuild:: typeReferenceDirectives::", () => {
13+
verifyTsc({
14+
scenario: "typeReferenceDirectives",
15+
subScenario: `effective type roots affect module resolution`,
16+
fs: () =>
17+
loadProjectFromFiles({
18+
"/users/username/projects/replay/axios-src/test/module/ts-require/tsconfig.json": JSON.stringify({
19+
compilerOptions: { incremental: true },
20+
}),
21+
"/users/username/projects/replay/axios-src/test/module/ts-require/index.ts": dedent`
22+
export const a = 10;
23+
`,
24+
"/users/username/projects/replay/axios-src/test/module/ts-require/node_modules/@types/node/index.d.ts": dedent`
25+
declare const tsRequireGlobal = 10;
26+
`,
27+
"/users/username/projects/replay/axios-src/node_modules/@types/responselike/index.d.ts": dedent`
28+
/// <reference types="node" />
29+
export const z = 10;
30+
`,
31+
"/users/username/projects/replay/axios-src/test/module/ts/tsconfig.json": JSON.stringify({
32+
compilerOptions: { incremental: true },
33+
}),
34+
"/users/username/projects/replay/axios-src/test/module/ts/index.ts": dedent`
35+
export const y = 10;
36+
`,
37+
"/users/username/projects/replay/axios-src/test/module/ts/node_modules/@types/node/index.d.ts": dedent`
38+
declare const tsGlobal = 10;
39+
`,
40+
}, { cwd: "/users/username/projects/replay/axios-src" }),
41+
commandLineArgs: ["-b", "test/module/ts-require", "test/module/ts", "--verbose", "--traceResolution", "--explainFiles"],
42+
edits: [{
43+
caption: "build ts project with edit",
44+
edit: fs => appendText(fs, "/users/username/projects/replay/axios-src/test/module/ts/index.ts", `export const z = 10;`),
45+
}],
46+
});
47+
});

src/testRunner/unittests/tsserver/resolutionCache.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem with pr
634634
compilerOptions: compilerOptionsToConfigJson({
635635
composite: true,
636636
traceResolution: true,
637+
typeRoots: [],
637638
}),
638639
}),
639640
"/users/username/projects/common/moduleA.ts": "export const a = 10;",
@@ -645,6 +646,7 @@ describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem with pr
645646
compilerOptions: compilerOptionsToConfigJson({
646647
composite: true,
647648
traceResolution: true,
649+
typeRoots: [],
648650
}),
649651
references: [{ path: "../common" }],
650652
}),
@@ -662,6 +664,41 @@ describe("unittests:: tsserver:: resolutionCache:: tsserverProjectSystem with pr
662664
baselineTsserverLogs("resolutionCache", "sharing across references", session);
663665
});
664666

667+
it("not sharing across references because typeRoots are not specified and config directories are different", () => {
668+
const host = createServerHost({
669+
"/users/username/projects/node_modules/moduleX/index.d.ts": "export const x = 10;",
670+
"/users/username/projects/common/tsconfig.json": JSON.stringify({
671+
compilerOptions: compilerOptionsToConfigJson({
672+
composite: true,
673+
traceResolution: true,
674+
}),
675+
}),
676+
"/users/username/projects/common/moduleA.ts": "export const a = 10;",
677+
"/users/username/projects/common/moduleB.ts": Utils.dedent`
678+
import { x } from "moduleX";
679+
export const b = x;
680+
`,
681+
"/users/username/projects/app/tsconfig.json": JSON.stringify({
682+
compilerOptions: compilerOptionsToConfigJson({
683+
composite: true,
684+
traceResolution: true,
685+
}),
686+
references: [{ path: "../common" }],
687+
}),
688+
"/users/username/projects/app/appA.ts": Utils.dedent`
689+
import { x } from "moduleX";
690+
export const y = x;
691+
`,
692+
"/users/username/projects/app/appB.ts": Utils.dedent`
693+
import { x } from "../common/moduleB";
694+
export const y = x;
695+
`,
696+
});
697+
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
698+
openFilesForSession(["/users/username/projects/app/appB.ts"], session);
699+
baselineTsserverLogs("resolutionCache", "not sharing across references because typeRoots are not specified and config directories are different", session);
700+
});
701+
665702
it("not sharing across references", () => {
666703
const host = createServerHost({
667704
"/users/username/projects/node_modules/moduleX/index.d.ts": "export const x = 10;",

src/testRunner/unittests/tsserver/typeReferenceDirectives.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import * as ts from "../../_namespaces/ts";
2+
import {
3+
dedent,
4+
} from "../../_namespaces/Utils";
15
import {
26
baselineTsserverLogs,
37
createLoggerWithInMemoryLogs,
@@ -10,7 +14,7 @@ import {
1014
libFile,
1115
} from "../helpers/virtualFileSystemWithWatch";
1216

13-
describe("unittests:: tsserver:: typeReferenceDirectives", () => {
17+
describe("unittests:: tsserver:: typeReferenceDirectives::", () => {
1418
it("when typeReferenceDirective contains UpperCasePackage", () => {
1519
const libProjectLocation = `/user/username/projects/myproject/lib`;
1620
const typeLib: File = {
@@ -91,4 +95,56 @@ declare class TestLib {
9195
openFilesForSession([file], session);
9296
baselineTsserverLogs("typeReferenceDirectives", "when typeReferenceDirective is relative path and in a sibling folder", session);
9397
});
98+
99+
it("typeReferenceDirective of shared auto type file in two projects with same options", () => {
100+
const host = createServerHost({
101+
"/users/username/projects/replay/axios-src/test/module/ts-require/index.js": dedent`
102+
export const a = 10;
103+
104+
`,
105+
"/users/username/projects/replay/axios-src/test/module/ts-require/node_modules/@types/node/index.d.ts": dedent`
106+
export const x = 10;
107+
`,
108+
"/users/username/projects/replay/axios-src/node_modules/@types/responselike/index.d.ts": dedent`
109+
/// <reference types="node" />
110+
export const z = 10;
111+
`,
112+
"/users/username/projects/replay/axios-src/test/module/ts/index.js": dedent`
113+
export const y = 10;
114+
`,
115+
"/users/username/projects/replay/axios-src/test/module/ts/node_modules/@types/node/index.d.ts": dedent`
116+
export const x = 10;
117+
`,
118+
});
119+
const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host), disableAutomaticTypingAcquisition: true });
120+
// This will add responselike/index.d.ts and resolve the type ref "node" to "test/module/ts-require/node_modules/@types/node/index.d.ts" because of current directory
121+
openFilesForSession(["/users/username/projects/replay/axios-src/test/module/ts-require/index.js"], session);
122+
session.executeCommandSeq<ts.server.protocol.UpdateOpenRequest>({ // Schedule update
123+
command: ts.server.protocol.CommandTypes.UpdateOpen,
124+
arguments: {
125+
changedFiles: [{
126+
fileName: "/users/username/projects/replay/axios-src/test/module/ts-require/index.js",
127+
textChanges: [{
128+
newText: "//comment",
129+
start: { line: 2, offset: 1 },
130+
end: { line: 2, offset: 1 },
131+
}],
132+
}],
133+
},
134+
});
135+
// This will add responselike/index.d.ts - which is same sourceFile as from previous project and update the typeRef "node" to "test/module/ts/node_modules/@types/node/index.d.ts" because of current directory
136+
openFilesForSession(["/users/username/projects/replay/axios-src/test/module/ts/index.js"], session);
137+
const firstProjectSourceFile = session.getProjectService().inferredProjects[0].getCurrentProgram()!.getSourceFile("/users/username/projects/replay/axios-src/node_modules/@types/responselike/index.d.ts");
138+
const secondProjectSourceFile = session.getProjectService().inferredProjects[1].getCurrentProgram()!.getSourceFile("/users/username/projects/replay/axios-src/node_modules/@types/responselike/index.d.ts");
139+
assert.isTrue(firstProjectSourceFile === secondProjectSourceFile, "Source file would be same in both projects even though resolutions will not be");
140+
// So when first project is updated as part of this command, it will get incorrect type ref resolution from the other project
141+
session.executeCommandSeq<ts.server.protocol.NavtoRequest>({
142+
command: ts.server.protocol.CommandTypes.Navto,
143+
arguments: {
144+
searchValue: "a",
145+
maxResultCount: 256,
146+
},
147+
});
148+
baselineTsserverLogs("typeReferenceDirectives", "typeReferenceDirective of shared auto type file in two projects with same options", session);
149+
});
94150
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
0:: build ts project with edit
2+
*** Needs explanation
3+
TsBuild info text without affectedFilesPendingEmit:: /users/username/projects/replay/axios-src/test/module/ts/tsconfig.tsbuildinfo.readable.baseline.txt::
4+
CleanBuild:
5+
{
6+
"program": {
7+
"fileInfos": {
8+
"../../../../../../../../lib/lib.d.ts": {
9+
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
10+
"affectsGlobalScope": true
11+
},
12+
"./index.ts": {
13+
"version": "-14419396410-export const y = 10;\nexport const z = 10;"
14+
},
15+
"./node_modules/@types/node/index.d.ts": {
16+
"version": "-7116520553-declare const tsGlobal = 10;\n",
17+
"affectsGlobalScope": true
18+
},
19+
"../../../node_modules/@types/responselike/index.d.ts": {
20+
"version": "4670743798-/// <reference types=\"node\" />\nexport const z = 10;\n"
21+
}
22+
},
23+
"root": [
24+
[
25+
2,
26+
"./index.ts"
27+
]
28+
],
29+
"referencedMap": {
30+
"../../../node_modules/@types/responselike/index.d.ts": [
31+
"../ts-require/node_modules/@types/node/index.d.ts"
32+
]
33+
},
34+
"semanticDiagnosticsPerFile": [
35+
"../../../../../../../../lib/lib.d.ts",
36+
"../../../node_modules/@types/responselike/index.d.ts",
37+
"./index.ts",
38+
"./node_modules/@types/node/index.d.ts"
39+
],
40+
"options": {}
41+
},
42+
"version": "FakeTSVersion"
43+
}
44+
IncrementalBuild:
45+
{
46+
"program": {
47+
"fileInfos": {
48+
"../../../../../../../../lib/lib.d.ts": {
49+
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
50+
"affectsGlobalScope": true
51+
},
52+
"./index.ts": {
53+
"version": "-14419396410-export const y = 10;\nexport const z = 10;"
54+
},
55+
"./node_modules/@types/node/index.d.ts": {
56+
"version": "-7116520553-declare const tsGlobal = 10;\n",
57+
"affectsGlobalScope": true
58+
},
59+
"../../../node_modules/@types/responselike/index.d.ts": {
60+
"version": "4670743798-/// <reference types=\"node\" />\nexport const z = 10;\n"
61+
}
62+
},
63+
"root": [
64+
[
65+
2,
66+
"./index.ts"
67+
]
68+
],
69+
"referencedMap": {
70+
"../../../node_modules/@types/responselike/index.d.ts": [
71+
"./node_modules/@types/node/index.d.ts"
72+
]
73+
},
74+
"semanticDiagnosticsPerFile": [
75+
"../../../../../../../../lib/lib.d.ts",
76+
"../../../node_modules/@types/responselike/index.d.ts",
77+
"./index.ts",
78+
"./node_modules/@types/node/index.d.ts"
79+
],
80+
"options": {}
81+
},
82+
"version": "FakeTSVersion"
83+
}

0 commit comments

Comments
 (0)