Skip to content

Commit

Permalink
[FE] 달력 테스트 코드 작성 (#383)
Browse files Browse the repository at this point in the history
* chore: 변경사항이 있을 때마다 테스트를 다시 실행할 수 있도록 --watch 속성 추가

* chore: @utils 절대 경로를 인식할 수 있도록 설정 추가

* refactor: 달력 데이터의 첫 날짜를 설정하는 코드를 함수로 분리, jsDoc 제거

* test: 달력 데이터를 생성하는 유틸 모듈 테스트 추가

* chore: 변수명, 함수명을 더 직관적으로 수정

* test: useCalendar 커스텀 훅 테스트 추가

- 달, 년 이동시 달력 데이터가 올바르게 변경 되는지 테스트
- 현재 달력 데이터를 생성할 때, 빈 공간을 prev & next 상태를 가진 날짜들로 만들어서 같이 계산해 주기 때문에 이와 관련된 로직 테스트 추가

* chore: watch 속성 제거

* chore: 특정 달의 첫 번째 날을 표현하는 변수명을 더 직관적으로 수정

* chore: 테스트 케이스를 더 직관적으로 개선

* test: 달력 데이터를 생성하는 유틸 함수 테스트 개선

- 자바스크립트 Date 객체 동작을 확인하는 테스트 제거
- 오타 수정
- 윤년 테스트 추가
- 특정 날짜의 상태를 테스트하는 로직 개선
  • Loading branch information
hwinkr authored Oct 13, 2024
1 parent 1ea14a4 commit a68817b
Show file tree
Hide file tree
Showing 5 changed files with 402 additions and 55 deletions.
5 changes: 5 additions & 0 deletions frontend/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ module.exports = {
},
setupFiles: ['./jest.polyfills.js'],
reporters: ['default', ['jest-junit', { outputDirectory: 'reports', outputName: 'report.xml' }]],

moduleNameMapper: {
'^@utils/(.*)$': '<rootDir>/src/utils/$1',
'^@constants/(.*)$': '<rootDir>/src/constants/$1',
},
};
175 changes: 175 additions & 0 deletions frontend/src/hooks/useCalendar/useCalendar.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react';

import { getFullDate } from '@utils/date';

import useCalendar from './useCalendar';

describe('useCalendar', () => {
const TEST_YEAR = 2024;
const TEST_MONTH = 9;
const TEST_DATE = 4;
const FIRST_MONTH_INDEX = 0;
const LAST_MONTH_INDEX = 11;

beforeAll(() => {
jest.useFakeTimers();
});

afterAll(() => {
jest.useRealTimers();
});

describe('현재 달력 데이터 계산', () => {
it('현재 년도, 월을 올바르게 계산해서 반환한다.', () => {
jest.setSystemTime(new Date(TEST_YEAR, TEST_MONTH, TEST_DATE));

const { result } = renderHook(() => useCalendar());

const { headers, isCurrentMonth } = result.current;
const { currentYear, currentMonth } = headers;

expect(currentYear).toBe(TEST_YEAR);
expect(currentMonth).toBe(TEST_MONTH);
expect(isCurrentMonth).toBeTruthy();
});
});

describe('달력 년도 이동 기능', () => {
it('12월에서 다음 달로 이동하면 다음 년도로 변경되어야 한다.', () => {
jest.setSystemTime(new Date(TEST_YEAR, LAST_MONTH_INDEX, TEST_DATE));

const { result } = renderHook(() => useCalendar());
const { view } = result.current;
const { moveToNextMonth } = view;

act(() => {
moveToNextMonth();
});

const { headers, isCurrentMonth } = result.current;
const { currentYear, currentMonth } = headers;

expect(currentYear).toBe(TEST_YEAR + 1);
expect(currentMonth).toBe(FIRST_MONTH_INDEX);
expect(isCurrentMonth).toBeFalsy();
});

it('1월에서 이전 년도로 이동하면 이전 년도로 변경되어야 한다.', () => {
jest.setSystemTime(new Date(TEST_YEAR, FIRST_MONTH_INDEX, TEST_DATE));

const { result } = renderHook(() => useCalendar());
const { view } = result.current;
const { moveToPrevMonth } = view;

act(() => {
moveToPrevMonth();
});

const { headers, isCurrentMonth } = result.current;
const { currentYear, currentMonth } = headers;

expect(currentYear).toBe(TEST_YEAR - 1);
expect(currentMonth).toBe(LAST_MONTH_INDEX);
expect(isCurrentMonth).toBeFalsy();
});
});

describe('달력 월 이동 기능', () => {
it('이전 달로 이동하면, 달 데이터가 변경되어야 한다.', () => {
jest.setSystemTime(new Date(TEST_YEAR, TEST_MONTH, TEST_DATE));

const { result } = renderHook(() => useCalendar());
const { view } = result.current;
const { moveToPrevMonth } = view;

act(() => {
moveToPrevMonth();
});

const { headers, isCurrentMonth } = result.current;
const { currentYear, currentMonth } = headers;

expect(currentYear).toBe(TEST_YEAR);
expect(currentMonth).toBe(TEST_MONTH - 1);
expect(isCurrentMonth).toBeFalsy();
});

it('다음 달로 이동하면 달 데이터가 변경되어야 한다..', () => {
jest.setSystemTime(new Date(TEST_YEAR, TEST_MONTH, TEST_DATE));

const { result } = renderHook(() => useCalendar());
const { view } = result.current;
const { moveToNextMonth } = view;

act(() => {
moveToNextMonth();
});

const { headers, isCurrentMonth } = result.current;
const { currentYear, currentMonth } = headers;

expect(currentYear).toBe(TEST_YEAR);
expect(currentMonth).toBe(TEST_MONTH + 1);
expect(isCurrentMonth).toBeFalsy();
});
});

describe('월 이동 시, 변경된 달력 데이터 계산', () => {
it('현재 달의 마지막 주에 있는 current 상태의 날짜들이 다음 달로 이동했을 때 prev 상태로 변경되어야 한다.', () => {
const { result } = renderHook(() => useCalendar());
const {
body: { value: initialCalendarData },
view: { moveToNextMonth },
} = result.current;
const lastWeekOfCurrentMonth = initialCalendarData[initialCalendarData.length - 1].value;
const currentDatesInLastWeek = lastWeekOfCurrentMonth.filter(
(day) => day.status === 'current',
);

act(() => {
moveToNextMonth();
});

const {
body: { value: updatedCalendarData },
} = result.current;
const firstWeekOfNextMonth = updatedCalendarData[0].value;
const prevDatesInFirstWeek = firstWeekOfNextMonth.filter((day) => day.status === 'prev');

expect(prevDatesInFirstWeek.length).toBe(currentDatesInLastWeek.length);
currentDatesInLastWeek.forEach((date, index) => {
expect(getFullDate(prevDatesInFirstWeek[index].value)).toBe(getFullDate(date.value));
expect(prevDatesInFirstWeek[index].status).toBe('prev');
});
});

it('현재 달의 첫 주에 있는 current 상태의 날짜들이 이전 달로 이동했을 때 next 상태로 변경되어야 한다.', () => {
const { result } = renderHook(() => useCalendar());
const {
body: { value: initialCalendarData },
view: { moveToPrevMonth },
} = result.current;
const firstWeekOfCurrentMonth = initialCalendarData[0].value;
const currentDatesInFirstWeek = firstWeekOfCurrentMonth.filter(
(day) => day.status === 'current',
);

act(() => {
moveToPrevMonth();
});

const {
body: { value: updatedCalendarData },
} = result.current;
const lastWeekOfPrevMonth = updatedCalendarData[updatedCalendarData.length - 1].value;
const nextDatesInLastWeek = lastWeekOfPrevMonth.filter((day) => day.status === 'next');

expect(nextDatesInLastWeek.length).toBe(currentDatesInFirstWeek.length);
currentDatesInFirstWeek.forEach((date, index) => {
expect(getFullDate(nextDatesInLastWeek[index].value)).toBe(getFullDate(date.value));
expect(nextDatesInLastWeek[index].status).toBe('next');
});
});
});
});
6 changes: 3 additions & 3 deletions frontend/src/hooks/useCalendar/useCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { MonthlyDays } from 'types/calendar';

import { getMonth, getYear } from '@utils/date';

import { getMonthlyDate } from './useCalendar.utils';
import { getMonthlyCalendarDate } from './useCalendar.utils';

interface useCalendarReturn {
headers: {
Expand Down Expand Up @@ -39,7 +39,7 @@ const useCalendar = (): useCalendarReturn => {
setCurrentFullDate(new Date(currentYear, currentMonth + 1));
};

const monthlyDates = getMonthlyDate(currentFullDate);
const monthlyCalendarDate = getMonthlyCalendarDate(currentFullDate);

return {
headers: {
Expand All @@ -49,7 +49,7 @@ const useCalendar = (): useCalendarReturn => {
},
body: {
today: TODAY,
value: monthlyDates,
value: monthlyCalendarDate,
},
view: {
moveToNextMonth,
Expand Down
Loading

0 comments on commit a68817b

Please sign in to comment.