Skip to content

Commit e1a4c27

Browse files
authored
Merge pull request microsoft#27440 from Microsoft/invalidTypes
Only copy non error values in array when converting the json
2 parents 21148b3 + 552777d commit e1a4c27

File tree

2 files changed

+91
-22
lines changed

2 files changed

+91
-22
lines changed

src/compiler/commandLineParser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,12 @@ namespace ts {
15291529
elements: NodeArray<Expression>,
15301530
elementOption: CommandLineOption | undefined
15311531
): any[] | void {
1532-
return (returnValue ? elements.map : elements.forEach).call(elements, (element: Expression) => convertPropertyValueToJson(element, elementOption));
1532+
if (!returnValue) {
1533+
return elements.forEach(element => convertPropertyValueToJson(element, elementOption));
1534+
}
1535+
1536+
// Filter out invalid values
1537+
return filter(elements.map(element => convertPropertyValueToJson(element, elementOption)), v => v !== undefined);
15331538
}
15341539

15351540
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption | undefined): any {

src/testRunner/unittests/convertCompilerOptionsFromJson.ts

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,50 @@
11
namespace ts {
22
describe("convertCompilerOptionsFromJson", () => {
3-
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
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: ReadonlyArray<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) {
426
assertCompilerOptionsWithJson(json, configFileName, expectedResult);
527
assertCompilerOptionsWithJsonNode(json, configFileName, expectedResult);
628
}
729

8-
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
9-
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
30+
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
31+
const { options: actualCompilerOptions, errors: actualErrors } = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
1032

1133
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
1234
const expectedCompilerOptions = JSON.stringify({ ...expectedResult.compilerOptions, configFilePath: configFileName });
1335
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
1436

15-
const expectedErrors = expectedResult.errors;
16-
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
17-
for (let i = 0; i < actualErrors.length; i++) {
18-
const actualError = actualErrors[i];
19-
const expectedError = expectedErrors[i];
20-
assert.equal(actualError.code, expectedError.code);
21-
assert.equal(actualError.category, expectedError.category);
22-
assert.equal(actualError.messageText, expectedError.messageText);
23-
}
37+
verifyErrors(actualErrors, expectedResult.errors, /*ignoreLocation*/ true);
2438
}
2539

26-
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
27-
const fileText = JSON.stringify(json);
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) {
2845
const result = parseJsonText(configFileName, fileText);
29-
assert(!result.parseDiagnostics.length);
3046
assert(!!result.endOfFileToken);
47+
assert.equal(!!result.parseDiagnostics.length, isExpectedResultWithParsingFailure(expectedResult));
3148
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
3249
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
3350
expectedResult.compilerOptions.configFilePath = configFileName;
@@ -37,17 +54,32 @@ namespace ts {
3754
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
3855
assert.equal(actualCompilerOptions.configFile, result);
3956

40-
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
41-
const expectedErrors = expectedResult.errors;
42-
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
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: ReadonlyArray<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, " ")}.`);
4364
for (let i = 0; i < actualErrors.length; i++) {
4465
const actualError = actualErrors[i];
4566
const expectedError = expectedErrors[i];
67+
4668
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
4769
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
48-
assert(actualError.file);
49-
assert(actualError.start);
50-
assert(actualError.length);
70+
if (!ignoreLocation) {
71+
assert(actualError.file);
72+
assert(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);
5183
}
5284
}
5385

@@ -539,5 +571,37 @@ namespace ts {
539571
}
540572
);
541573
});
574+
575+
it("Convert tsconfig options when there are multiple invalid strings", () => {
576+
assertCompilerOptionsWithJsonText(`{
577+
"compilerOptions": {
578+
"target": "<%- options.useTsWithBabel ? 'esnext' : 'es5' %>",
579+
"module": "esnext",
580+
<%_ if (options.classComponent) { _%>
581+
"experimentalDecorators": true,
582+
<%_ } _%>
583+
"sourceMap": true,
584+
"types": [
585+
"webpack-env"<% if (hasMocha || hasJest) { %>,<% } %>
586+
<%_ if (hasMocha) { _%>
587+
"mocha",
588+
"chai"
589+
<%_ } else if (hasJest) { _%>
590+
"jest"
591+
<%_ } _%>
592+
]
593+
}
594+
}
595+
`, "tsconfig.json",
596+
{
597+
compilerOptions: {
598+
target: undefined,
599+
module: ModuleKind.ESNext,
600+
types: []
601+
},
602+
hasParseErrors: true
603+
}
604+
);
605+
});
542606
});
543607
}

0 commit comments

Comments
 (0)