Skip to content

Commit 8e189da

Browse files
committed
add converter trailing-comma
1 parent 07be509 commit 8e189da

File tree

2 files changed

+395
-0
lines changed

2 files changed

+395
-0
lines changed
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
import { convertTrailingComma } from "../trailing-comma";
2+
3+
describe(convertTrailingComma, () => {
4+
test("conversion without arguments", () => {
5+
const result = convertTrailingComma({
6+
ruleArguments: [],
7+
});
8+
9+
expect(result).toEqual({
10+
rules: [
11+
{
12+
ruleName: "comma-dangle",
13+
},
14+
],
15+
});
16+
});
17+
18+
describe("conversion with arguments using string values", () => {
19+
const testCases = [
20+
{
21+
argument: {
22+
singleline: "never",
23+
},
24+
expectedRuleArguments: [],
25+
},
26+
{
27+
argument: {
28+
singleline: "always",
29+
},
30+
expectedRuleArguments: [],
31+
},
32+
{
33+
argument: {
34+
multiline: "never",
35+
},
36+
expectedRuleArguments: [],
37+
},
38+
{
39+
argument: {
40+
multiline: "always",
41+
},
42+
expectedRuleArguments: ["always-multiline"],
43+
},
44+
{
45+
argument: {
46+
singleline: "never",
47+
multiline: "never",
48+
},
49+
expectedRuleArguments: [],
50+
},
51+
{
52+
argument: {
53+
singleline: "never",
54+
multiline: "always",
55+
},
56+
expectedRuleArguments: ["always-multiline"],
57+
},
58+
{
59+
argument: {
60+
singleline: "always",
61+
multiline: "never",
62+
},
63+
expectedRuleArguments: [],
64+
},
65+
{
66+
argument: {
67+
singleline: "always",
68+
multiline: "always",
69+
},
70+
expectedRuleArguments: ["always"],
71+
},
72+
];
73+
74+
testCases.forEach(testCase => {
75+
test(`conversion with arguments ${JSON.stringify(testCase.argument)}`, () => {
76+
const result = convertTrailingComma({
77+
ruleArguments: [testCase.argument],
78+
});
79+
80+
expect(result).toEqual({
81+
rules: [
82+
{
83+
ruleName: "comma-dangle",
84+
...(testCase.expectedRuleArguments.length !== 0 && {
85+
ruleArguments: testCase.expectedRuleArguments,
86+
}),
87+
},
88+
],
89+
});
90+
});
91+
});
92+
});
93+
94+
describe("conversion with arguments using object values", () => {
95+
const testCases = [
96+
{
97+
argument: {
98+
singleline: "never",
99+
multiline: {
100+
objects: "always",
101+
arrays: "always",
102+
functions: "always",
103+
imports: "always",
104+
exports: "always",
105+
typeLiterals: "ignore",
106+
},
107+
},
108+
expectedRuleArguments: [
109+
{
110+
arrays: "always-multiline",
111+
objects: "always-multiline",
112+
functions: "always-multiline",
113+
imports: "always-multiline",
114+
exports: "always-multiline",
115+
},
116+
],
117+
},
118+
{
119+
argument: {
120+
singleline: "always",
121+
multiline: {
122+
objects: "always",
123+
arrays: "always",
124+
functions: "always",
125+
imports: "always",
126+
exports: "always",
127+
typeLiterals: "ignore",
128+
},
129+
},
130+
expectedRuleArguments: [
131+
{
132+
arrays: "always",
133+
objects: "always",
134+
functions: "always",
135+
imports: "always",
136+
exports: "always",
137+
},
138+
],
139+
},
140+
{
141+
argument: {
142+
singleline: {
143+
objects: "never",
144+
arrays: "never",
145+
functions: "never",
146+
imports: "never",
147+
exports: "never",
148+
typeLiterals: "ignore",
149+
},
150+
},
151+
expectedRuleArguments: [
152+
{
153+
arrays: "never",
154+
objects: "never",
155+
functions: "never",
156+
imports: "never",
157+
exports: "never",
158+
},
159+
],
160+
},
161+
{
162+
argument: {
163+
singleline: {
164+
objects: "never",
165+
arrays: "never",
166+
functions: "never",
167+
typeLiterals: "ignore",
168+
},
169+
multiline: {
170+
objects: "never",
171+
arrays: "never",
172+
functions: "never",
173+
typeLiterals: "ignore",
174+
},
175+
},
176+
expectedRuleArguments: [
177+
{
178+
arrays: "never",
179+
objects: "never",
180+
functions: "never",
181+
},
182+
],
183+
},
184+
{
185+
argument: {
186+
multiline: {
187+
objects: "always",
188+
arrays: "always",
189+
functions: "always",
190+
imports: "always",
191+
exports: "always",
192+
typeLiterals: "ignore",
193+
},
194+
},
195+
expectedRuleArguments: [
196+
{
197+
arrays: "always-multiline",
198+
objects: "always-multiline",
199+
functions: "always-multiline",
200+
imports: "always-multiline",
201+
exports: "always-multiline",
202+
},
203+
],
204+
},
205+
{
206+
argument: {
207+
singleline: {
208+
objects: "always",
209+
arrays: "always",
210+
functions: "always",
211+
imports: "always",
212+
exports: "always",
213+
typeLiterals: "ignore",
214+
},
215+
multiline: {
216+
objects: "always",
217+
arrays: "always",
218+
functions: "always",
219+
imports: "always",
220+
exports: "always",
221+
typeLiterals: "ignore",
222+
},
223+
},
224+
expectedRuleArguments: [
225+
{
226+
arrays: "always",
227+
objects: "always",
228+
functions: "always",
229+
imports: "always",
230+
exports: "always",
231+
},
232+
],
233+
},
234+
{
235+
argument: {
236+
singleline: {
237+
objects: "always",
238+
arrays: "always",
239+
},
240+
multiline: {
241+
objects: "always",
242+
arrays: "always",
243+
functions: "always",
244+
},
245+
},
246+
expectedRuleArguments: [
247+
{
248+
arrays: "always",
249+
objects: "always",
250+
functions: "always-multiline",
251+
},
252+
],
253+
},
254+
];
255+
256+
testCases.forEach(testCase => {
257+
test(`conversion with arguments ${JSON.stringify(testCase.argument)}`, () => {
258+
const result = convertTrailingComma({
259+
ruleArguments: [testCase.argument],
260+
});
261+
262+
expect(result).toEqual({
263+
rules: [
264+
{
265+
ruleName: "comma-dangle",
266+
...(testCase.expectedRuleArguments.length !== 0 && {
267+
ruleArguments: testCase.expectedRuleArguments,
268+
}),
269+
},
270+
],
271+
});
272+
});
273+
});
274+
});
275+
});
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { RuleConverter } from "../converter";
2+
3+
export const convertTrailingComma: RuleConverter = tslintRule => {
4+
const eslintArgs =
5+
tslintRule.ruleArguments.length !== 0
6+
? collectArguments(tslintRule.ruleArguments)
7+
: undefined;
8+
9+
return {
10+
rules: [
11+
{
12+
ruleName: "comma-dangle",
13+
...(eslintArgs && { ruleArguments: [eslintArgs] }),
14+
},
15+
],
16+
};
17+
};
18+
19+
function collectArguments(args: any[]) {
20+
const tslintArg: any = args[0];
21+
const { multiline, singleline } = tslintArg;
22+
23+
if (typeof multiline === "object" || typeof singleline === "object") {
24+
const fields = mergePropertyKeys(singleline, multiline);
25+
const single = getFieldValue(singleline);
26+
const multi = getFieldValue(multiline);
27+
28+
return fields.reduce(
29+
(acc, field) => ({
30+
...acc,
31+
...collectFields(field, single, multi),
32+
}),
33+
{},
34+
);
35+
}
36+
37+
if (
38+
multiline === TSLintValue.Always &&
39+
(singleline === undefined || singleline === TSLintValue.Never)
40+
) {
41+
return ESLintValue.AlwaysMultiline;
42+
}
43+
44+
if (multiline === TSLintValue.Always && singleline === TSLintValue.Always) {
45+
return ESLintValue.Always;
46+
}
47+
48+
return;
49+
}
50+
51+
function mergePropertyKeys(singleline: any, multiline: any) {
52+
const getKeysIfObject = (field: any) => (typeof field === "object" ? Object.keys(field) : []);
53+
const singlelineKeys = getKeysIfObject(singleline);
54+
const multilineKeys = getKeysIfObject(multiline);
55+
56+
const uniqueKeys = [...new Set([...singlelineKeys, ...multilineKeys])];
57+
const unsupportedKeyInEsLint = "typeLiterals";
58+
59+
return uniqueKeys.filter(field => field !== unsupportedKeyInEsLint);
60+
}
61+
62+
function collectFields(fieldName: string, singleline: any, multiline: any) {
63+
const hasSingleline = Boolean(singleline);
64+
const hasSinglelineAndFieldExist = Boolean(singleline && singleline[fieldName]);
65+
const hasSinglelineAlways = Boolean(singleline && singleline[fieldName] === TSLintValue.Always);
66+
const hasMultilineAlways = Boolean(multiline && multiline[fieldName] === TSLintValue.Always);
67+
68+
if (!hasSingleline && hasMultilineAlways) {
69+
return {
70+
[fieldName]: ESLintValue.AlwaysMultiline,
71+
};
72+
}
73+
74+
if (!hasSinglelineAndFieldExist && hasMultilineAlways) {
75+
return {
76+
[fieldName]: ESLintValue.AlwaysMultiline,
77+
};
78+
}
79+
80+
if (!hasSinglelineAlways && hasMultilineAlways) {
81+
return {
82+
[fieldName]: ESLintValue.AlwaysMultiline,
83+
};
84+
}
85+
86+
if (hasSinglelineAlways && hasMultilineAlways) {
87+
return {
88+
[fieldName]: ESLintValue.Always,
89+
};
90+
}
91+
92+
return {
93+
[fieldName]: ESLintValue.Never,
94+
};
95+
}
96+
97+
function getFieldValue(value: string | object) {
98+
return typeof value === "string"
99+
? {
100+
arrays: value,
101+
objects: value,
102+
functions: value,
103+
imports: value,
104+
exports: value,
105+
}
106+
: value;
107+
}
108+
109+
enum TSLintValue {
110+
Always = "always",
111+
Never = "never",
112+
}
113+
114+
enum ESLintValue {
115+
Never = "never",
116+
Always = "always",
117+
AlwaysMultiline = "always-multiline",
118+
OnlyMultiline = "only-multiline",
119+
Ignore = "ignore",
120+
}

0 commit comments

Comments
 (0)