Skip to content

Commit

Permalink
Merge pull request #49 from ony3000/fix-compound-component
Browse files Browse the repository at this point in the history
Correctly extract name of compound component
  • Loading branch information
ony3000 authored Apr 1, 2024
2 parents e326e48 + c1ea64d commit 6ecb18c
Show file tree
Hide file tree
Showing 13 changed files with 1,151 additions and 4 deletions.
51 changes: 47 additions & 4 deletions src/packages/core-parts/finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,31 @@ type ASTNode = {
range: NodeRange;
};

type JSXOpeningElementNameAsString = {
type: 'JSXIdentifier';
name: string;
};

type JSXOpeningElementNameAsObject = {
type: 'JSXMemberExpression';
object: JSXOpeningElementNameAsString | JSXOpeningElementNameAsObject;
property: JSXOpeningElementNameAsString;
};

function isTypeof<T extends ZodTypeAny>(arg: unknown, expectedSchema: T): arg is ZodInfer<T> {
return expectedSchema.safeParse(arg).success;
}

function getElementName(
param: JSXOpeningElementNameAsString | JSXOpeningElementNameAsObject,
): string {
if (param.type === 'JSXIdentifier') {
return param.name;
}

return `${getElementName(param.object)}.${param.property.name}`;
}

function filterAndSortClassNameNodes(
nonCommentNodes: ASTNode[],
prettierIgnoreNodes: ASTNode[],
Expand Down Expand Up @@ -168,9 +189,28 @@ export function findTargetClassNameNodes(
line: z.unknown(),
}),
}),
name: z.object({
name: z.string(),
}),
name: z.union([
z.object({
type: z.literal('JSXIdentifier'),
name: z.string(),
}),
z.object({
type: z.literal('JSXMemberExpression'),
// recursive structure
object: z.union([
z.object({
type: z.literal('JSXIdentifier'),
}),
z.object({
type: z.literal('JSXMemberExpression'),
}),
]),
property: z.object({
type: z.literal('JSXIdentifier'),
name: z.string(),
}),
}),
]),
}),
) &&
parentNode.type === 'JSXOpeningElement' &&
Expand Down Expand Up @@ -210,7 +250,10 @@ export function findTargetClassNameNodes(
? ClassNameType.ASL
: ClassNameType.AOL;
// eslint-disable-next-line no-param-reassign
classNameNode.elementName = parentNode.name.name;
classNameNode.elementName = getElementName(
// @ts-ignore
parentNode.name,
);
}
}
});
Expand Down
92 changes: 92 additions & 0 deletions tests/v2-test/babel/issue-47/absolute.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { format } from 'prettier';
import type { Fixture } from 'test-settings';
import { baseOptions } from 'test-settings';
import { describe, expect, test } from 'vitest';

// eslint-disable-next-line import/no-extraneous-dependencies
import * as thisPlugin from '@/packages/v2-plugin';

const options = {
...baseOptions,
plugins: [thisPlugin],
parser: 'babel',
endingPosition: 'absolute',
};

const fixtures: Fixture[] = [
{
name: 'component composition',
input: `
export const Overlay = () => {
return (
<Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0
z-50 h-screen w-screen"
/>
);
};
`,
},
{
name: 'double composition',
input: `
export const Overlay = () => {
return (
<Foo.Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Foo.Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0
z-50 h-screen w-screen"
/>
);
};
`,
},
{
name: 'triple composition',
input: `
export const Overlay = () => {
return (
<Foo.Bar.Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Foo.Bar.Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0
z-50 h-screen w-screen"
/>
);
};
`,
},
];

describe.each(fixtures)('$name', ({ input, output, options: fixtureOptions }) => {
const fixedOptions = {
...options,
...(fixtureOptions ?? {}),
};
const formattedText = format(input, fixedOptions);

test('expectation', () => {
expect(formattedText).toBe(output);
});

test.runIf(formattedText === output)('consistency', () => {
const doubleFormattedText = format(formattedText, fixedOptions);

expect(doubleFormattedText).toBe(formattedText);
});
});
92 changes: 92 additions & 0 deletions tests/v2-test/babel/issue-47/ideal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { format } from 'prettier';
import type { Fixture } from 'test-settings';
import { baseOptions } from 'test-settings';
import { describe, expect, test } from 'vitest';

// eslint-disable-next-line import/no-extraneous-dependencies
import * as thisPlugin from '@/packages/v2-plugin';

const options = {
...baseOptions,
plugins: [thisPlugin],
parser: 'babel',
endingPosition: 'absolute-with-indent',
};

const fixtures: Fixture[] = [
{
name: 'component composition',
input: `
export const Overlay = () => {
return (
<Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0
z-50 h-screen w-screen"
/>
);
};
`,
},
{
name: 'double composition',
input: `
export const Overlay = () => {
return (
<Foo.Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Foo.Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0
z-50 h-screen w-screen"
/>
);
};
`,
},
{
name: 'triple composition',
input: `
export const Overlay = () => {
return (
<Foo.Bar.Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Foo.Bar.Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0
z-50 h-screen w-screen"
/>
);
};
`,
},
];

describe.each(fixtures)('$name', ({ input, output, options: fixtureOptions }) => {
const fixedOptions = {
...options,
...(fixtureOptions ?? {}),
};
const formattedText = format(input, fixedOptions);

test('expectation', () => {
expect(formattedText).toBe(output);
});

test.runIf(formattedText === output)('consistency', () => {
const doubleFormattedText = format(formattedText, fixedOptions);

expect(doubleFormattedText).toBe(formattedText);
});
});
92 changes: 92 additions & 0 deletions tests/v2-test/babel/issue-47/relative.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { format } from 'prettier';
import type { Fixture } from 'test-settings';
import { baseOptions } from 'test-settings';
import { describe, expect, test } from 'vitest';

// eslint-disable-next-line import/no-extraneous-dependencies
import * as thisPlugin from '@/packages/v2-plugin';

const options = {
...baseOptions,
plugins: [thisPlugin],
parser: 'babel',
endingPosition: 'relative',
};

const fixtures: Fixture[] = [
{
name: 'component composition',
input: `
export const Overlay = () => {
return (
<Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen
w-screen"
/>
);
};
`,
},
{
name: 'double composition',
input: `
export const Overlay = () => {
return (
<Foo.Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Foo.Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen
w-screen"
/>
);
};
`,
},
{
name: 'triple composition',
input: `
export const Overlay = () => {
return (
<Foo.Bar.Dialog.Overlay className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen w-screen" />
);
};
`,
output: `export const Overlay = () => {
return (
<Foo.Bar.Dialog.Overlay
className="bg-popover backdrop-opacity-disabled focus:ring-0 fixed inset-0 z-50 h-screen
w-screen"
/>
);
};
`,
},
];

describe.each(fixtures)('$name', ({ input, output, options: fixtureOptions }) => {
const fixedOptions = {
...options,
...(fixtureOptions ?? {}),
};
const formattedText = format(input, fixedOptions);

test('expectation', () => {
expect(formattedText).toBe(output);
});

test.runIf(formattedText === output)('consistency', () => {
const doubleFormattedText = format(formattedText, fixedOptions);

expect(doubleFormattedText).toBe(formattedText);
});
});
Loading

0 comments on commit 6ecb18c

Please sign in to comment.