-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Chip 컴포넌트 테스트 작성 #88
Changes from 31 commits
1b84b6c
eed11c1
9e09ac2
2fda402
8c4e6d9
22b23f6
9c84c45
471b195
489a401
c8bdcc8
4579454
b283e21
ab0dffd
8afd547
fe77716
5b35c13
da739a2
fc75fdc
75d7737
f28bbbb
2297768
c14a875
9429b52
0781e50
1cf5670
3b90049
6f591f4
6e9ad33
f3c1962
c0c47ba
34e36d0
693c414
e3bcfb0
82d9a35
1b3b761
0db9c5e
8d78f90
9eb7022
43fea6b
12a8892
ab4d238
ccb7138
ba3f1c5
45a385b
f6ff146
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { render, type RenderResult, waitFor } from "@testing-library/react"; | ||
import { userEvent } from "@testing-library/user-event"; | ||
|
||
import Chip from "@/components/Chip"; | ||
|
||
describe("Chip rendering Test", () => { | ||
let renderChip: RenderResult; | ||
beforeEach(() => { | ||
renderChip = render(<Chip as="div" label="Chip" />); | ||
}); | ||
|
||
it("should render Chip", () => { | ||
const { getByText } = renderChip; | ||
expect(getByText("Chip")).toBeInTheDocument(); | ||
}); | ||
|
||
it("should render with attributes aria-disabled to be false by default", () => { | ||
const chipComponent = renderChip.getByRole("contentinfo"); | ||
|
||
expect(chipComponent).toHaveAttribute("aria-disabled", "false"); | ||
}); | ||
}); | ||
|
||
describe("Chip toggle Test", () => { | ||
let renderChip: RenderResult; | ||
beforeEach(() => { | ||
renderChip = render(<Chip as="button" clickable={true} label="Chip" />); | ||
}); | ||
|
||
it("should toggle state when onClick event is fired", async () => { | ||
const chipComponent = renderChip.getByRole("checkbox"); | ||
const user = userEvent.setup(); | ||
|
||
await user.click(chipComponent); | ||
expect(chipComponent).toHaveAttribute("aria-checked", "true"); | ||
await user.click(chipComponent); | ||
expect(chipComponent).toHaveAttribute("aria-checked", "false"); | ||
}); | ||
|
||
it("should toggle state when Enter key is pressed", async () => { | ||
const chipComponent = renderChip.getByRole("checkbox"); | ||
userEvent.type(chipComponent, "{enter}"); | ||
await waitFor(() => { | ||
expect(chipComponent).toHaveAttribute("aria-checked", "true"); | ||
}); | ||
userEvent.type(chipComponent, "{enter}"); | ||
await waitFor(() => { | ||
expect(chipComponent).toHaveAttribute("aria-checked", "false"); | ||
}); | ||
}); | ||
|
||
it("should toggle state when Space key is pressed", async () => { | ||
const chipComponent = renderChip.getByRole("checkbox"); | ||
|
||
await userEvent.type(chipComponent, "{space}"); | ||
expect(chipComponent).toHaveAttribute("aria-checked", "true"); | ||
await userEvent.type(chipComponent, "{space}"); | ||
expect(chipComponent).toHaveAttribute("aria-checked", "false"); | ||
}); | ||
}); | ||
|
||
describe("Chip disabled Test", () => { | ||
let renderChip: RenderResult; | ||
beforeEach(() => { | ||
renderChip = render(<Chip disabled={true} label="Chip" />); | ||
}); | ||
|
||
it("should render with attributes aria-disabled to be true", () => { | ||
const chipComponent = renderChip.getByRole("contentinfo"); | ||
|
||
expect(chipComponent).toHaveAttribute("aria-disabled", "true"); | ||
}); | ||
|
||
it("should not allow focusing", () => { | ||
const chipComponent = renderChip.getByRole("contentinfo"); | ||
userEvent.click(chipComponent); | ||
|
||
expect(chipComponent).not.toHaveFocus(); | ||
}); | ||
}); | ||
|
||
describe("external control and events", () => { | ||
let renderChip: RenderResult; | ||
|
||
it("should fire external onClick event", async () => { | ||
renderChip = render(<Chip clickable label="Chip" />); | ||
const chipComponent = renderChip.getByRole("checkbox"); | ||
const user = userEvent.setup(); | ||
const onClickHandler = jest.fn(); | ||
chipComponent.onclick = onClickHandler; | ||
|
||
await user.click(chipComponent); | ||
expect(onClickHandler).toHaveBeenCalled(); | ||
}); | ||
|
||
it("should fire external onKeyDown event", async () => { | ||
renderChip = render(<Chip clickable as="button" label="Chip" />); | ||
const user = userEvent.setup(); | ||
const chipComponent = renderChip.getByRole("checkbox"); | ||
const onKeyDownHandler = jest.fn(); | ||
chipComponent.onkeydown = onKeyDownHandler; | ||
|
||
await user.type(chipComponent, "{enter}"); | ||
expect(onKeyDownHandler).toHaveBeenCalled(); | ||
await user.type(chipComponent, "{space}"); | ||
expect(onKeyDownHandler).toHaveBeenCalled(); | ||
}); | ||
|
||
it("should toggle external checked state when onClick event fired", async () => { | ||
const user = userEvent.setup(); | ||
let checked = false; | ||
const handleChange = () => { | ||
checked = !checked; | ||
}; | ||
const rendered = render(<Chip clickable as="button" label="Chip" />); | ||
const chipComponent = rendered.getByRole("checkbox"); | ||
chipComponent.onchange = handleChange; | ||
|
||
await user.click(chipComponent); | ||
|
||
expect(chipComponent).toHaveAttribute("aria-checked", "true"); | ||
expect(chipComponent).toHaveAttribute("aria-disabled", "false"); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,11 +75,10 @@ const Chip: ChipComponent & { displayName?: string } = forwardRef( | |
defaultChecked = false, | ||
disabled = false, | ||
style, | ||
...rest | ||
}: ChipProps<T>, | ||
ref: any | ||
) => { | ||
const Component = as || "button"; | ||
const Component = (as || "button") as React.ElementType; | ||
const [isChecked, setIsChecked] = useState(() => | ||
checkedProp ? checkedProp : defaultChecked | ||
); | ||
|
@@ -92,25 +91,28 @@ const Chip: ChipComponent & { displayName?: string } = forwardRef( | |
const handleClick = () => { | ||
if (disabled) return; | ||
onClick?.(); | ||
clickable ? setIsChecked((prev) => !prev) : null; | ||
clickable ? setIsChecked((prev: boolean) => !prev) : null; | ||
}; | ||
|
||
const handleKeyDown = (event: any) => { | ||
if (!clickable || disabled) return; | ||
if (event.currentTarget === event.target) { | ||
event.preventDefault(); | ||
if (event.key === "Enter" || event.key === " ") { | ||
setIsChecked((prev) => !prev); | ||
setIsChecked((prev: boolean) => !prev); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p4; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CI/CD로 test를 진행할 때 타입 추론을 추가해주지 않으면 타입스크립트 에러로 테스트가 터지더라구요.. cry |
||
onKeyDown?.(); | ||
} | ||
} | ||
}; | ||
|
||
return ( | ||
<Component | ||
aria-checked={clickable ? isChecked : undefined} | ||
aria-disabled={disabled} | ||
aria-label={`chip ${isChecked ? "activated" : "inactivated"}`} | ||
data-selected={isChecked} | ||
ref={ref} | ||
role={clickable ? "checkbox" : "contentinfo"} | ||
style={style} | ||
className={chip({ | ||
clickable: disabled ? false : clickable, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ask;
typescript 가 install 되어있지 않으면 test ci가 실패로 뜨나요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chip 컴포넌트에 대한 테스트를 진행할 때 타입에러가 자꾸 발견하여 typescript 문제인가 하여서 혹쉬..! 설치 과정을 넣어놓았어요. 오늘 확인해보니까 타입스크립트는 별로 잘못이 없는 친구라는게 드러나서 워크플로우에서 지웠습니다 😃