• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1describe("unittests:: services:: PreProcessFile:", () => {
2    function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
3        const resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
4
5        assert.equal(resultPreProcess.isLibFile, expectedPreProcess.isLibFile, "Pre-processed file has different value for isLibFile. Expected: " + expectedPreProcess.isLibFile + ". Actual: " + resultPreProcess.isLibFile);
6
7        checkFileReferenceList("Imported files", expectedPreProcess.importedFiles, resultPreProcess.importedFiles);
8        checkFileReferenceList("Referenced files", expectedPreProcess.referencedFiles, resultPreProcess.referencedFiles);
9        checkFileReferenceList("Type reference directives", expectedPreProcess.typeReferenceDirectives, resultPreProcess.typeReferenceDirectives);
10        checkFileReferenceList("Lib reference directives", expectedPreProcess.libReferenceDirectives, resultPreProcess.libReferenceDirectives);
11
12        assert.deepEqual(resultPreProcess.ambientExternalModules, expectedPreProcess.ambientExternalModules);
13    }
14
15    function checkFileReferenceList(kind: string, expected: ts.FileReference[], actual: ts.FileReference[]) {
16        if (expected === actual) {
17            return;
18        }
19        assert.deepEqual(actual, expected, `Expected [${kind}] ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
20    }
21
22    describe("Test preProcessFiles,", () => {
23        it("Correctly return referenced files from triple slash", () => {
24            test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
25                /*readImportFile*/ true,
26                /*detectJavaScriptImports*/ false,
27                {
28                    referencedFiles: [{ fileName: "refFile1.ts", pos: 22, end: 33 }, { fileName: "refFile2.ts", pos: 59, end: 70 },
29                        { fileName: "refFile3.ts", pos: 94, end: 105 }, { fileName: "..\\refFile4d.ts", pos: 131, end: 146 }],
30                    importedFiles: [] as ts.FileReference[],
31                    typeReferenceDirectives: [],
32                    libReferenceDirectives: [],
33                    ambientExternalModules: undefined,
34                    isLibFile: false
35                });
36        });
37
38        it("Do not return reference path because of invalid triple-slash syntax", () => {
39            test("///<reference path\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\">" + "\n" + "///<referencepath=\"refFile3.ts\" />" + "\n" + "///<reference pat= \"refFile4d.ts\" />",
40                /*readImportFile*/ true,
41                /*detectJavaScriptImports*/ false,
42                {
43                    referencedFiles: [] as ts.FileReference[],
44                    importedFiles: [] as ts.FileReference[],
45                    typeReferenceDirectives: [],
46                    libReferenceDirectives: [],
47                    ambientExternalModules: undefined,
48                    isLibFile: false
49                });
50        });
51
52        it("Do not return reference path of non-imports", () => {
53            test("Quill.import('delta');",
54                /*readImportFile*/ true,
55                /*detectJavaScriptImports*/ false,
56                {
57                    referencedFiles: [] as ts.FileReference[],
58                    importedFiles: [] as ts.FileReference[],
59                    typeReferenceDirectives: [],
60                    libReferenceDirectives: [],
61                    ambientExternalModules: undefined,
62                    isLibFile: false
63                });
64        });
65
66        it("Do not return reference path of nested non-imports", () => {
67            test("a.b.import('c');",
68                /*readImportFile*/ true,
69                /*detectJavaScriptImports*/ false,
70                {
71                    referencedFiles: [] as ts.FileReference[],
72                    importedFiles: [] as ts.FileReference[],
73                    typeReferenceDirectives: [],
74                    libReferenceDirectives: [],
75                    ambientExternalModules: undefined,
76                    isLibFile: false
77                });
78        });
79
80        it("Correctly return imported files", () => {
81            test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require  (\"r5.ts\");",
82                /*readImportFile*/ true,
83                /*detectJavaScriptImports*/ false,
84                {
85                    referencedFiles: [] as ts.FileReference[],
86                    typeReferenceDirectives: [],
87                    libReferenceDirectives: [],
88                    importedFiles: [{ fileName: "r1.ts", pos: 20, end: 25 }, { fileName: "r2.ts", pos: 49, end: 54 }, { fileName: "r3.ts", pos: 78, end: 83 },
89                        { fileName: "r4.ts", pos: 106, end: 111 }, { fileName: "r5.ts", pos: 138, end: 143 }],
90                    ambientExternalModules: undefined,
91                    isLibFile: false
92                });
93        });
94
95        it("Do not return imported files if readImportFiles argument is false", () => {
96            test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require  (\"r5.ts\");",
97                /*readImportFile*/ false,
98                /*detectJavaScriptImports*/ false,
99                {
100                    referencedFiles: [] as ts.FileReference[],
101                    typeReferenceDirectives: [],
102                    libReferenceDirectives: [],
103                    importedFiles: [] as ts.FileReference[],
104                    ambientExternalModules: undefined,
105                    isLibFile: false
106                });
107        });
108
109        it("Do not return import path because of invalid import syntax", () => {
110            test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5",
111                /*readImportFile*/ true,
112                /*detectJavaScriptImports*/ false,
113                {
114                    referencedFiles: [] as ts.FileReference[],
115                    typeReferenceDirectives: [],
116                    libReferenceDirectives: [],
117                    importedFiles: [{ fileName: "r3.ts", pos: 73, end: 78 }],
118                    ambientExternalModules: undefined,
119                    isLibFile: false
120                });
121        });
122
123        it("Correctly return referenced files and import files", () => {
124            test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");",
125                /*readImportFile*/ true,
126                /*detectJavaScriptImports*/ false,
127                {
128                    referencedFiles: [{ fileName: "refFile1.ts", pos: 20, end: 31 }, { fileName: "refFile2.ts", pos: 57, end: 68 }],
129                    typeReferenceDirectives: [],
130                    libReferenceDirectives: [],
131                    importedFiles: [{ fileName: "r1.ts", pos: 92, end: 97 }, { fileName: "r2.ts", pos: 121, end: 126 }],
132                    ambientExternalModules: undefined,
133                    isLibFile: false
134                });
135        });
136
137        it("Correctly return referenced files and import files even with some invalid syntax", () => {
138            test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path \"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");",
139                /*readImportFile*/ true,
140                /*detectJavaScriptImports*/ false,
141                {
142                    referencedFiles: [{ fileName: "refFile1.ts", pos: 20, end: 31 }],
143                    typeReferenceDirectives: [],
144                    libReferenceDirectives: [],
145                    importedFiles: [{ fileName: "r1.ts", pos: 91, end: 96 }, { fileName: "r3.ts", pos: 148, end: 153 }],
146                    ambientExternalModules: undefined,
147                    isLibFile: false
148                });
149        });
150
151        it("Correctly return ES6 imports", () => {
152            test("import * as ns from \"m1\";" + "\n" +
153                "import def, * as ns from \"m2\";" + "\n" +
154                "import def from \"m3\";" + "\n" +
155                "import {a} from \"m4\";" + "\n" +
156                "import {a as A} from \"m5\";" + "\n" +
157                "import {a as A, b, c as C} from \"m6\";" + "\n" +
158                "import def , {a, b, c as C} from \"m7\";" + "\n",
159            /*readImportFile*/ true,
160            /*detectJavaScriptImports*/ false,
161            {
162                referencedFiles: [],
163                typeReferenceDirectives: [],
164                libReferenceDirectives: [],
165                importedFiles: [
166                    { fileName: "m1", pos: 20, end: 22 },
167                    { fileName: "m2", pos: 51, end: 53 },
168                    { fileName: "m3", pos: 73, end: 75 },
169                    { fileName: "m4", pos: 95, end: 97 },
170                    { fileName: "m5", pos: 122, end: 124 },
171                    { fileName: "m6", pos: 160, end: 162 },
172                    { fileName: "m7", pos: 199, end: 201 }
173                ],
174                ambientExternalModules: undefined,
175                isLibFile: false
176            });
177        });
178
179        it("Correctly ignore commented imports following template expression", () => {
180            /* eslint-disable no-template-curly-in-string */
181            test("/**" + "\n" +
182                " * Before" + "\n" +
183                " * ```" + "\n" +
184                " * import * as a from \"a\";" + "\n" +
185                " * ```" + "\n" +
186                " */" + "\n" +
187                "type Foo = `${string}`;" + "\n" +
188                "/**" + "\n" +
189                " * After" + "\n" +
190                " * ```" + "\n" +
191                " * import { B } from \"b\";" + "\n" +
192                " * import * as c from \"c\";" + "\n" +
193                " * ```" + "\n" +
194                " */",
195            /*readImportFile*/ true,
196            /*detectJavaScriptImports*/ true,
197            {
198                referencedFiles: [],
199                typeReferenceDirectives: [],
200                libReferenceDirectives: [],
201                importedFiles: [],
202                ambientExternalModules: undefined,
203                isLibFile: false
204            });
205            /* eslint-enable no-template-curly-in-string */
206        });
207
208        it("Ignores imports in template strings", () => {
209            /* eslint-disable no-template-curly-in-string */
210            test("a ? `&${a}` : `#${b}`;\n\n `import(\"${moduleSpecifier}\").${id}`;",
211            /*readImportFile*/ true,
212            /*detectJavaScriptImports*/ true,
213            {
214                referencedFiles: [],
215                typeReferenceDirectives: [],
216                libReferenceDirectives: [],
217                importedFiles: [],
218                ambientExternalModules: undefined,
219                isLibFile: false
220            });
221            /* eslint-enable no-template-curly-in-string */
222        });
223
224        it("Correctly returns imports after a template expression", () => {
225            /* eslint-disable no-template-curly-in-string */
226            test("`${foo}`; import \"./foo\";",
227            /*readImportFile*/ true,
228            /*detectJavaScriptImports*/ true,
229            {
230                referencedFiles: [],
231                typeReferenceDirectives: [],
232                libReferenceDirectives: [],
233                importedFiles: [
234                    { fileName: "./foo", pos: 17, end: 22 }
235                ],
236                ambientExternalModules: undefined,
237                isLibFile: false
238            });
239            /* eslint-enable no-template-curly-in-string */
240        });
241
242        it("Correctly returns dynamic imports from template expression", () => {
243            /* eslint-disable no-template-curly-in-string */
244            test("`${(<div>Text `` ${} text {} " + "\n" +
245                "${import(\"a\")} {import(\"b\")} " + "\n" +
246                "${/* A comment */} ${/* import(\"ignored\") */} </div>)}`",
247            /*readImportFile*/ true,
248            /*detectJavaScriptImports*/ true,
249            {
250                referencedFiles: [],
251                typeReferenceDirectives: [],
252                libReferenceDirectives: [],
253                importedFiles: [
254                    { fileName: "a", pos: 39, end: 40 },
255                    { fileName: "b", pos: 53, end: 54 }
256                ],
257                ambientExternalModules: undefined,
258                isLibFile: false
259            });
260            /* eslint-enable no-template-curly-in-string */
261        });
262
263        it("Correctly returns dynamic imports from nested template expression", () => {
264            /* eslint-disable no-template-curly-in-string */
265            test("`${foo(`${bar(`${import(\"a\")} ${import(\"b\")}`, `${baz(`${import(\"c\") ${import(\"d\")}`)}`)}`)}`",
266            /*readImportFile*/ true,
267            /*detectJavaScriptImports*/ true,
268            {
269                referencedFiles: [],
270                typeReferenceDirectives: [],
271                libReferenceDirectives: [],
272                importedFiles: [
273                    { fileName: "a", pos: 24, end: 25 },
274                    { fileName: "b", pos: 39, end: 40 },
275                    { fileName: "c", pos: 64, end: 65 },
276                    { fileName: "d", pos: 78, end: 79 },
277                ],
278                ambientExternalModules: undefined,
279                isLibFile: false
280            });
281            /* eslint-enable no-template-curly-in-string */
282        });
283
284        it("Correctly returns dynamic imports from tagged template expression", () => {
285            /* eslint-disable no-template-curly-in-string */
286            test("foo`${ fn({ a: 100 }, import(\"a\"), `${import(\"b\")}`, import(\"c\"), `${import(\"d\")} foo`, import(\"e\")) }`",
287            /*readImportFile*/ true,
288            /*detectJavaScriptImports*/ true,
289            {
290                referencedFiles: [],
291                typeReferenceDirectives: [],
292                libReferenceDirectives: [],
293                importedFiles: [
294                    { fileName: "a", pos: 29, end: 30 },
295                    { fileName: "b", pos: 45, end: 46 },
296                    { fileName: "c", pos: 60, end: 61 },
297                    { fileName: "d", pos: 76, end: 77 },
298                    { fileName: "e", pos: 95, end: 96 },
299                ],
300                ambientExternalModules: undefined,
301                isLibFile: false
302            });
303            /* eslint-enable no-template-curly-in-string */
304        });
305
306        it("Correctly returns dynamic imports from template expression and imports following it", () => {
307            /* eslint-disable no-template-curly-in-string */
308            test("const x = `hello ${await import(\"a\").default}`;" + "\n\n" +
309                "import { y } from \"b\";",
310            /*readImportFile*/ true,
311            /*detectJavaScriptImports*/ true,
312            {
313                referencedFiles: [],
314                typeReferenceDirectives: [],
315                libReferenceDirectives: [],
316                importedFiles: [
317                    { fileName: "a", pos: 32, end: 33 },
318                    { fileName: "b", pos: 67, end: 68 },
319                ],
320                ambientExternalModules: undefined,
321                isLibFile: false
322            });
323            /* eslint-enable no-template-curly-in-string */
324        });
325
326        it("Correctly returns dynamic imports from template expressions and other imports", () => {
327            /* eslint-disable no-template-curly-in-string */
328            test("const x = `x ${await import(\"a\").default}`;" + "\n\n" +
329                "import { y } from \"b\";" + "\n" +
330                "const y = `y ${import(\"c\")}`;" + "\n\n" +
331                "import { d } from \"d\";",
332            /*readImportFile*/ true,
333            /*detectJavaScriptImports*/ true,
334            {
335                referencedFiles: [],
336                typeReferenceDirectives: [],
337                libReferenceDirectives: [],
338                importedFiles: [
339                    { fileName: "a", pos: 28, end: 29 },
340                    { fileName: "b", pos: 63, end: 64 },
341                    { fileName: "c", pos: 90, end: 91 },
342                    { fileName: "d", pos: 117, end: 118 },
343                ],
344                ambientExternalModules: undefined,
345                isLibFile: false
346            });
347            /* eslint-enable no-template-curly-in-string */
348        });
349
350        it("Correctly returns empty importedFiles with incorrect template expression", () => {
351            /* eslint-disable no-template-curly-in-string */
352            test("const foo = `${",
353            /*readImportFile*/ true,
354            /*detectJavaScriptImports*/ true,
355            {
356                referencedFiles: [],
357                typeReferenceDirectives: [],
358                libReferenceDirectives: [],
359                importedFiles: [],
360                ambientExternalModules: undefined,
361                isLibFile: false
362            });
363            /* eslint-enable no-template-curly-in-string */
364        });
365
366        it("Correctly return ES6 exports", () => {
367            test("export * from \"m1\";" + "\n" +
368                "export {a} from \"m2\";" + "\n" +
369                "export {a as A} from \"m3\";" + "\n" +
370                "export {a as A, b, c as C} from \"m4\";" + "\n",
371            /*readImportFile*/ true,
372            /*detectJavaScriptImports*/ false,
373            {
374                referencedFiles: [],
375                typeReferenceDirectives: [],
376                libReferenceDirectives: [],
377                importedFiles: [
378                    { fileName: "m1", pos: 14, end: 16 },
379                    { fileName: "m2", pos: 36, end: 38 },
380                    { fileName: "m3", pos: 63, end: 65 },
381                    { fileName: "m4", pos: 101, end: 103 },
382                ],
383                ambientExternalModules: undefined,
384                isLibFile: false
385            });
386        });
387
388        it("Correctly handles import types", () => {
389            test("import type * as ns from \"m1\";" + "\n" +
390                "import type def, * as ns from \"m2\";" + "\n" +
391                "import type def from \"m3\";" + "\n" +
392                "import type {a} from \"m4\";" + "\n" +
393                "import type {a as A} from \"m5\";" + "\n" +
394                "import type {a as A, b, c as C} from \"m6\";" + "\n" +
395                "import type def , {a, b, c as C} from \"m7\";" + "\n" +
396                "import type from \"m8\";" + "\n" +
397                "import type T = require(\"m9\");" + "\n" +
398                "import type = require(\"m10\");" + "\n" +
399                "export import type T = require(\"m11\");" + "\n" +
400                "export import type = require(\"m12\");" + "\n",
401            /*readImportFile*/ true,
402            /*detectJavaScriptImports*/ false,
403            {
404                referencedFiles: [] as ts.FileReference[],
405                typeReferenceDirectives: [],
406                libReferenceDirectives: [],
407                importedFiles: [
408                    { fileName: "m1", pos: 25, end: 27 },
409                    { fileName: "m2", pos: 61, end: 63 },
410                    { fileName: "m3", pos: 88, end: 90 },
411                    { fileName: "m4", pos: 115, end: 117 },
412                    { fileName: "m5", pos: 147, end: 149 },
413                    { fileName: "m6", pos: 190, end: 192 },
414                    { fileName: "m7", pos: 234, end: 236 },
415                    { fileName: "m8", pos: 257, end: 259 },
416                    { fileName: "m9", pos: 287, end: 289 },
417                    { fileName: "m10", pos: 316, end: 319 },
418                    { fileName: "m11", pos: 355, end: 358 },
419                    { fileName: "m12", pos: 392, end: 395 },
420                ],
421                ambientExternalModules: undefined,
422                isLibFile: false
423            });
424        });
425
426        it("Correctly handles export types", () => {
427            test("export type * from \"m1\";" + "\n" +
428                "export type {a} from \"m2\";" + "\n" +
429                "export type {a as A} from \"m3\";" + "\n" +
430                "export type {a as A, b, c as C} from \"m4\";" + "\n",
431            /*readImportFile*/ true,
432            /*detectJavaScriptImports*/ false,
433            {
434                referencedFiles: [] as ts.FileReference[],
435                typeReferenceDirectives: [],
436                libReferenceDirectives: [],
437                importedFiles: [
438                    { fileName: "m1", pos: 19, end: 21 },
439                    { fileName: "m2", pos: 46, end: 48 },
440                    { fileName: "m3", pos: 78, end: 80 },
441                    { fileName: "m4", pos: 121, end: 123 },
442                ],
443                ambientExternalModules: undefined,
444                isLibFile: false
445            });
446        });
447
448        it("Correctly handles import type node", () => {
449            test("const x: import(\"m1\") = { x: 0, y: 0 };" + "\n" +
450                "let y: import(\"m2\").Bar.I = { a: \"\", b: 0 };" + "\n" +
451                "let shim: typeof import(\"m3\") = { Bar: Bar2 };" + "\n",
452            /*readImportFile*/ true,
453            /*detectJavaScriptImports*/ false,
454            {
455                referencedFiles: [],
456                typeReferenceDirectives: [],
457                libReferenceDirectives: [],
458                importedFiles: [
459                    { fileName: "m1", pos: 16, end: 18 },
460                    { fileName: "m2", pos: 54, end: 56 },
461                    { fileName: "m3", pos: 109, end: 111 },
462                ],
463                ambientExternalModules: undefined,
464                isLibFile: false
465            });
466        });
467
468        it("Correctly return ambient external modules", () => {
469            test(`
470               declare module A {}
471               declare module "B" {}
472               function foo() {
473               }
474               `,
475            /*readImportFile*/ true,
476            /*detectJavaScriptImports*/ false,
477            {
478                referencedFiles: [],
479                typeReferenceDirectives: [],
480                libReferenceDirectives: [],
481                importedFiles: [],
482                ambientExternalModules: ["B"],
483                isLibFile: false
484            });
485        });
486
487        it("Correctly handles export import declarations", () => {
488            test("export import a = require(\"m1\");",
489                /*readImportFile*/ true,
490                /*detectJavaScriptImports*/ false,
491                {
492                    referencedFiles: [],
493                    typeReferenceDirectives: [],
494                    libReferenceDirectives: [],
495                    importedFiles: [
496                        { fileName: "m1", pos: 26, end: 28 }
497                    ],
498                    ambientExternalModules: undefined,
499                    isLibFile: false
500                });
501        });
502        it("Correctly handles export require calls in JavaScript files", () => {
503            test(`
504            export import a = require("m1");
505            var x = require('m2');
506            foo(require('m3'));
507            var z = { f: require('m4') }
508            `,
509            /*readImportFile*/ true,
510            /*detectJavaScriptImports*/ true,
511            {
512                referencedFiles: [],
513                typeReferenceDirectives: [],
514                libReferenceDirectives: [],
515                importedFiles: [
516                    { fileName: "m1", pos: 39, end: 41 },
517                    { fileName: "m2", pos: 74, end: 76 },
518                    { fileName: "m3", pos: 105, end: 107 },
519                    { fileName: "m4", pos: 146, end: 148 },
520                ],
521                ambientExternalModules: undefined,
522                isLibFile: false
523            });
524        });
525        it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", () => {
526            test(`
527            define(["mod1", "mod2"], (m1, m2) => {
528            });
529            `,
530            /*readImportFile*/ true,
531            /*detectJavaScriptImports*/ true,
532            {
533                referencedFiles: [],
534                typeReferenceDirectives: [],
535                libReferenceDirectives: [],
536                importedFiles: [
537                    { fileName: "mod1", pos: 21, end: 25 },
538                    { fileName: "mod2", pos: 29, end: 33 },
539                ],
540                ambientExternalModules: undefined,
541                isLibFile: false
542            });
543        });
544
545        it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", () => {
546            test(`
547            define("mod", ["mod1", "mod2"], (m1, m2) => {
548            });
549            `,
550            /*readImportFile*/ true,
551            /*detectJavaScriptImports*/ true,
552            {
553                referencedFiles: [],
554                typeReferenceDirectives: [],
555                libReferenceDirectives: [],
556                importedFiles: [
557                    { fileName: "mod1", pos: 28, end: 32 },
558                    { fileName: "mod2", pos: 36, end: 40 },
559                ],
560                ambientExternalModules: undefined,
561                isLibFile: false
562            });
563        });
564
565        it("correctly handles augmentations in external modules - 1", () => {
566            test(`
567            declare module "../Observable" {
568                interface I {}
569            }
570
571            export {}
572            `,
573            /*readImportFile*/ true,
574            /*detectJavaScriptImports*/ false,
575            {
576                referencedFiles: [],
577                typeReferenceDirectives: [],
578                libReferenceDirectives: [],
579                importedFiles: [
580                    { fileName: "../Observable", pos: 28, end: 41 }
581                ],
582                ambientExternalModules: undefined,
583                isLibFile: false
584            });
585        });
586        it("correctly handles augmentations in external modules - 2", () => {
587            test(`
588            declare module "../Observable" {
589                interface I {}
590            }
591
592            import * as x from "m";
593            `,
594            /*readImportFile*/ true,
595            /*detectJavaScriptImports*/ false,
596            {
597                referencedFiles: [],
598                typeReferenceDirectives: [],
599                libReferenceDirectives: [],
600                importedFiles: [
601                    { fileName: "m", pos: 123, end: 124 },
602                    { fileName: "../Observable", pos: 28, end: 41 }
603                ],
604                ambientExternalModules: undefined,
605                isLibFile: false
606            });
607        });
608        it("correctly handles augmentations in external modules - 3", () => {
609            test(`
610            declare module "../Observable" {
611                interface I {}
612            }
613
614            import m = require("m");
615            `,
616            /*readImportFile*/ true,
617            /*detectJavaScriptImports*/ false,
618            {
619                referencedFiles: [],
620                typeReferenceDirectives: [],
621                libReferenceDirectives: [],
622                importedFiles: [
623                    { fileName: "m", pos: 123, end: 124 },
624                    { fileName: "../Observable", pos: 28, end: 41 }
625                ],
626                ambientExternalModules: undefined,
627                isLibFile: false
628            });
629        });
630        it("correctly handles augmentations in external modules - 4", () => {
631            test(`
632            declare module "../Observable" {
633                interface I {}
634            }
635            namespace N {}
636            export = N;
637            `,
638            /*readImportFile*/ true,
639            /*detectJavaScriptImports*/ false,
640            {
641                referencedFiles: [],
642                typeReferenceDirectives: [],
643                libReferenceDirectives: [],
644                importedFiles: [
645                    { fileName: "../Observable", pos: 28, end: 41 }
646                ],
647                ambientExternalModules: undefined,
648                isLibFile: false
649            });
650        });
651        it("correctly handles augmentations in external modules - 5", () => {
652            test(`
653            declare module "../Observable" {
654                interface I {}
655            }
656            namespace N {}
657            export import IN = N;
658            `,
659            /*readImportFile*/ true,
660            /*detectJavaScriptImports*/ false,
661            {
662                referencedFiles: [],
663                typeReferenceDirectives: [],
664                libReferenceDirectives: [],
665                importedFiles: [
666                    { fileName: "../Observable", pos: 28, end: 41 }
667                ],
668                ambientExternalModules: undefined,
669                isLibFile: false
670            });
671        });
672        it("correctly handles augmentations in external modules - 6", () => {
673            test(`
674            declare module "../Observable" {
675                interface I {}
676            }
677            export let x = 1;
678            `,
679            /*readImportFile*/ true,
680            /*detectJavaScriptImports*/ false,
681            {
682                referencedFiles: [],
683                typeReferenceDirectives: [],
684                libReferenceDirectives: [],
685                importedFiles: [
686                    { fileName: "../Observable", pos: 28, end: 41 }
687                ],
688                ambientExternalModules: undefined,
689                isLibFile: false
690            });
691        });
692        it ("correctly handles augmentations in ambient external modules - 1", () => {
693            test(`
694            declare module "m1" {
695                export * from "m2";
696                declare module "augmentation" {
697                    interface I {}
698                }
699            }
700            `,
701            /*readImportFile*/ true,
702            /*detectJavaScriptImports*/ false,
703            {
704                referencedFiles: [],
705                typeReferenceDirectives: [],
706                libReferenceDirectives: [],
707                importedFiles: [
708                    { fileName: "m2", pos: 65, end: 67 },
709                    { fileName: "augmentation", pos: 102, end: 114 }
710                ],
711                ambientExternalModules: ["m1"],
712                isLibFile: false
713            });
714        });
715        it ("correctly handles augmentations in ambient external modules - 2", () => {
716            test(`
717            namespace M { var x; }
718            import IM = M;
719            declare module "m1" {
720                export * from "m2";
721                declare module "augmentation" {
722                    interface I {}
723                }
724            }
725            `,
726            /*readImportFile*/ true,
727            /*detectJavaScriptImports*/ false,
728            {
729                referencedFiles: [],
730                typeReferenceDirectives: [],
731                libReferenceDirectives: [],
732                importedFiles: [
733                    { fileName: "m2", pos: 127, end: 129 },
734                    { fileName: "augmentation", pos: 164, end: 176 }
735                ],
736                ambientExternalModules: ["m1"],
737                isLibFile: false
738            });
739        });
740        it ("correctly recognizes type reference directives", () => {
741            test(`
742            /// <reference path="a"/>
743            /// <reference types="a1"/>
744            /// <reference path="a2"/>
745            /// <reference types="a3"/>
746            `,
747            /*readImportFile*/ true,
748            /*detectJavaScriptImports*/ false,
749            {
750                referencedFiles: [
751                    { pos: 34, end: 35, fileName: "a" },
752                    { pos: 112, end: 114, fileName: "a2" }
753                ],
754                typeReferenceDirectives: [
755                    { pos: 73, end: 75, fileName: "a1" },
756                    { pos: 152, end: 154, fileName: "a3" }
757                ],
758                libReferenceDirectives: [],
759                importedFiles: [],
760                ambientExternalModules: undefined,
761                isLibFile: false
762            });
763        });
764        it ("correctly recognizes lib reference directives", () => {
765            test(`
766            /// <reference path="a"/>
767            /// <reference lib="a1"/>
768            /// <reference path="a2"/>
769            /// <reference lib="a3"/>
770            `,
771            /*readImportFile*/ true,
772            /*detectJavaScriptImports*/ false,
773            {
774                referencedFiles: [
775                    { pos: 34, end: 35, fileName: "a" },
776                    { pos: 110, end: 112, fileName: "a2" }
777                ],
778                typeReferenceDirectives: [
779                ],
780                libReferenceDirectives: [
781                    { pos: 71, end: 73, fileName: "a1" },
782                    { pos: 148, end: 150, fileName: "a3" }
783                ],
784                importedFiles: [],
785                ambientExternalModules: undefined,
786                isLibFile: false
787            });
788        });
789
790        it("Correctly handles dynamic imports with template literals", () => {
791            test("const m1 = import('mod1');" + "\n" +
792            "const m2 = import(`mod2`);" + "\n" +
793            "Promise.all([import('mod3'), import(`mod4`)]);" + "\n" +
794            "import(/* webpackChunkName: 'module5' */ `mod5`);" + "\n",
795            /*readImportFile*/ true,
796            /*detectJavaScriptImports*/ false,
797            {
798                referencedFiles: [],
799                typeReferenceDirectives: [],
800                libReferenceDirectives: [],
801                importedFiles: [
802                    { fileName: "mod1", pos: 18, end: 22 },
803                    { fileName: "mod2", pos: 45, end: 49 },
804                    { fileName: "mod3", pos: 74, end: 78 },
805                    { fileName: "mod4", pos: 90, end: 94 },
806                    { fileName: "mod5", pos: 142, end: 146 }
807                ],
808                ambientExternalModules: undefined,
809                isLibFile: false
810            });
811        });
812
813        it("Correctly handles require calls with template literals in JS files", () => {
814            test("const m1 = require(`mod1`);" + "\n" +
815            "f(require(`mod2`));" + "\n" +
816            "const a = { x: require(`mod3`) };" + "\n",
817            /*readImportFile*/ true,
818            /*detectJavaScriptImports*/ true,
819            {
820                referencedFiles: [],
821                typeReferenceDirectives: [],
822                libReferenceDirectives: [],
823                importedFiles: [
824                    { fileName: "mod1", pos: 19, end: 23 },
825                    { fileName: "mod2", pos: 38, end: 42 },
826                    { fileName: "mod3", pos: 71, end: 75 }
827                ],
828                ambientExternalModules: undefined,
829                isLibFile: false
830            });
831        });
832
833        it("Correctly handles dependency lists in define(modName, [deplist]) calls with template literals in JS files", () => {
834            test("define(`mod`, [`mod1`, `mod2`], (m1, m2) => {});",
835            /*readImportFile*/ true,
836            /*detectJavaScriptImports*/ true,
837            {
838                referencedFiles: [],
839                typeReferenceDirectives: [],
840                libReferenceDirectives: [],
841                importedFiles: [
842                    { fileName: "mod1", pos: 15, end: 19 },
843                    { fileName: "mod2", pos: 23, end: 27 },
844                ],
845                ambientExternalModules: undefined,
846                isLibFile: false
847            });
848        });
849    });
850});
851