• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: Semantic operations on Syntax server", () => {
3        function setup() {
4            const file1: File = {
5                path: `${tscWatch.projectRoot}/a.ts`,
6                content: `import { y, cc } from "./b";
7import { something } from "something";
8class c { prop = "hello"; foo() { return this.prop; } }`
9            };
10            const file2: File = {
11                path: `${tscWatch.projectRoot}/b.ts`,
12                content: `export { cc } from "./c";
13import { something } from "something";
14                export const y = 10;`
15            };
16            const file3: File = {
17                path: `${tscWatch.projectRoot}/c.ts`,
18                content: `export const cc = 10;`
19            };
20            const something: File = {
21                path: `${tscWatch.projectRoot}/node_modules/something/index.d.ts`,
22                content: "export const something = 10;"
23            };
24            const configFile: File = {
25                path: `${tscWatch.projectRoot}/tsconfig.json`,
26                content: "{}"
27            };
28            const host = createServerHost([file1, file2, file3, something, libFile, configFile]);
29            const session = createSession(host, { syntaxOnly: true, useSingleInferredProject: true, logger: createLoggerWithInMemoryLogs(host) });
30            return { host, session, file1, file2, file3, something, configFile };
31        }
32
33        function verifySessionException<T extends server.protocol.Request>(session: TestSession, request: Partial<T>) {
34            try {
35                session.executeCommandSeq(request);
36            }
37            catch (e) {
38                session.logger.info(e.message);
39            }
40        }
41
42        it("open files are added to inferred project even if config file is present and semantic operations fail", () => {
43            const { session, file1, file2, file3, something } = setup();
44            openFilesForSession([file1], session);
45            verifyCompletions();
46            verifyGoToDefToB();
47
48            openFilesForSession([file2], session);
49            verifyCompletions();
50            verifyGoToDefToB();
51            verifyGoToDefToC();
52
53            openFilesForSession([file3], session);
54            openFilesForSession([something], session);
55
56            // Close open files and verify resolutions
57            closeFilesForSession([file3], session);
58            closeFilesForSession([file2], session);
59
60            baselineTsserverLogs("syntacticServer", "files go to inferred project and semantic operations fail", session);
61
62            function verifyCompletions() {
63                verifySessionException<protocol.CompletionsRequest>(session, {
64                    command: protocol.CommandTypes.Completions,
65                    arguments: protocolFileLocationFromSubstring(file1, "prop", { index: 1 })
66                });
67            }
68
69            function verifyGoToDefToB() {
70                verifySessionException<protocol.DefinitionAndBoundSpanRequest>(session, {
71                    command: protocol.CommandTypes.DefinitionAndBoundSpan,
72                    arguments: protocolFileLocationFromSubstring(file1, "y")
73                });
74            }
75
76            function verifyGoToDefToC() {
77                verifySessionException<protocol.DefinitionAndBoundSpanRequest>(session, {
78                    command: protocol.CommandTypes.DefinitionAndBoundSpan,
79                    arguments: protocolFileLocationFromSubstring(file1, "cc")
80                });
81            }
82        });
83
84        it("throws on unsupported commands", () => {
85            const { session, file1 } = setup();
86            const service = session.getProjectService();
87            openFilesForSession([file1], session);
88            verifySessionException<protocol.SemanticDiagnosticsSyncRequest>(session, {
89                type: "request",
90                seq: 1,
91                command: protocol.CommandTypes.SemanticDiagnosticsSync,
92                arguments: { file: file1.path }
93            });
94
95            const project = service.inferredProjects[0];
96            try {
97                project.getLanguageService().getSemanticDiagnostics(file1.path);
98            }
99            catch (e) {
100                session.logger.info(e.message);
101            }
102            baselineTsserverLogs("syntacticServer", "throws on unsupported commands", session);
103        });
104
105        it("should not include auto type reference directives", () => {
106            const { host, session, file1 } = setup();
107            const atTypes: File = {
108                path: `/node_modules/@types/somemodule/index.d.ts`,
109                content: "export const something = 10;"
110            };
111            host.ensureFileOrFolder(atTypes);
112            openFilesForSession([file1], session);
113            baselineTsserverLogs("syntacticServer", "should not include auto type reference directives", session);
114        });
115
116        it("should not include referenced files from unopened files", () => {
117            const file1: File = {
118                path: `${tscWatch.projectRoot}/a.ts`,
119                content: `///<reference path="b.ts"/>
120///<reference path="${tscWatch.projectRoot}/node_modules/something/index.d.ts"/>
121function fooA() { }`
122            };
123            const file2: File = {
124                path: `${tscWatch.projectRoot}/b.ts`,
125                content: `///<reference path="./c.ts"/>
126///<reference path="${tscWatch.projectRoot}/node_modules/something/index.d.ts"/>
127function fooB() { }`
128            };
129            const file3: File = {
130                path: `${tscWatch.projectRoot}/c.ts`,
131                content: `function fooC() { }`
132            };
133            const something: File = {
134                path: `${tscWatch.projectRoot}/node_modules/something/index.d.ts`,
135                content: "function something() {}"
136            };
137            const configFile: File = {
138                path: `${tscWatch.projectRoot}/tsconfig.json`,
139                content: "{}"
140            };
141            const host = createServerHost([file1, file2, file3, something, libFile, configFile]);
142            const session = createSession(host, { syntaxOnly: true, useSingleInferredProject: true });
143            const service = session.getProjectService();
144            openFilesForSession([file1], session);
145            checkNumberOfProjects(service, { inferredProjects: 1 });
146            const project = service.inferredProjects[0];
147            checkProjectActualFiles(project, emptyArray);
148
149            openFilesForSession([file2], session);
150            checkNumberOfProjects(service, { inferredProjects: 1 });
151            assert.isFalse(project.dirty);
152            project.updateGraph();
153            checkProjectActualFiles(project, emptyArray);
154
155            closeFilesForSession([file2], session);
156            checkNumberOfProjects(service, { inferredProjects: 1 });
157            assert.isTrue(project.dirty);
158            checkProjectActualFiles(project, emptyArray);
159        });
160    });
161}
162