• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts {
2    describe("unittests:: config:: convertCompilerOptionsFromJson", () => {
3        const formatDiagnosticHost: FormatDiagnosticsHost = {
4            getCurrentDirectory: () => "/apath/",
5            getCanonicalFileName: createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ true),
6            getNewLine: () => "\n"
7        };
8
9        interface ExpectedResultWithParsingSuccess {
10            compilerOptions: CompilerOptions;
11            errors: readonly Diagnostic[];
12        }
13
14        interface ExpectedResultWithParsingFailure {
15            compilerOptions: CompilerOptions;
16            hasParseErrors: true;
17        }
18
19        type ExpectedResult = ExpectedResultWithParsingSuccess | ExpectedResultWithParsingFailure;
20
21        function isExpectedResultWithParsingFailure(expectedResult: ExpectedResult): expectedResult is ExpectedResultWithParsingFailure {
22            return !!(expectedResult as ExpectedResultWithParsingFailure).hasParseErrors;
23        }
24
25        function assertCompilerOptions(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
26            assertCompilerOptionsWithJson(json, configFileName, expectedResult);
27            assertCompilerOptionsWithJsonNode(json, configFileName, expectedResult);
28        }
29
30        function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
31            const { options: actualCompilerOptions, errors: actualErrors } = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
32
33            const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
34            const expectedCompilerOptions = JSON.stringify({ ...expectedResult.compilerOptions, configFilePath: configFileName });
35            assert.equal(parsedCompilerOptions, expectedCompilerOptions);
36
37            verifyErrors(actualErrors, expectedResult.errors, /*ignoreLocation*/ true);
38        }
39
40        function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
41            assertCompilerOptionsWithJsonText(JSON.stringify(json), configFileName, expectedResult);
42        }
43
44        function assertCompilerOptionsWithJsonText(fileText: string, configFileName: string, expectedResult: ExpectedResult) {
45            const result = parseJsonText(configFileName, fileText);
46            assert(!!result.endOfFileToken);
47            assert.equal(!!result.parseDiagnostics.length, isExpectedResultWithParsingFailure(expectedResult));
48            const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
49            const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
50            expectedResult.compilerOptions.configFilePath = configFileName;
51
52            const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
53            const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
54            assert.equal(parsedCompilerOptions, expectedCompilerOptions);
55            assert.equal(actualCompilerOptions.configFile, result);
56
57            if (!isExpectedResultWithParsingFailure(expectedResult)) {
58                verifyErrors(actualParseErrors.filter(error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code), expectedResult.errors);
59            }
60        }
61
62        function verifyErrors(actualErrors: Diagnostic[], expectedErrors: readonly Diagnostic[], ignoreLocation?: boolean) {
63            assert.isTrue(expectedErrors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedErrors.map(getDiagnosticString), undefined, " ")}. Actual error: ${JSON.stringify(actualErrors.map(getDiagnosticString), undefined, " ")}.`);
64            for (let i = 0; i < actualErrors.length; i++) {
65                const actualError = actualErrors[i];
66                const expectedError = expectedErrors[i];
67
68                assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
69                assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
70                if (!ignoreLocation) {
71                    assert(actualError.file);
72                    assert.isDefined(actualError.start);
73                    assert(actualError.length);
74                }
75            }
76
77            function getDiagnosticString(diagnostic: Diagnostic) {
78                if (ignoreLocation) {
79                    const { file, ...rest } = diagnostic;
80                    diagnostic = { file: undefined, ...rest };
81                }
82                return formatDiagnostic(diagnostic, formatDiagnosticHost);
83            }
84        }
85
86        // tsconfig.json tests
87        it("Convert correctly format tsconfig.json to compiler-options ", () => {
88            assertCompilerOptions(
89                {
90                    compilerOptions: {
91                        module: "commonjs",
92                        target: "es5",
93                        noImplicitAny: false,
94                        sourceMap: false,
95                        lib: ["es5", "es2015.core", "es2015.symbol"]
96                    }
97                }, "tsconfig.json",
98                {
99                    compilerOptions: {
100                        module: ModuleKind.CommonJS,
101                        target: ScriptTarget.ES5,
102                        noImplicitAny: false,
103                        sourceMap: false,
104                        lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
105                    },
106                    errors: []
107                }
108            );
109        });
110
111        it("Convert correctly format tsconfig.json with allowJs is false to compiler-options ", () => {
112            assertCompilerOptions(
113                {
114                    compilerOptions: {
115                        module: "commonjs",
116                        target: "es5",
117                        noImplicitAny: false,
118                        sourceMap: false,
119                        allowJs: false,
120                        lib: ["es5", "es2015.core", "es2015.symbol"]
121                    }
122                }, "tsconfig.json",
123                {
124                    compilerOptions: {
125                        module: ModuleKind.CommonJS,
126                        target: ScriptTarget.ES5,
127                        noImplicitAny: false,
128                        sourceMap: false,
129                        allowJs: false,
130                        lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
131                    },
132                    errors: []
133                }
134            );
135        });
136
137        it("Convert incorrect option of jsx to compiler-options ", () => {
138            assertCompilerOptions(
139                {
140                    compilerOptions: {
141                        module: "commonjs",
142                        target: "es5",
143                        noImplicitAny: false,
144                        sourceMap: false,
145                        jsx: ""
146                    }
147                }, "tsconfig.json",
148                {
149                    compilerOptions: {
150                        module: ModuleKind.CommonJS,
151                        target: ScriptTarget.ES5,
152                        noImplicitAny: false,
153                        sourceMap: false,
154                    },
155                    errors: [{
156                        file: undefined,
157                        start: 0,
158                        length: 0,
159                        messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.",
160                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
161                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
162                    }]
163                }
164            );
165        });
166
167        it("Convert incorrect option of module to compiler-options ", () => {
168            assertCompilerOptions(
169                {
170                    compilerOptions: {
171                        module: "",
172                        target: "es5",
173                        noImplicitAny: false,
174                        sourceMap: false,
175                    }
176                }, "tsconfig.json",
177                {
178                    compilerOptions: {
179                        target: ScriptTarget.ES5,
180                        noImplicitAny: false,
181                        sourceMap: false,
182                    },
183                    errors: [{
184                        file: undefined,
185                        start: 0,
186                        length: 0,
187                        messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext'.",
188                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
189                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
190                    }]
191                }
192            );
193        });
194
195        it("Convert incorrect option of newLine to compiler-options ", () => {
196            assertCompilerOptions(
197                {
198                    compilerOptions: {
199                        newLine: "",
200                        target: "es5",
201                        noImplicitAny: false,
202                        sourceMap: false,
203                    }
204                }, "tsconfig.json",
205                {
206                    compilerOptions: {
207                        target: ScriptTarget.ES5,
208                        noImplicitAny: false,
209                        sourceMap: false,
210                    },
211                    errors: [{
212                        file: undefined,
213                        start: 0,
214                        length: 0,
215                        messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.",
216                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
217                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
218                    }]
219                }
220            );
221        });
222
223        it("Convert incorrect option of target to compiler-options ", () => {
224            assertCompilerOptions(
225                {
226                    compilerOptions: {
227                        target: "",
228                        noImplicitAny: false,
229                        sourceMap: false,
230                    }
231                }, "tsconfig.json",
232                {
233                    compilerOptions: {
234                        noImplicitAny: false,
235                        sourceMap: false,
236                    },
237                    errors: [{
238                        file: undefined,
239                        start: 0,
240                        length: 0,
241                        messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext'.",
242                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
243                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
244                    }]
245                }
246            );
247        });
248
249        it("Convert incorrect option of module-resolution to compiler-options ", () => {
250            assertCompilerOptions(
251                {
252                    compilerOptions: {
253                        moduleResolution: "",
254                        noImplicitAny: false,
255                        sourceMap: false,
256                    }
257                }, "tsconfig.json",
258                {
259                    compilerOptions: {
260                        noImplicitAny: false,
261                        sourceMap: false,
262                    },
263                    errors: [{
264                        file: undefined,
265                        start: 0,
266                        length: 0,
267                        messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'.",
268                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
269                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
270                    }]
271                }
272            );
273        });
274
275        it("Convert incorrect option of libs to compiler-options ", () => {
276            assertCompilerOptions(
277                {
278                    compilerOptions: {
279                        module: "commonjs",
280                        target: "es5",
281                        noImplicitAny: false,
282                        sourceMap: false,
283                        lib: ["es5", "es2015.core", "incorrectLib"]
284                    }
285                }, "tsconfig.json",
286                {
287                    compilerOptions: {
288                        module: ModuleKind.CommonJS,
289                        target: ScriptTarget.ES5,
290                        noImplicitAny: false,
291                        sourceMap: false,
292                        lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts"]
293                    },
294                    errors: [{
295                        file: undefined,
296                        start: 0,
297                        length: 0,
298                        messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.bigint', 'esnext.string', 'esnext.promise'.",
299                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
300                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
301                    }]
302                }
303            );
304        });
305
306        it("Convert empty string option of libs to compiler-options ", () => {
307            assertCompilerOptions(
308                {
309                    compilerOptions: {
310                        module: "commonjs",
311                        target: "es5",
312                        noImplicitAny: false,
313                        sourceMap: false,
314                        lib: ["es5", ""]
315                    }
316                }, "tsconfig.json",
317                {
318                    compilerOptions: {
319                        module: ModuleKind.CommonJS,
320                        target: ScriptTarget.ES5,
321                        noImplicitAny: false,
322                        sourceMap: false,
323                        lib: ["lib.es5.d.ts"]
324                    },
325                    errors: [{
326                        file: undefined,
327                        start: 0,
328                        length: 0,
329                        messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise'.",
330                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
331                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
332                    }]
333                }
334            );
335        });
336
337        it("Convert empty string option of libs to compiler-options ", () => {
338            assertCompilerOptions(
339                {
340                    compilerOptions: {
341                        module: "commonjs",
342                        target: "es5",
343                        noImplicitAny: false,
344                        sourceMap: false,
345                        lib: [""]
346                    }
347                }, "tsconfig.json",
348                {
349                    compilerOptions: {
350                        module: ModuleKind.CommonJS,
351                        target: ScriptTarget.ES5,
352                        noImplicitAny: false,
353                        sourceMap: false,
354                        lib: []
355                    },
356                    errors: [{
357                        file: undefined,
358                        start: 0,
359                        length: 0,
360                        messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise'.",
361                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
362                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
363                    }]
364                }
365            );
366        });
367
368        it("Convert trailing-whitespace string option of libs to compiler-options ", () => {
369            assertCompilerOptions(
370                {
371                    compilerOptions: {
372                        module: "commonjs",
373                        target: "es5",
374                        noImplicitAny: false,
375                        sourceMap: false,
376                        lib: ["   "]
377                    }
378                }, "tsconfig.json",
379                {
380                    compilerOptions: {
381                        module: ModuleKind.CommonJS,
382                        target: ScriptTarget.ES5,
383                        noImplicitAny: false,
384                        sourceMap: false,
385                        lib: []
386                    },
387                    errors: [{
388                        file: undefined,
389                        start: 0,
390                        length: 0,
391                        messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise'.",
392                        code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
393                        category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
394                    }]
395                }
396            );
397        });
398
399        it("Convert empty option of libs to compiler-options ", () => {
400            assertCompilerOptions(
401                {
402                    compilerOptions: {
403                        module: "commonjs",
404                        target: "es5",
405                        noImplicitAny: false,
406                        sourceMap: false,
407                        lib: []
408                    }
409                }, "tsconfig.json",
410                {
411                    compilerOptions: {
412                        module: ModuleKind.CommonJS,
413                        target: ScriptTarget.ES5,
414                        noImplicitAny: false,
415                        sourceMap: false,
416                        lib: []
417                    },
418                    errors: []
419                }
420            );
421        });
422
423        it("Convert empty string option of moduleSuffixes to compiler-options ", () => {
424            assertCompilerOptions(
425                {
426                    compilerOptions: {
427                        moduleSuffixes: [".ios", ""]
428                    }
429                }, "tsconfig.json",
430                {
431                    compilerOptions: {
432                        moduleSuffixes: [".ios", ""]
433                    },
434                    errors: []
435                }
436            );
437        });
438
439        it("Convert empty string option of moduleSuffixes to compiler-options ", () => {
440            assertCompilerOptions(
441                {
442                    compilerOptions: {
443                        moduleSuffixes: [""]
444                    }
445                }, "tsconfig.json",
446                {
447                    compilerOptions: {
448                        moduleSuffixes: [""]
449                    },
450                    errors: []
451                }
452            );
453        });
454
455        it("Convert trailing-whitespace string option of moduleSuffixes to compiler-options ", () => {
456            assertCompilerOptions(
457                {
458                    compilerOptions: {
459                        moduleSuffixes: ["   "]
460                    }
461                }, "tsconfig.json",
462                {
463                    compilerOptions: {
464                        moduleSuffixes: ["   "]
465                    },
466                    errors: []
467                }
468            );
469        });
470
471        it("Convert empty option of moduleSuffixes to compiler-options ", () => {
472            assertCompilerOptions(
473                {
474                    compilerOptions: {
475                        moduleSuffixes: []
476                    }
477                }, "tsconfig.json",
478                {
479                    compilerOptions: {
480                        moduleSuffixes: []
481                    },
482                    errors: []
483                }
484            );
485        });
486
487        it("Convert incorrectly format tsconfig.json to compiler-options ", () => {
488            assertCompilerOptions(
489                {
490                    compilerOptions: {
491                        modu: "commonjs",
492                    }
493                }, "tsconfig.json",
494                {
495                    compilerOptions: {},
496                    errors: [{
497                        file: undefined,
498                        start: 0,
499                        length: 0,
500                        messageText: "Unknown compiler option 'modu'.",
501                        code: Diagnostics.Unknown_compiler_option_0.code,
502                        category: Diagnostics.Unknown_compiler_option_0.category
503                    }]
504                }
505            );
506        });
507
508        it("Convert default tsconfig.json to compiler-options ", () => {
509            assertCompilerOptions({}, "tsconfig.json",
510                {
511                    compilerOptions: {},
512                    errors: []
513                }
514            );
515        });
516
517        it("Convert negative numbers in tsconfig.json ", () => {
518            assertCompilerOptions(
519                {
520                    compilerOptions: {
521                        allowJs: true,
522                        maxNodeModuleJsDepth: -1
523                    }
524                }, "tsconfig.json",
525                {
526                    compilerOptions: {
527                        allowJs: true,
528                        maxNodeModuleJsDepth: -1
529                    },
530                    errors: []
531                }
532            );
533        });
534
535        // jsconfig.json
536        it("Convert correctly format jsconfig.json to compiler-options ", () => {
537            assertCompilerOptions(
538                {
539                    compilerOptions: {
540                        module: "commonjs",
541                        target: "es5",
542                        noImplicitAny: false,
543                        sourceMap: false,
544                        lib: ["es5", "es2015.core", "es2015.symbol"]
545                    }
546                }, "jsconfig.json",
547                {
548                    compilerOptions: {
549                        allowJs: true,
550                        maxNodeModuleJsDepth: 2,
551                        allowSyntheticDefaultImports: true,
552                        skipLibCheck: true,
553                        noEmit: true,
554                        module: ModuleKind.CommonJS,
555                        target: ScriptTarget.ES5,
556                        noImplicitAny: false,
557                        sourceMap: false,
558                        lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
559                    },
560                    errors: []
561                }
562            );
563        });
564
565        it("Convert correctly format jsconfig.json with allowJs is false to compiler-options ", () => {
566            assertCompilerOptions(
567                {
568                    compilerOptions: {
569                        module: "commonjs",
570                        target: "es5",
571                        noImplicitAny: false,
572                        sourceMap: false,
573                        allowJs: false,
574                        lib: ["es5", "es2015.core", "es2015.symbol"]
575                    }
576                }, "jsconfig.json",
577                {
578                    compilerOptions: {
579                        allowJs: false,
580                        maxNodeModuleJsDepth: 2,
581                        allowSyntheticDefaultImports: true,
582                        skipLibCheck: true,
583                        noEmit: true,
584                        module: ModuleKind.CommonJS,
585                        target: ScriptTarget.ES5,
586                        noImplicitAny: false,
587                        sourceMap: false,
588                        lib: ["lib.es5.d.ts", "lib.es2015.core.d.ts", "lib.es2015.symbol.d.ts"]
589                    },
590                    errors: []
591                }
592            );
593        });
594
595        it("Convert incorrectly format jsconfig.json to compiler-options ", () => {
596            assertCompilerOptions(
597                {
598                    compilerOptions: {
599                        modu: "commonjs",
600                    }
601                }, "jsconfig.json",
602                {
603                    compilerOptions:
604                    {
605                        allowJs: true,
606                        maxNodeModuleJsDepth: 2,
607                        allowSyntheticDefaultImports: true,
608                        skipLibCheck: true,
609                        noEmit: true
610                    },
611                    errors: [{
612                        file: undefined,
613                        start: 0,
614                        length: 0,
615                        messageText: "Unknown compiler option 'modu'.",
616                        code: Diagnostics.Unknown_compiler_option_0.code,
617                        category: Diagnostics.Unknown_compiler_option_0.category
618                    }]
619                }
620            );
621        });
622
623        it("Convert default jsconfig.json to compiler-options ", () => {
624            assertCompilerOptions({}, "jsconfig.json",
625                {
626                    compilerOptions:
627                    {
628                        allowJs: true,
629                        maxNodeModuleJsDepth: 2,
630                        allowSyntheticDefaultImports: true,
631                        skipLibCheck: true,
632                        noEmit: true
633                    },
634                    errors: []
635                }
636            );
637        });
638
639        it("Convert tsconfig options when there are multiple invalid strings", () => {
640            assertCompilerOptionsWithJsonText(`{
641  "compilerOptions": {
642    "target": "<%- options.useTsWithBabel ? 'esnext' : 'es5' %>",
643    "module": "esnext",
644    <%_ if (options.classComponent) { _%>
645    "experimentalDecorators": true,
646    <%_ } _%>
647    "sourceMap": true,
648    "types": [
649      "webpack-env"<% if (hasMocha || hasJest) { %>,<% } %>
650      <%_ if (hasMocha) { _%>
651      "mocha",
652      "chai"
653      <%_ } else if (hasJest) { _%>
654      "jest"
655      <%_ } _%>
656    ]
657  }
658}
659`,
660            "tsconfig.json",
661            {
662                compilerOptions: {
663                    target: undefined,
664                    module: ModuleKind.ESNext,
665                    experimentalDecorators: true,
666                },
667                hasParseErrors: true
668            });
669        });
670
671        it("Convert a tsconfig file with stray trailing characters", () => {
672            assertCompilerOptionsWithJsonText(`{
673                "compilerOptions": {
674                    "target": "esnext"
675                }
676            } blah`, "tsconfig.json", {
677                compilerOptions: {
678                    target: ScriptTarget.ESNext
679                },
680                hasParseErrors: true,
681                errors: [{
682                    ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object,
683                    messageText: "The root value of a 'tsconfig.json' file must be an object.",
684                    file: undefined,
685                    start: 0,
686                    length: 0
687                }]
688            });
689        });
690
691        it("Convert a tsconfig file with stray leading characters", () => {
692            assertCompilerOptionsWithJsonText(`blah {
693                "compilerOptions": {
694                    "target": "esnext"
695                }
696            }`, "tsconfig.json", {
697                compilerOptions: {
698                    target: ScriptTarget.ESNext
699                },
700                hasParseErrors: true,
701                errors: [{
702                    ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object,
703                    messageText: "The root value of a 'tsconfig.json' file must be an object.",
704                    file: undefined,
705                    start: 0,
706                    length: 0
707                }]
708            });
709        });
710
711        it("Convert a tsconfig file as an array", () => {
712            assertCompilerOptionsWithJsonText(`[{
713                "compilerOptions": {
714                    "target": "esnext"
715                }
716            }]`, "tsconfig.json", {
717                compilerOptions: {
718                    target: ScriptTarget.ESNext
719                },
720                errors: [{
721                    ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object,
722                    messageText: "The root value of a 'tsconfig.json' file must be an object.",
723                    file: undefined,
724                    start: 0,
725                    length: 0
726                }]
727            });
728        });
729
730        it("raises an error if you've set a compiler flag in the root without including 'compilerOptions'", () => {
731            assertCompilerOptionsWithJsonText(`{
732                "module": "esnext",
733            }`, "tsconfig.json", {
734                compilerOptions: {},
735                errors: [{
736                    ...Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file,
737                    messageText: "'module' should be set inside the 'compilerOptions' object of the config json file.",
738                    file: undefined,
739                    start: 0,
740                    length: 0
741                }]
742            });
743        });
744
745        it("does not raise an error if you've set a compiler flag in the root when you have included 'compilerOptions'", () => {
746            assertCompilerOptionsWithJsonText(`{
747                "target": "esnext",
748                "compilerOptions": {
749                    "module": "esnext"
750                }
751            }`, "tsconfig.json", {
752                compilerOptions: {
753                    module: ModuleKind.ESNext
754                },
755                errors: []
756            });
757        });
758
759        it("Don't crash when root expression is not object at all", () => {
760            assertCompilerOptionsWithJsonText(`42`, "tsconfig.json", {
761                compilerOptions: {},
762                errors: [{
763                    ...Diagnostics.The_root_value_of_a_0_file_must_be_an_object,
764                    messageText: "The root value of a 'tsconfig.json' file must be an object.",
765                    file: undefined,
766                    start: 0,
767                    length: 0
768                }]
769            });
770        });
771
772        it("Allow trailing comments", () => {
773            assertCompilerOptionsWithJsonText(`{} // no options`, "tsconfig.json", {
774                compilerOptions: {},
775                errors: []
776            });
777        });
778    });
779}
780