Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions packages/core/src/components/icon-button/icon-button.test.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import type { ComponentProps } from 'react';
import { type ComponentProps, forwardRef } from 'react';

import { cleanup, render } from '@testing-library/react';
import user from '@testing-library/user-event';
import type { Mock } from 'vitest';
import { axe } from 'vitest-axe';

import { IconButton } from '.';
import { Tooltip } from '../tooltip';

const ARIA_LABEL = 'Like';

const IconButtonTest = (props: IconButton.Props) => {
const IconButtonTest = forwardRef<HTMLButtonElement, IconButton.Props>((props, ref) => {
return (
<IconButton {...props}>
<IconButton {...props} ref={ref}>
<HeartIcon data-testid="icon" />
</IconButton>
);
};
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

forwardRef로 감싸진 컴포넌트에는 디버깅 편의성을 위해 displayName을 설정하는 것이 좋습니다.1

Suggested change
});
});
IconButtonTest.displayName = 'IconButtonTest';

Style Guide References

Footnotes

  1. 스타일 가이드에서는 디버깅 편의성을 위해 forwardRef를 사용하는 컴포넌트에 displayName을 설정하는 것을 권장하고 있습니다.


describe('IconButton', () => {
afterEach(cleanup);
Expand Down Expand Up @@ -59,6 +60,31 @@ describe('IconButton', () => {

expect(svg).toHaveAttribute('aria-hidden', 'true');
});

it('should handle click on icon area when used with Tooltip', async () => {
const handleClickMock: Mock = vi.fn();

const rendered = render(
<Tooltip.Root>
<Tooltip.Trigger
render={<IconButton aria-label={ARIA_LABEL} onClick={handleClickMock} />}
>
<HeartIcon data-testid="icon" />
</Tooltip.Trigger>
<Tooltip.Popup>Tooltip Content</Tooltip.Popup>
</Tooltip.Root>,
);

const button = rendered.getByLabelText(ARIA_LABEL);
const icon = rendered.getByTestId('icon');

await user.click(button);

const icon2 = rendered.getByTestId('icon');

expect(handleClickMock).toHaveBeenCalledTimes(1);
expect(icon).toBe(icon2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

테스트의 의도를 더 명확하게 하고 견고성을 높이기 위해, handleClickMock이 실제로 호출되었는지 확인하는 단언문을 추가하는 것이 좋습니다. 현재 테스트는 아이콘이 리마운트되지 않았는지만 확인하고 있어, 클릭 이벤트가 정상적으로 처리되었는지는 검증하지 못하고 있습니다.

        expect(icon).toBe(icon2);
        expect(handleClickMock).toHaveBeenCalledTimes(1);

});
});

const HeartIcon = (props: ComponentProps<'svg'>) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components/icon-button/icon-button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef } from 'react';
import { forwardRef, useMemo } from 'react';

import clsx from 'clsx';

Expand All @@ -25,7 +25,7 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButton.Props>((props

const { size } = otherProps;

const IconElement = createSlot(children);
const IconElement = useMemo(() => createSlot(children), [children]);

return (
<Button
Expand Down
Loading