Skip to content
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

feat(Control): Control 테스트코드 작성 #135

Merged
merged 11 commits into from
Sep 19, 2024
5 changes: 5 additions & 0 deletions .changeset/modern-pumas-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sopt-makers/ui': patch
---

add Control test code.
34 changes: 14 additions & 20 deletions packages/ui/Control/CheckBox.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,33 @@
import type { InputHTMLAttributes } from "react";
import { forwardRef } from "react";
import { IconCheck } from "@sopt-makers/icons";
import theme from "../theme.css";
import {
check,
checkBox,
checkBoxChecked,
checkBoxInput,
controlLabel,
controlWrapper,
} from "./style.css";
import type { InputHTMLAttributes } from 'react';
import { forwardRef } from 'react';
import { IconCheck } from '@sopt-makers/icons';
import theme from '../theme.css';
import { check, checkBox, checkBoxChecked, checkBoxInput, controlLabel, controlWrapper } from './style.css';

export interface CheckBoxProps
extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
export interface CheckBoxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
label?: string;
size?: "sm" | "lg";
size?: 'sm' | 'lg';
checked?: boolean;
color?: string;
}

const CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(
({ checked = false, label, size = "sm", color = theme.colors.gray10, ...props }, ref) => {
({ checked = false, label, size = 'sm', color = theme.colors.gray10, ...props }, ref) => {
return (
<label className={controlWrapper}>
<input className={checkBoxInput} ref={ref} type="checkbox" {...props} />
<input checked={checked} className={checkBoxInput} ref={ref} type='checkbox' {...props} />
<div className={`${checkBox[size]} ${checkBoxChecked[`${checked}`]}`}>
{checked ? <IconCheck className={check[size]} /> : null}
</div>
{label ? (
<p className={controlLabel[size]} style={{ color }}>{label}</p>
<p className={controlLabel[size]} style={{ color }}>
{label}
</p>
) : null}
</label>
);
}
},
);
CheckBox.displayName = "CheckBox";
CheckBox.displayName = 'CheckBox';

export default CheckBox;
42 changes: 42 additions & 0 deletions packages/ui/Control/test/Checkbox.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import type { CheckBoxProps } from 'Control/CheckBox';
import { CheckBox } from '../index';

describe('Checkbox의', () => {
function renderCheckbox(props?: CheckBoxProps) {
render(<CheckBox {...props} />);
}

describe('정상동작은 다음과 같다.', () => {
it('Checkbox 컴포넌트가 정상적으로 렌더링 된다.', () => {
renderCheckbox();

expect(screen.getByRole('checkbox')).toBeInTheDocument();
});

it('checked = true 이면 checkbox가 활성화된 상태로 렌더링된다.', () => {
renderCheckbox({ checked: true });

expect(screen.getByRole('checkbox')).toBeChecked();
});

it('checked = false 이면 checkbox가 비활성화된 상태로 렌더링된다.', () => {
renderCheckbox({ checked: false });

expect(screen.getByRole('checkbox')).not.toBeChecked();
});
});

describe('onClick 이벤트는 다음과 같다.', () => {
it('Checkbox를 클릭했을 때 onClick 핸들러가 호출된다.', () => {
const handleClick = vi.fn();
renderCheckbox({ onClick: handleClick });

const checkbox = screen.getByRole('checkbox');
fireEvent.click(checkbox);

expect(handleClick).toHaveBeenCalled();
});
});
});
42 changes: 42 additions & 0 deletions packages/ui/Control/test/Radio.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { RadioProps } from 'Control/Radio';
import { describe, expect, it, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { Radio } from '../index';

describe('Radio의', () => {
function renderRadio(props?: RadioProps) {
render(<Radio {...props} />);
}

describe('기본 동작은 다음과 같다.', () => {
it('Checkbox 컴포넌트가 정상적으로 렌더링 된다.', () => {
renderRadio();

expect(screen.getByRole('radio')).toBeInTheDocument();
});

it('checked = true 이면 checkbox가 활성화된 상태로 렌더링된다.', () => {
renderRadio({ checked: true });

expect(screen.getByRole('radio')).toBeChecked();
});

it('checked = false 이면 checkbox가 비활성화된 상태로 렌더링된다.', () => {
renderRadio({ checked: false });

expect(screen.getByRole('radio')).not.toBeChecked();
});
});

describe('onClick 이벤트는 다음과 같다.', () => {
it('Radio를 클릭했을 때 onClick 핸들러가 호출된다.', () => {
const handleClick = vi.fn();
renderRadio({ onClick: handleClick });

const radio = screen.getByRole('radio');
fireEvent.click(radio);

expect(handleClick).toHaveBeenCalled();
});
});
});
48 changes: 48 additions & 0 deletions packages/ui/Control/test/Toggle.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import type { ToggleProps } from 'Control/Toggle';
import { Toggle } from '../index';

describe('Toggle의', () => {
const mockOnCheckedChange = vi.fn();

function renderToggle(props: ToggleProps) {
render(<Toggle {...props} onCheckedChange={mockOnCheckedChange} />);
}

describe('기본 동작은 다음과 같다.', () => {
it('on 상태로 렌더링 될 수 있다.', () => {
renderToggle({ 'aria-checked': true });

const toggle = screen.getByRole('switch');

// aria-checked 상태를 확인
expect(toggle).toHaveAttribute('aria-checked', 'true');
});

it('off 상태로 렌더링 될 수 있다.', () => {
renderToggle({ 'aria-checked': false });

const toggle = screen.getByRole('switch');

// aria-checked 상태를 확인
expect(toggle).toHaveAttribute('aria-checked', 'false');
});
});

describe('onCheckedChange 이벤트는 다음과 같다.', () => {
beforeEach(() => {
mockOnCheckedChange.mockClear(); // 테스트마다 mock을 초기화
});

it('Toggle을 클릭했을 때 onCheckedChange 핸들러가 호출된다.', () => {
renderToggle({ 'aria-checked': false });

const toggle = screen.getByRole('switch');

fireEvent.click(toggle);

expect(mockOnCheckedChange).toHaveBeenCalledWith(true);
});
});
});
Loading