Skip to content

Commit eb73504

Browse files
Fixed up tests
1 parent 3734366 commit eb73504

File tree

2 files changed

+108
-75
lines changed

2 files changed

+108
-75
lines changed

src/converters/editorConfigs/converters/convertVSCodeConfig.test.ts

Lines changed: 101 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,87 @@ describe("convertVSCodeConfig", () => {
1010
const editorSettings = { unrelated: true };
1111

1212
// Act
13-
const result = convertVSCodeConfig(JSON.stringify(editorSettings), stubSettings);
13+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
1414

1515
// Assert
16-
expect(result).toEqual({
17-
contents: JSON.stringify(editorSettings, null, 4),
18-
missing: [],
19-
});
16+
expect(result).toMatchInlineSnapshot(`
17+
Object {
18+
"contents": "{
19+
\\"unrelated\\": true
20+
}",
21+
"missing": Array [],
22+
}
23+
`);
2024
});
2125

22-
it("includes eslint.autoFixOnSave when source.fixAll.tslint exists", () => {
26+
it("preserves original settings when the input structure is not an object", () => {
27+
// Arrange
28+
const editorSettings: never[] = [];
29+
30+
// Act
31+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
32+
33+
// Assert
34+
expect(result).toMatchInlineSnapshot(`
35+
Object {
36+
"contents": "[]",
37+
"missing": Array [],
38+
}
39+
`);
40+
});
41+
42+
it("does not include eslint.autoFixOnSave when source.fixAll.tslint is false", () => {
2343
// Arrange
2444
const editorSettings = {
2545
"editor.codeActionsOnSave": {
26-
"source.fixAll.tslint": true,
46+
"source.fixAll.tslint": false,
2747
},
2848
unrelated: true,
2949
};
3050

3151
// Act
32-
const result = convertVSCodeConfig(JSON.stringify(editorSettings), stubSettings);
52+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
3353

3454
// Assert
35-
expect(result).toEqual({
36-
contents: JSON.stringify(
37-
{
38-
"editor.codeActionsOnSave": {
39-
"source.fixAll.tslint": true,
40-
"eslint.autoFixOnSave": true,
41-
},
42-
unrelated: true,
43-
},
44-
null,
45-
4,
46-
),
47-
missing: [],
48-
});
55+
expect(result).toMatchInlineSnapshot(`
56+
Object {
57+
"contents": "{
58+
\\"editor.codeActionsOnSave\\": {
59+
\\"source.fixAll.tslint\\": false
60+
},
61+
\\"unrelated\\": true
62+
}",
63+
"missing": Array [],
64+
}
65+
`);
66+
});
67+
68+
it("includes eslint.autoFixOnSave when source.fixAll.tslint is true", () => {
69+
// Arrange
70+
const editorSettings = {
71+
"editor.codeActionsOnSave": {
72+
"source.fixAll.tslint": true,
73+
},
74+
unrelated: false,
75+
};
76+
77+
// Act
78+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
79+
80+
// Assert
81+
expect(result).toMatchInlineSnapshot(`
82+
Object {
83+
"contents": "{
84+
\\"editor.codeActionsOnSave\\": {
85+
\\"source.fixAll.tslint\\": true,
86+
\\"eslint.autoFixOnSave\\": true
87+
},
88+
\\"unrelated\\": false
89+
}
90+
",
91+
"missing": Array [],
92+
}
93+
`);
4994
});
5095

5196
it("does not include configFile when tslint.configFile does not match the output config", () => {
@@ -56,7 +101,7 @@ describe("convertVSCodeConfig", () => {
56101
};
57102

58103
// Act
59-
const result = convertVSCodeConfig(JSON.stringify(editorSettings), stubSettings);
104+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
60105

61106
// Assert
62107
expect(result).toEqual({
@@ -73,23 +118,22 @@ describe("convertVSCodeConfig", () => {
73118
};
74119

75120
// Act
76-
const result = convertVSCodeConfig(JSON.stringify(editorSettings), stubSettings);
121+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
77122

78123
// Assert
79-
expect(result).toEqual({
80-
contents: JSON.stringify(
81-
{
82-
"tslint.configFile": "./tslint.json",
83-
unrelated: true,
84-
"eslint.options": {
85-
configFile: stubSettings.config,
86-
},
87-
},
88-
null,
89-
4,
90-
),
91-
missing: [],
92-
});
124+
expect(result).toMatchInlineSnapshot(`
125+
Object {
126+
"contents": "{
127+
\\"tslint.configFile\\": \\"./tslint.json\\",
128+
\\"unrelated\\": true,
129+
\\"eslint.options\\": {
130+
\\"configFile\\": \\".eslintrc.js\\"
131+
}
132+
}
133+
",
134+
"missing": Array [],
135+
}
136+
`);
93137
});
94138

95139
it("includes missing notices when known missing settings are included", () => {
@@ -103,18 +147,26 @@ describe("convertVSCodeConfig", () => {
103147
};
104148

105149
// Act
106-
const result = convertVSCodeConfig(JSON.stringify(editorSettings), stubSettings);
150+
const result = convertVSCodeConfig(JSON.stringify(editorSettings, null, 4), stubSettings);
107151

108152
// Assert
109-
expect(result).toEqual({
110-
contents: JSON.stringify(editorSettings, null, 4),
111-
missing: [
112-
"tslint.alwaysShowRuleFailuresAsWarnings",
113-
"tslint.exclude",
114-
"tslint.ignoreDefinitionFiles",
115-
"tslint.jsEnable",
116-
"tslint.suppressWhileTypeErrorsPresent",
117-
],
118-
});
153+
expect(result).toMatchInlineSnapshot(`
154+
Object {
155+
"contents": "{
156+
\\"tslint.alwaysShowRuleFailuresAsWarnings\\": true,
157+
\\"tslint.exclude\\": true,
158+
\\"tslint.ignoreDefinitionFiles\\": true,
159+
\\"tslint.jsEnable\\": true,
160+
\\"tslint.suppressWhileTypeErrorsPresent\\": true
161+
}",
162+
"missing": Array [
163+
"tslint.alwaysShowRuleFailuresAsWarnings",
164+
"tslint.exclude",
165+
"tslint.ignoreDefinitionFiles",
166+
"tslint.jsEnable",
167+
"tslint.suppressWhileTypeErrorsPresent",
168+
],
169+
}
170+
`);
119171
});
120172
});

src/converters/editorConfigs/converters/convertVSCodeConfig.ts

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,6 @@ const knownMissingSettings = [
1212
"tslint.suppressWhileTypeErrorsPresent",
1313
];
1414

15-
const getJsonRoot = (sourceFile: ts.SourceFile) => {
16-
const [rootStatement] = sourceFile.statements;
17-
18-
return ts.isExpressionStatement(rootStatement) && ts.isObjectLiteralExpression(rootStatement.expression)
19-
? rootStatement.expression
20-
: undefined;
21-
}
22-
23-
2415
export const convertVSCodeConfig: EditorConfigConverter = (rawEditorSettings, settings) => {
2516
const editorSettings: Record<string, string | number | symbol> = parseJson(rawEditorSettings);
2617
const missing = knownMissingSettings.filter((setting) => editorSettings[setting]);
@@ -39,17 +30,14 @@ export const convertVSCodeConfig: EditorConfigConverter = (rawEditorSettings, se
3930
path.dirname(settings.config),
4031
);
4132

42-
// We can bail without making changes if there are no changes we need to make...
33+
// We can bail without making changes if there are no changes we need to make
4334
if (!autoFixOnSave && !eslintPathMatches) {
4435
return { contents: rawEditorSettings, missing };
4536
}
4637

47-
// ...or the JSON file doesn't seem to be a normal {} object root
38+
// Since we've found at least one matching setting, we know the source structure is a proper {}
4839
const sourceFile = ts.createSourceFile("settings.json", rawEditorSettings, ts.ScriptTarget.Latest, /*setParentNodes*/ true, ts.ScriptKind.JSON);
49-
const jsonRoot = getJsonRoot(sourceFile);
50-
if (!jsonRoot) {
51-
return { contents: rawEditorSettings, missing };
52-
}
40+
const jsonRoot = (sourceFile.statements[0] as ts.ExpressionStatement).expression as ts.ObjectLiteralExpression;
5341

5442
const propertyIndexByName = (properties: ts.NodeArray<ts.ObjectLiteralElementLike>, name: string) =>
5543
properties.findIndex(property => property.name && ts.isStringLiteral(property.name) && property.name.text === name);
@@ -69,9 +57,7 @@ export const convertVSCodeConfig: EditorConfigConverter = (rawEditorSettings, se
6957
`"${setting}"`,
7058
typeof value === "string"
7159
? context.factory.createStringLiteral(value)
72-
: value
73-
? context.factory.createTrue()
74-
: context.factory.createFalse()
60+
: context.factory.createTrue()
7561
)
7662
],
7763
true
@@ -83,15 +69,10 @@ export const convertVSCodeConfig: EditorConfigConverter = (rawEditorSettings, se
8369

8470
if (existingIndex !== -1) {
8571
const existingProperty = originalProperties[existingIndex];
86-
if (
87-
!ts.isPropertyAssignment(existingProperty)
88-
|| !ts.isObjectLiteralExpression(existingProperty.initializer)
89-
|| propertyIndexByName(existingProperty.initializer.properties, `"${parent}"`) === -1) {
90-
return node;
91-
}
92-
9372
const updatedProperties = [...node.properties];
94-
updatedProperties[existingIndex] = createNewChild(existingProperty.initializer.properties)
73+
74+
// We know these casts should be safe because we previously found a matching parent object for the property
75+
updatedProperties[existingIndex] = createNewChild(((existingProperty as ts.PropertyAssignment).initializer as ts.ObjectLiteralExpression).properties as ts.NodeArray<ts.ObjectLiteralElementLike> | undefined)
9576
node = context.factory.createObjectLiteralExpression(updatedProperties, true);
9677
} else {
9778
node = context.factory.createObjectLiteralExpression([...node.properties, createNewChild()], true);

0 commit comments

Comments
 (0)