diff --git a/src/__tests__/unit/easy.dateUtils.spec.ts b/src/__tests__/unit/easy.dateUtils.spec.ts index 967bfacd..4b585258 100644 --- a/src/__tests__/unit/easy.dateUtils.spec.ts +++ b/src/__tests__/unit/easy.dateUtils.spec.ts @@ -12,105 +12,247 @@ import { } from '../../utils/dateUtils'; describe('getDaysInMonth', () => { - it('1월은 31일 수를 반환한다', () => {}); - - it('4월은 30일 일수를 반환한다', () => {}); - - it('윤년의 2월에 대해 29일을 반환한다', () => {}); - - it('평년의 2월에 대해 28일을 반환한다', () => {}); - - it('유효하지 않은 월에 대해 적절히 처리한다', () => {}); + it('1월은 31일 수를 반환한다', () => { + expect(getDaysInMonth(2025, 1)).toBe(31); + }); + + it('4월은 30일 일수를 반환한다', () => { + expect(getDaysInMonth(2025, 4)).toBe(30); + }); + + it('윤년의 2월에 대해 29일을 반환한다', () => { + expect(getDaysInMonth(2024, 2)).toBe(29); + }); + + it('평년의 2월에 대해 28일을 반환한다', () => { + expect(getDaysInMonth(2025, 2)).toBe(28); + }); + + it('유효하지 않은 월에 대해 적절히 처리한다', () => { + expect(getDaysInMonth(2025, 0)).toBe(31); + expect(getDaysInMonth(2025, 13)).toBe(31); + expect(getDaysInMonth(2025, -1)).toBe(30); + }); }); describe('getWeekDates', () => { - it('주중의 날짜(수요일)에 대해 올바른 주의 날짜들을 반환한다', () => {}); - - it('주의 시작(월요일)에 대해 올바른 주의 날짜들을 반환한다', () => {}); - - it('주의 끝(일요일)에 대해 올바른 주의 날짜들을 반환한다', () => {}); - - it('연도를 넘어가는 주의 날짜를 정확히 처리한다 (연말)', () => {}); - - it('연도를 넘어가는 주의 날짜를 정확히 처리한다 (연초)', () => {}); - - it('윤년의 2월 29일을 포함한 주를 올바르게 처리한다', () => {}); - - it('월의 마지막 날짜를 포함한 주를 올바르게 처리한다', () => {}); + it('주중의 날짜(수요일)에 대해 올바른 주의 날짜들을 반환한다', () => { + const dates = getWeekDates(new Date(2025, 6, 9)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2025-07-06'); + expect(strs[6]).toBe('2025-07-12'); + }); + + it('주의 시작(월요일)에 대해 올바른 주의 날짜들을 반환한다', () => { + const dates = getWeekDates(new Date(2025, 6, 7)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2025-07-06'); + expect(strs[6]).toBe('2025-07-12'); + }); + + it('주의 끝(일요일)에 대해 올바른 주의 날짜들을 반환한다', () => { + const dates = getWeekDates(new Date(2025, 6, 6)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2025-07-06'); + expect(strs[6]).toBe('2025-07-12'); + }); + + it('연도를 넘어가는 주의 날짜를 정확히 처리한다 (연말)', () => { + const dates = getWeekDates(new Date(2024, 11, 31)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2024-12-29'); + expect(strs[6]).toBe('2025-01-04'); + }); + + it('연도를 넘어가는 주의 날짜를 정확히 처리한다 (연초)', () => { + const dates = getWeekDates(new Date(2025, 0, 1)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2024-12-29'); + expect(strs[6]).toBe('2025-01-04'); + }); + + it('윤년의 2월 29일을 포함한 주를 올바르게 처리한다', () => { + const dates = getWeekDates(new Date(2024, 1, 29)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2024-02-25'); + expect(strs[6]).toBe('2024-03-02'); + }); + + it('월의 마지막 날짜를 포함한 주를 올바르게 처리한다', () => { + const dates = getWeekDates(new Date(2025, 3, 30)); + const strs = dates.map((d) => formatDate(d)); + expect(strs[0]).toBe('2025-04-27'); + expect(strs[6]).toBe('2025-05-03'); + }); }); describe('getWeeksAtMonth', () => { - it('2025년 7월 1일의 올바른 주 정보를 반환해야 한다', () => {}); + it('2025년 7월 1일의 올바른 주 정보를 반환해야 한다', () => { + const weeks = getWeeksAtMonth(new Date(2025, 6, 1)); + expect(weeks).toEqual([ + [null, null, 1, 2, 3, 4, 5], + [6, 7, 8, 9, 10, 11, 12], + [13, 14, 15, 16, 17, 18, 19], + [20, 21, 22, 23, 24, 25, 26], + [27, 28, 29, 30, 31, null, null], + ]); + }); }); describe('getEventsForDay', () => { - it('특정 날짜(1일)에 해당하는 이벤트만 정확히 반환한다', () => {}); - - it('해당 날짜에 이벤트가 없을 경우 빈 배열을 반환한다', () => {}); - - it('날짜가 0일 경우 빈 배열을 반환한다', () => {}); - - it('날짜가 32일 이상인 경우 빈 배열을 반환한다', () => {}); + const makeEvent = (id: string, y: number, m: number, d: number): Event => ({ + id, + title: `e${id}`, + date: formatDate(new Date(y, m, d)), + startTime: '09:00', + endTime: '10:00', + description: '', + location: '', + category: 'default', + repeat: { type: 'none', interval: 1 }, + notificationTime: 0, + }); + + const events: Event[] = [ + makeEvent('1', 2025, 6, 1), + makeEvent('2', 2025, 6, 1), + makeEvent('3', 2025, 6, 2), + makeEvent('4', 2025, 6, 15), + ]; + + it('특정 날짜(1일)에 해당하는 이벤트만 정확히 반환한다', () => { + const result = getEventsForDay(events, 1); + expect(result.map((e) => e.id)).toEqual(['1', '2']); + }); + + it('해당 날짜에 이벤트가 없을 경우 빈 배열을 반환한다', () => { + const result = getEventsForDay(events, 3); + expect(result).toEqual([]); + }); + + it('날짜가 0일 경우 빈 배열을 반환한다', () => { + const result = getEventsForDay(events, 0); + expect(result).toEqual([]); + }); + + it('날짜가 32일 이상인 경우 빈 배열을 반환한다', () => { + const result = getEventsForDay(events, 32); + expect(result).toEqual([]); + }); }); describe('formatWeek', () => { - it('월의 중간 날짜에 대해 올바른 주 정보를 반환한다', () => {}); + it('월의 중간 날짜에 대해 올바른 주 정보를 반환한다', () => { + expect(formatWeek(new Date(2025, 6, 10))).toBe('2025년 7월 2주'); + }); - it('월의 첫 주에 대해 올바른 주 정보를 반환한다', () => {}); + it('월의 첫 주에 대해 올바른 주 정보를 반환한다', () => { + expect(formatWeek(new Date(2025, 6, 1))).toBe('2025년 7월 1주'); + }); - it('월의 마지막 주에 대해 올바른 주 정보를 반환한다', () => {}); + it('월의 마지막 주에 대해 올바른 주 정보를 반환한다', () => { + expect(formatWeek(new Date(2025, 6, 31))).toBe('2025년 7월 5주'); + }); - it('연도가 바뀌는 주에 대해 올바른 주 정보를 반환한다', () => {}); + it('연도가 바뀌는 주에 대해 올바른 주 정보를 반환한다', () => { + expect(formatWeek(new Date(2024, 11, 31))).toBe('2025년 1월 1주'); + }); - it('윤년 2월의 마지막 주에 대해 올바른 주 정보를 반환한다', () => {}); + it('윤년 2월의 마지막 주에 대해 올바른 주 정보를 반환한다', () => { + expect(formatWeek(new Date(2024, 1, 29))).toBe('2024년 2월 5주'); + }); - it('평년 2월의 마지막 주에 대해 올바른 주 정보를 반환한다', () => {}); + it('평년 2월의 마지막 주에 대해 올바른 주 정보를 반환한다', () => { + expect(formatWeek(new Date(2025, 1, 28))).toBe('2025년 2월 4주'); + }); }); describe('formatMonth', () => { - it("2025년 7월 10일을 '2025년 7월'로 반환한다", () => {}); + it("2025년 7월 10일을 '2025년 7월'로 반환한다", () => { + expect(formatMonth(new Date(2025, 6, 10))).toBe('2025년 7월'); + }); }); describe('isDateInRange', () => { - it('범위 내의 날짜 2025-07-10에 대해 true를 반환한다', () => {}); + const d = (y: number, m0: number, day: number) => new Date(y, m0, day); + + it('범위 내의 날짜 2025-07-10에 대해 true를 반환한다', () => { + expect(isDateInRange(d(2025, 6, 10), d(2025, 6, 1), d(2025, 6, 31))).toBe(true); + }); - it('범위의 시작일 2025-07-01에 대해 true를 반환한다', () => {}); + it('범위의 시작일 2025-07-01에 대해 true를 반환한다', () => { + expect(isDateInRange(d(2025, 6, 1), d(2025, 6, 1), d(2025, 6, 31))).toBe(true); + }); - it('범위의 종료일 2025-07-31에 대해 true를 반환한다', () => {}); + it('범위의 종료일 2025-07-31에 대해 true를 반환한다', () => { + expect(isDateInRange(d(2025, 6, 31), d(2025, 6, 1), d(2025, 6, 31))).toBe(true); + }); - it('범위 이전의 날짜 2025-06-30에 대해 false를 반환한다', () => {}); + it('범위 이전의 날짜 2025-06-30에 대해 false를 반환한다', () => { + expect(isDateInRange(d(2025, 5, 30), d(2025, 6, 1), d(2025, 6, 31))).toBe(false); + }); - it('범위 이후의 날짜 2025-08-01에 대해 false를 반환한다', () => {}); + it('범위 이후의 날짜 2025-08-01에 대해 false를 반환한다', () => { + expect(isDateInRange(d(2025, 7, 1), d(2025, 6, 1), d(2025, 6, 31))).toBe(false); + }); - it('시작일이 종료일보다 늦은 경우 모든 날짜에 대해 false를 반환한다', () => {}); + it('시작일이 종료일보다 늦은 경우 모든 날짜에 대해 false를 반환한다', () => { + expect(isDateInRange(d(2025, 6, 10), d(2025, 6, 31), d(2025, 6, 1))).toBe(false); + }); }); describe('fillZero', () => { - it("5를 2자리로 변환하면 '05'를 반환한다", () => {}); + it("5를 2자리로 변환하면 '05'를 반환한다", () => { + expect(fillZero(5, 2)).toBe('05'); + }); - it("10을 2자리로 변환하면 '10'을 반환한다", () => {}); + it("10을 2자리로 변환하면 '10'을 반환한다", () => { + expect(fillZero(10, 2)).toBe('10'); + }); - it("3을 3자리로 변환하면 '003'을 반환한다", () => {}); + it("3을 3자리로 변환하면 '003'을 반환한다", () => { + expect(fillZero(3, 3)).toBe('003'); + }); - it("100을 2자리로 변환하면 '100'을 반환한다", () => {}); + it("100을 2자리로 변환하면 '100'을 반환한다", () => { + expect(fillZero(100, 2)).toBe('100'); + }); - it("0을 2자리로 변환하면 '00'을 반환한다", () => {}); + it("0을 2자리로 변환하면 '00'을 반환한다", () => { + expect(fillZero(0, 2)).toBe('00'); + }); - it("1을 5자리로 변환하면 '00001'을 반환한다", () => {}); + it("1을 5자리로 변환하면 '00001'을 반환한다", () => { + expect(fillZero(1, 5)).toBe('00001'); + }); - it("소수점이 있는 3.14를 5자리로 변환하면 '03.14'를 반환한다", () => {}); + it("소수점이 있는 3.14를 5자리로 변환하면 '03.14'를 반환한다", () => { + expect(fillZero(3.14, 5)).toBe('03.14'); + }); - it('size 파라미터를 생략하면 기본값 2를 사용한다', () => {}); + it('size 파라미터를 생략하면 기본값 2를 사용한다', () => { + expect(fillZero(7)).toBe('07'); + }); - it('value가 지정된 size보다 큰 자릿수를 가지면 원래 값을 그대로 반환한다', () => {}); + it('value가 지정된 size보다 큰 자릿수를 가지면 원래 값을 그대로 반환한다', () => { + expect(fillZero(1234, 2)).toBe('1234'); + }); }); describe('formatDate', () => { - it('날짜를 YYYY-MM-DD 형식으로 포맷팅한다', () => {}); + it('날짜를 YYYY-MM-DD 형식으로 포맷팅한다', () => { + expect(formatDate(new Date('2025-07-10'))).toBe('2025-07-10'); + }); - it('day 파라미터가 제공되면 해당 일자로 포맷팅한다', () => {}); + it('day 파라미터가 제공되면 해당 일자로 포맷팅한다', () => { + expect(formatDate(new Date(2025, 6, 10), 1)).toBe('2025-07-01'); + }); - it('월이 한 자리 수일 때 앞에 0을 붙여 포맷팅한다', () => {}); + it('월이 한 자리 수일 때 앞에 0을 붙여 포맷팅한다', () => { + expect(formatDate(new Date(2025, 0, 15))).toBe('2025-01-15'); + }); - it('일이 한 자리 수일 때 앞에 0을 붙여 포맷팅한다', () => {}); + it('일이 한 자리 수일 때 앞에 0을 붙여 포맷팅한다', () => { + expect(formatDate(new Date(2025, 6, 5))).toBe('2025-07-05'); + }); }); diff --git a/src/__tests__/unit/easy.eventOverlap.spec.ts b/src/__tests__/unit/easy.eventOverlap.spec.ts index 5e5f6497..7bbeb78b 100644 --- a/src/__tests__/unit/easy.eventOverlap.spec.ts +++ b/src/__tests__/unit/easy.eventOverlap.spec.ts @@ -5,32 +5,101 @@ import { isOverlapping, parseDateTime, } from '../../utils/eventOverlap'; + +const makeEvent = (overrides?: Partial): Event => ({ + id: '1', + title: 'title', + date: '2025-07-01', + startTime: '10:00', + endTime: '11:00', + description: '', + location: '', + category: '', + repeat: { type: 'none', interval: 1 }, + notificationTime: 0, + ...overrides, +}); + describe('parseDateTime', () => { - it('2025-07-01 14:30을 정확한 Date 객체로 변환한다', () => {}); + it('2025-07-01 14:30을 정확한 Date 객체로 변환한다', () => { + const parsedDateTime = parseDateTime('2025-07-01', '14:30'); + expect(parsedDateTime.getTime()).toBe(new Date('2025-07-01T14:30').getTime()); + }); - it('잘못된 날짜 형식에 대해 Invalid Date를 반환한다', () => {}); + it('잘못된 날짜 형식에 대해 Invalid Date를 반환한다', () => { + const parsedDateTime = parseDateTime('invalid-date', '14:30'); + expect(Number.isNaN(parsedDateTime.getTime())).toBe(true); + }); - it('잘못된 시간 형식에 대해 Invalid Date를 반환한다', () => {}); + it('잘못된 시간 형식에 대해 Invalid Date를 반환한다', () => { + const parsedDateTime = parseDateTime('2025-07-01', '25:61'); + expect(Number.isNaN(parsedDateTime.getTime())).toBe(true); + }); - it('날짜 문자열이 비어있을 때 Invalid Date를 반환한다', () => {}); + it('날짜 문자열이 비어있을 때 Invalid Date를 반환한다', () => { + const parsedDateTime = parseDateTime('', '10:00'); + expect(Number.isNaN(parsedDateTime.getTime())).toBe(true); + }); }); describe('convertEventToDateRange', () => { - it('일반적인 이벤트를 올바른 시작 및 종료 시간을 가진 객체로 변환한다', () => {}); + it('일반적인 이벤트를 올바른 시작 및 종료 시간을 가진 객체로 변환한다', () => { + const event = makeEvent({ date: '2025-07-01', startTime: '09:15', endTime: '10:45' }); + const range = convertEventToDateRange(event); + expect(range.start.getTime()).toBe(new Date('2025-07-01T09:15').getTime()); + expect(range.end.getTime()).toBe(new Date('2025-07-01T10:45').getTime()); + }); - it('잘못된 날짜 형식의 이벤트에 대해 Invalid Date를 반환한다', () => {}); + it('잘못된 날짜 형식의 이벤트에 대해 Invalid Date를 반환한다', () => { + const event = makeEvent({ date: 'invalid-date' }); + const range = convertEventToDateRange(event); + expect(Number.isNaN(range.start.getTime())).toBe(true); + expect(Number.isNaN(range.end.getTime())).toBe(true); + }); - it('잘못된 시간 형식의 이벤트에 대해 Invalid Date를 반환한다', () => {}); + it('잘못된 시간 형식의 이벤트에 대해 Invalid Date를 반환한다', () => { + const event = makeEvent({ startTime: '25:00' }); + const range = convertEventToDateRange(event); + expect(Number.isNaN(range.start.getTime())).toBe(true); + expect(range.end.getTime()).toBe(new Date('2025-07-01T11:00').getTime()); + }); }); describe('isOverlapping', () => { - it('두 이벤트가 겹치는 경우 true를 반환한다', () => {}); + it('두 이벤트가 겹치는 경우 true를 반환한다', () => { + const a = makeEvent({ startTime: '10:00', endTime: '11:00' }); + const b = makeEvent({ id: 'e2', startTime: '10:30', endTime: '11:30' }); + expect(isOverlapping(a, b)).toBe(true); + }); - it('두 이벤트가 겹치지 않는 경우 false를 반환한다', () => {}); + it('두 이벤트가 겹치지 않는 경우 false를 반환한다', () => { + const a = makeEvent({ startTime: '10:00', endTime: '11:00' }); + const b = makeEvent({ id: 'e2', startTime: '11:00', endTime: '12:00' }); + expect(isOverlapping(a, b)).toBe(false); + }); }); describe('findOverlappingEvents', () => { - it('새 이벤트와 겹치는 모든 이벤트를 반환한다', () => {}); + it('새 이벤트와 겹치는 모든 이벤트를 반환한다', () => { + const newEvent = makeEvent({ id: '1', startTime: '10:00', endTime: '11:00' }); + const events: Event[] = [ + makeEvent({ id: '1', startTime: '10:00', endTime: '11:00' }), + makeEvent({ id: '2', startTime: '10:30', endTime: '10:55' }), + makeEvent({ id: '3', startTime: '11:00', endTime: '12:00' }), + makeEvent({ id: '4', startTime: '09:00', endTime: '10:00' }), + makeEvent({ id: '5', startTime: '10:59', endTime: '11:01' }), + ]; + const result = findOverlappingEvents(newEvent, events); + expect(result.map((e) => e.id).sort()).toEqual(['2', '5']); + }); - it('겹치는 이벤트가 없으면 빈 배열을 반환한다', () => {}); + it('겹치는 이벤트가 없으면 빈 배열을 반환한다', () => { + const newEvent = makeEvent({ id: '10', startTime: '10:00', endTime: '11:00' }); + const events: Event[] = [ + makeEvent({ id: 'a', startTime: '08:00', endTime: '09:00' }), + makeEvent({ id: 'b', startTime: '11:00', endTime: '12:00' }), + ]; + const result = findOverlappingEvents(newEvent, events); + expect(result).toEqual([]); + }); }); diff --git a/src/__tests__/unit/easy.eventUtils.spec.ts b/src/__tests__/unit/easy.eventUtils.spec.ts index 8eef6371..37be3474 100644 --- a/src/__tests__/unit/easy.eventUtils.spec.ts +++ b/src/__tests__/unit/easy.eventUtils.spec.ts @@ -1,20 +1,126 @@ import { Event } from '../../types'; import { getFilteredEvents } from '../../utils/eventUtils'; +const dateStr = (y: number, m: number, d: number) => + [y, String(m + 1).padStart(2, '0'), String(d).padStart(2, '0')].join('-'); + +const makeEvent = ( + id: string, + y: number, + m: number, + d: number, + overrides: Partial = {} +): Event => ({ + id, + title: id, + date: dateStr(y, m, d), + startTime: '09:00', + endTime: '10:00', + description: '', + location: '', + category: 'default', + repeat: { type: 'none', interval: 1 }, + notificationTime: 10, + ...overrides, +}); + describe('getFilteredEvents', () => { - it("검색어 '이벤트 2'에 맞는 이벤트만 반환한다", () => {}); + it("검색어 '이벤트 2'에 맞는 이벤트만 반환한다", () => { + const events: Event[] = [ + makeEvent('이벤트 1', 2025, 6, 1), + makeEvent('이벤트 2', 2025, 6, 2), + makeEvent('이벤트 3', 2025, 6, 3), + ]; + + const result = getFilteredEvents(events, '이벤트 2', new Date(2025, 6, 1), 'month'); + + expect(result).toHaveLength(1); + expect(result[0].title).toBe('이벤트 2'); + }); + + it('주간 뷰에서 2025-07-01 주의 이벤트만 반환한다', () => { + const events: Event[] = [ + makeEvent('이벤트 1', 2025, 5, 28), + makeEvent('이벤트 2', 2025, 5, 29), + makeEvent('이벤트 3', 2025, 6, 1), + makeEvent('이벤트 4', 2025, 6, 5), + makeEvent('이벤트 5', 2025, 6, 6), + ]; + + const currentDate = new Date(2025, 6, 1); + const result = getFilteredEvents(events, '', currentDate, 'week'); + + const titles = result.map((e) => e.title); + expect(titles).toEqual(['이벤트 2', '이벤트 3', '이벤트 4']); + }); + + it('월간 뷰에서 2025년 7월의 모든 이벤트를 반환한다', () => { + const events: Event[] = [ + makeEvent('이벤트 1', 2025, 5, 30), + makeEvent('이벤트 2', 2025, 6, 1), + makeEvent('이벤트 3', 2025, 6, 15), + makeEvent('이벤트 4', 2025, 6, 31), + makeEvent('이벤트 5', 2025, 7, 1), + ]; + + const result = getFilteredEvents(events, '', new Date(2025, 6, 10), 'month'); + const titles = result.map((e) => e.title); + + expect(titles).toEqual(['이벤트 2', '이벤트 3', '이벤트 4']); + }); + + it("검색어 '이벤트'와 주간 뷰 필터링을 동시에 적용한다", () => { + const events: Event[] = [ + makeEvent('이벤트 1', 2025, 5, 29), + makeEvent('이벤트 2', 2025, 6, 1), + makeEvent('2벤트 3', 2025, 6, 3), + makeEvent('이벤트 4', 2025, 6, 5), + makeEvent('이벤트 5', 2025, 6, 6), + ]; + + const result = getFilteredEvents(events, '이벤트', new Date(2025, 6, 1), 'week'); + const titles = result.map((e) => e.title); + + expect(titles).toEqual(['이벤트 1', '이벤트 2', '이벤트 4']); + }); - it('주간 뷰에서 2025-07-01 주의 이벤트만 반환한다', () => {}); + it('검색어가 없을 때 모든 이벤트를 반환한다', () => { + const events: Event[] = [ + makeEvent('이벤트 1', 2025, 5, 29), + makeEvent('이벤트 2', 2025, 6, 1), + makeEvent('이벤트 3', 2025, 6, 5), + ]; - it('월간 뷰에서 2025년 7월의 모든 이벤트를 반환한다', () => {}); + const result = getFilteredEvents(events, '', new Date(2025, 6, 1), 'week'); + expect(result).toHaveLength(events.length); + expect(result.map((e) => e.id).sort()).toEqual(events.map((e) => e.id).sort()); + }); - it("검색어 '이벤트'와 주간 뷰 필터링을 동시에 적용한다", () => {}); + it('검색어가 대소문자를 구분하지 않고 작동한다', () => { + const events: Event[] = [ + makeEvent('Event 1', 2025, 6, 1), + makeEvent('event 2', 2025, 6, 2), + makeEvent('2vent 3', 2025, 6, 3), + ]; - it('검색어가 없을 때 모든 이벤트를 반환한다', () => {}); + const result = getFilteredEvents(events, 'EVENT', new Date(2025, 6, 1), 'week'); + expect(result.map((e) => e.title)).toEqual(['Event 1', 'event 2']); + }); - it('검색어가 대소문자를 구분하지 않고 작동한다', () => {}); + it('월의 경계에 있는 이벤트를 올바르게 필터링한다', () => { + const events: Event[] = [ + makeEvent('이벤트 1', 2025, 5, 30), + makeEvent('이벤트 2', 2025, 6, 1), + makeEvent('이벤트 3', 2025, 6, 31), + makeEvent('이벤트 4', 2025, 7, 1), + ]; - it('월의 경계에 있는 이벤트를 올바르게 필터링한다', () => {}); + const result = getFilteredEvents(events, '', new Date(2025, 6, 15), 'month'); + expect(result.map((e) => e.title)).toEqual(['이벤트 2', '이벤트 3']); + }); - it('빈 이벤트 리스트에 대해 빈 배열을 반환한다', () => {}); + it('빈 이벤트 리스트에 대해 빈 배열을 반환한다', () => { + const result = getFilteredEvents([], '', new Date(2025, 6, 1), 'week'); + expect(result).toEqual([]); + }); });