Skip to content

Commit

Permalink
chore: enable unicorn/no-array-reduce (#9640)
Browse files Browse the repository at this point in the history
* enable rule

* member-ordering

* parse-options

* no-type-alias

* no-base-to-string

* semi

* no-inferrable-types

* no-duplicate-type-constituents

* configs.test

* func-call-spacing.test

* prefer-nullish-coalescing.test

* no-explicit-any.test

* no-unsafe-assignment

* semi.test

* prefer-nullish-coalescing.test

* type-annotation-spacing.test

* indent.test

* parser

* configs.test

* resolveProjectList

* generate-configs

* deepMerge

* jsonSchema

* ConfigTypeScript

* generate-sponsors

* generate-configs

* fix semi

* review except for flatMap

* no longer using flatMap as filter

* fix variable name

* additional fix

* prettier

* refactor member-ordering

* move comment

* revert no-duplicate-type-constituents

* ConfigTypeScript

* revert generate-sponsors

* revert

* remove lint rule

* remove Object.groupBy because lib was downleveled

---------

Co-authored-by: Josh Goldberg <git@joshuakgoldberg.com>
  • Loading branch information
abrahamguo and JoshuaKGoldberg committed Sep 2, 2024
1 parent c66b259 commit 4bc801e
Show file tree
Hide file tree
Showing 15 changed files with 291 additions and 298 deletions.
100 changes: 49 additions & 51 deletions packages/eslint-plugin/src/rules/member-ordering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,75 +299,73 @@ export const defaultOrder: MemberType[] = [
'method',
];

const allMemberTypes = Array.from(
(
[
'readonly-signature',
'signature',
'readonly-field',
'field',
'method',
'call-signature',
'constructor',
'accessor',
'get',
'set',
'static-initialization',
] as const
).reduce<Set<MemberType>>((all, type) => {
all.add(type);

(['public', 'protected', 'private', '#private'] as const).forEach(
accessibility => {
if (
const allMemberTypes = [
...new Set(
(
[
'readonly-signature',
'signature',
'readonly-field',
'field',
'method',
'call-signature',
'constructor',
'accessor',
'get',
'set',
'static-initialization',
] as const
).flatMap(type => [
type,

...(['public', 'protected', 'private', '#private'] as const)
.flatMap<MemberType>(accessibility => [
type !== 'readonly-signature' &&
type !== 'signature' &&
type !== 'static-initialization' &&
type !== 'call-signature' &&
!(type === 'constructor' && accessibility === '#private')
) {
all.add(`${accessibility}-${type}`); // e.g. `public-field`
}
? `${accessibility}-${type}` // e.g. `public-field`
: [],

// Only class instance fields, methods, accessors, get and set can have decorators attached to them
if (
// Only class instance fields, methods, accessors, get and set can have decorators attached to them
accessibility !== '#private' &&
(type === 'readonly-field' ||
type === 'field' ||
type === 'method' ||
type === 'accessor' ||
type === 'get' ||
type === 'set')
) {
all.add(`${accessibility}-decorated-${type}`);
all.add(`decorated-${type}`);
}
? [`${accessibility}-decorated-${type}`, `decorated-${type}`]
: [],

if (
type !== 'constructor' &&
type !== 'readonly-signature' &&
type !== 'signature' &&
type !== 'call-signature'
) {
// There is no `static-constructor` or `instance-constructor` or `abstract-constructor`
if (accessibility === '#private' || accessibility === 'private') {
(['static', 'instance'] as const).forEach(scope => {
all.add(`${scope}-${type}`);
all.add(`${accessibility}-${scope}-${type}`);
});
} else {
(['static', 'instance', 'abstract'] as const).forEach(scope => {
all.add(`${scope}-${type}`);
all.add(`${accessibility}-${scope}-${type}`);
});
}
}
},
);

return all;
}, new Set<MemberType>()),
);
? (
[
'static',
'instance',
// There is no `static-constructor` or `instance-constructor` or `abstract-constructor`
...(accessibility === '#private' ||
accessibility === 'private'
? []
: (['abstract'] as const)),
] as const
).flatMap(
scope =>
[
`${scope}-${type}`,
`${accessibility}-${scope}-${type}`,
] as const,
)
: [],
])
.flat(),
]),
),
];

const functionExpressions = [
AST_NODE_TYPES.FunctionExpression,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ function normalizeOption(option: Selector): NormalizedSelector[] {
function parseOptions(context: Context): ParsedOptions {
const normalizedOptions = context.options.flatMap(normalizeOption);

const result = getEnumNames(Selectors).reduce((acc, k) => {
acc[k] = createValidator(k, context, normalizedOptions);
return acc;
// eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter
}, {} as ParsedOptions);

return result;
return Object.fromEntries(
getEnumNames(Selectors).map(k => [
k,
createValidator(k, context, normalizedOptions),
]),
) as ParsedOptions;
}

export { parseOptions };
5 changes: 1 addition & 4 deletions packages/eslint-plugin/src/rules/no-type-alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,7 @@ export default createRule<Options, MessageIds>({
node.type === AST_NODE_TYPES.TSUnionType ||
node.type === AST_NODE_TYPES.TSIntersectionType
) {
return node.types.reduce<TypeWithLabel[]>((acc, type) => {
acc.push(...getTypes(type, node.type));
return acc;
}, []);
return node.types.flatMap(type => getTypes(type, node.type));
}
return [{ node, compositionType }];
}
Expand Down
51 changes: 33 additions & 18 deletions packages/eslint-plugin/tests/configs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@ const EXTENSION_RULES = Object.entries(rules)
] as const,
);

function entriesToObject<T = unknown>(value: [string, T][]): Record<string, T> {
return value.reduce<Record<string, T>>((accum, [k, v]) => {
accum[k] = v;
return accum;
}, {});
}

function filterRules(
values: Record<string, string | unknown[]>,
): [string, string | unknown[]][] {
Expand Down Expand Up @@ -118,7 +111,9 @@ describe('all.ts', () => {
excludeDeprecated: true,
});

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -135,7 +130,9 @@ describe('disable-type-checked.ts', () => {
.filter(([, rule]) => rule.meta.docs?.requiresTypeChecking)
.map(([name]) => [`${RULE_NAME_PREFIX}${name}`, 'off']);

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});
});

Expand All @@ -151,7 +148,9 @@ describe('recommended.ts', () => {
recommendations: ['recommended'],
});

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -168,7 +167,9 @@ describe('recommended-type-checked.ts', () => {
recommendations: ['recommended'],
});

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -186,7 +187,9 @@ describe('recommended-type-checked-only.ts', () => {
recommendations: ['recommended'],
}).filter(([ruleName]) => ruleName);

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -205,7 +208,9 @@ describe('strict.ts', () => {
recommendations: ['recommended', 'strict'],
});

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -222,7 +227,9 @@ describe('strict-type-checked.ts', () => {
excludeDeprecated: true,
recommendations: ['recommended', 'strict'],
});
expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -241,7 +248,9 @@ describe('strict-type-checked-only.ts', () => {
recommendations: ['recommended', 'strict'],
}).filter(([ruleName]) => ruleName);

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -259,7 +268,9 @@ describe('stylistic.ts', () => {
recommendations: ['stylistic'],
});

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -275,7 +286,9 @@ describe('stylistic-type-checked.ts', () => {
});

it('contains all stylistic rules, excluding deprecated ones', () => {
expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand All @@ -293,7 +306,9 @@ describe('stylistic-type-checked-only.ts', () => {
recommendations: ['stylistic'],
}).filter(([ruleName]) => ruleName);

expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules));
expect(Object.fromEntries(ruleConfigs)).toEqual(
Object.fromEntries(configRules),
);
});

itHasBaseRulesOverriden(unfilteredConfigRules);
Expand Down
6 changes: 3 additions & 3 deletions packages/eslint-plugin/tests/rules/no-base-to-string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ ruleTester.run('no-base-to-string', rule, {
...literalList.map(i => `\`\${${i}}\`;`),

// operator + +=
...literalListWrapped
.map(l => literalListWrapped.map(r => `${l} + ${r};`))
.reduce((pre, cur) => [...pre, ...cur]),
...literalListWrapped.flatMap(l =>
literalListWrapped.map(r => `${l} + ${r};`),
),

// toString()
...literalListWrapped.map(i => `${i === '1' ? `(${i})` : i}.toString();`),
Expand Down
65 changes: 32 additions & 33 deletions packages/eslint-plugin/tests/rules/no-explicit-any.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ const test = <T extends Partial<never>>() => {};
],
},
] as RuleInvalidTestCase[]
).reduce<RuleInvalidTestCase[]>((acc, testCase) => {
).flatMap(testCase => {
const suggestions = (code: string): RuleSuggestionOutput[] => [
{
messageId: 'suggestUnknown',
Expand All @@ -1209,38 +1209,37 @@ const test = <T extends Partial<never>>() => {};
output: code.replace(/any/, 'never'),
},
];
acc.push({
...testCase,
errors: testCase.errors.map(e => ({
...e,
suggestions: e.suggestions ?? suggestions(testCase.code),
})),
});
const options = testCase.options ?? [];
const code = `// fixToUnknown: true\n${testCase.code}`;
acc.push({
code,
output: code.replaceAll('any', 'unknown'),
options: [{ ...options[0], fixToUnknown: true }],
errors: testCase.errors.map(err => {
if (err.line === undefined) {
return err;
}

return {
...err,
line: err.line + 1,
suggestions:
err.suggestions?.map(
(s): RuleSuggestionOutput => ({
...s,
output: `// fixToUnknown: true\n${s.output}`,
}),
) ?? suggestions(code),
};
}),
});
return [
{
...testCase,
errors: testCase.errors.map(e => ({
...e,
suggestions: e.suggestions ?? suggestions(testCase.code),
})),
},
{
code,
output: code.replaceAll('any', 'unknown'),
options: [{ ...testCase.options?.[0], fixToUnknown: true }],
errors: testCase.errors.map(err => {
if (err.line === undefined) {
return err;
}

return acc;
}, []),
return {
...err,
line: err.line + 1,
suggestions:
err.suggestions?.map(
(s): RuleSuggestionOutput => ({
...s,
output: `// fixToUnknown: true\n${s.output}`,
}),
) ?? suggestions(code),
};
}),
},
];
}),
});
Loading

0 comments on commit 4bc801e

Please sign in to comment.