Skip to content

Commit

Permalink
Improve ESLint migrations for v9 (#2735)
Browse files Browse the repository at this point in the history
  • Loading branch information
connor-baer authored Oct 23, 2024
1 parent d89175a commit 70f3ab8
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/metal-games-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sumup-oss/eslint-plugin-circuit-ui': minor
---

Expanded the `renamed-package-scope` ESLint rule to cover additional occurrences of package names such as in Jest module mocks.
5 changes: 5 additions & 0 deletions .changeset/quick-books-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sumup-oss/eslint-plugin-circuit-ui': patch
---

Fixed the `no-renamed-props` ESLint rule to add the `as="strong"` prop when migrating the Body's `variant="highlight"` prop to match the previous semantics.
20 changes: 18 additions & 2 deletions packages/eslint-plugin-circuit-ui/no-renamed-props/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,12 @@ ruleTester.run('no-renamed-props', noRenamedProps, {
}
function ComponentB() {
return (
<Body as="span" variant="highlight">Lorem ipsum</Body>
)
}
function ComponentC() {
return (
<Body variant="alert">Lorem ipsum</Body>
)
Expand All @@ -348,17 +354,27 @@ ruleTester.run('no-renamed-props', noRenamedProps, {
output: `
function ComponentA() {
return (
<Body weight="bold">Lorem ipsum</Body>
<Body as="strong" weight="bold">Lorem ipsum</Body>
)
}
function ComponentB() {
return (
<Body as="span" weight="bold">Lorem ipsum</Body>
)
}
function ComponentC() {
return (
<Body color="danger">Lorem ipsum</Body>
)
}
`,
errors: [{ messageId: 'bodyVariant' }, { messageId: 'bodyVariant' }],
errors: [
{ messageId: 'bodyVariant' },
{ messageId: 'bodyVariant' },
{ messageId: 'bodyVariant' },
],
},
],
});
7 changes: 6 additions & 1 deletion packages/eslint-plugin-circuit-ui/no-renamed-props/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,20 @@ const configs: (Config & { components: string[] })[] = [
const current = getAttributeValue(attribute);

if (current === 'highlight') {
const replacement = `weight="bold"`;
const replacement = `as="strong" weight="bold"`;
const weightAttribute = findAttribute(node, 'weight');
const asAttribute = findAttribute(node, 'as');
context.report({
node: attribute,
messageId: 'bodyVariant',
data: { component, current, replacement },
fix: weightAttribute
? undefined
: (fixer) => {
// Don't override an existing `as` attribute
if (asAttribute) {
return fixer.replaceText(attribute, 'weight="bold"');
}
return fixer.replaceText(attribute, replacement);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,63 @@ ruleTester.run('renamed-package-scope', renamedPackageScope, {
`,
errors: [{ messageId: 'refactor' }],
},
{
name: 'dynamic import from the old package scope',
code: `
const components = await import('@sumup/circuit-ui');
`,
output: `
const components = await import('@sumup-oss/circuit-ui');
`,
errors: [{ messageId: 'refactor' }],
},
{
name: 'module mock of the old package scope',
code: `
jest.mock('@sumup/circuit-ui');
jest.mock('@sumup/intl', () => ({
...jest.requireActual('@sumup/intl'),
formatNumber: jest.fn(),
}));
`,
output: `
jest.mock('@sumup-oss/circuit-ui');
jest.mock('@sumup-oss/intl', () => ({
...jest.requireActual('@sumup-oss/intl'),
formatNumber: jest.fn(),
}));
`,
errors: [
{ messageId: 'refactor' },
{ messageId: 'refactor' },
{ messageId: 'refactor' },
],
},
{
name: 'module mock of the old package scope with type annotations',
code: `
vi.mock('@sumup/circuit-ui', () => ({
...vi.importActual<typeof import('@sumup/circuit-ui')>(
'@sumup/circuit-ui',
),
useCollapsible: vi.fn(),
}));
`,
output: `
vi.mock('@sumup-oss/circuit-ui', () => ({
...vi.importActual<typeof import('@sumup-oss/circuit-ui')>(
'@sumup-oss/circuit-ui',
),
useCollapsible: vi.fn(),
}));
`,
errors: [
{ messageId: 'refactor' },
{ messageId: 'refactor' },
{ messageId: 'refactor' },
],
},
],
});
70 changes: 59 additions & 11 deletions packages/eslint-plugin-circuit-ui/renamed-package-scope/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,69 @@ export const renamedPackageScope = createRule({
// See https://eslint.org/docs/latest/extend/selectors#known-issues
const escapedFrom = from.replace('/', '\\u002F');

function fixPackageName(node: TSESTree.Node | TSESTree.Token) {
context.report({
node,
messageId: 'refactor',
data: { from, to },
fix(fixer) {
return fixer.replaceText(
node,
context.sourceCode.getText(node).replace(from, to),
);
},
});
}

return Object.assign(visitors, {
[`ImportDeclaration:has(Literal[value=/${escapedFrom}(?!-).*/])`]: (
node: TSESTree.ImportDeclaration,
) => {
context.report({
node,
messageId: 'refactor',
data: { from, to },
fix(fixer) {
return fixer.replaceText(
node,
context.sourceCode.getText(node).replace(from, to),
);
},
});
const { source } = node;

if (source.type !== 'Literal') {
return;
}

fixPackageName(source);
},
[`ImportExpression:has(Literal[value=/${escapedFrom}(?!-).*/])`]: (
node: TSESTree.ImportExpression,
) => {
const { source } = node;

if (source.type !== 'Literal') {
return;
}

fixPackageName(source);
},
[`CallExpression:has(Identifier[name=/(mock|requireActual|importActual)/]):has(Literal[value=/${escapedFrom}(?!-).*/])`]:
(node: TSESTree.CallExpression) => {
const firstArg = node.arguments[0];

if (firstArg.type !== 'Literal') {
return;
}

fixPackageName(firstArg);
},
[`TSImportType:has(Literal[value=/${escapedFrom}(?!-).*/])`]: (
node: TSESTree.TSImportType,
) => {
const { argument } = node;

if (argument.type !== 'TSLiteralType') {
return;
}

const { literal } = argument;

if (literal.type !== 'Literal') {
return;
}

fixPackageName(literal);
},
});
}, {});
Expand Down

0 comments on commit 70f3ab8

Please sign in to comment.