import isAfter from 'date-fns/isAfter';

isAfter(new Date(), new Date(DATE))

날짜 비교 할 일이 있어서 별 생각 없이 new Date를 때렸는데 safari에서 안되는 문제가 발견되었다. 콘솔을 확인해보니 yyyy-MM-dd HH:mm:ss 해당 형태의 포멧 에서는 안된다. 평소에 new Date 보다는 moment나 date-fns같은 라이브러리를 당연하게 써오다 보니 몰랐다. 그런데 또 다른 생각을 해보자면 저런 문제가 있기 때문에 더 적극적으로 라이브러리를 사용해야 한다는 게 함정.

import isAfter from 'date-fns/isAfter';
import format from 'date-fns/format';

isAfter(new Date(), format(DATE))
#159
import {
  addDays,
  addMonths,
  eachDayOfInterval,
  eachWeekOfInterval,
  startOfMonth,
} from 'date-fns'

const startOfMonthDate = startOfMonth(new Date())
const matrix = eachWeekOfInterval({
  start: startOfMonthDate,
  end: addMonths(startOfMonthDate, 1),
}).map((weekDay) => {
  const startDate = new Date(weekDay)

  return eachDayOfInterval({
    start: startDate,
    end: addDays(startDate, 6),
  })
})
#29

Never Call new Date() Inside Your Components never-call-new-date-inside-your-components

function Today({ date = formatDate(new Date()) }) {
  return <label>{date}</label>
}

컴포넌트 내에서 new Date()와 같은 비순수한 함수를 호출하면, 호출할 때마다 결과가 달라집니다. 이는 테스트에서 일관된 결과를 기대할 수 없게 만들어, 테스트가 불안정해질 수 있습니다. 코드 변경 없이도 테스트가 때로는 통과하고, 때로는 실패하는 Flaky Test를 유발할 수 있습니다.

순수하지 않은 함수의 결과나 함수를 prop으로 전달함으로써 컴포넌트가 더 예측 가능해지고, 테스트하기 쉬워집니다. 이렇게 하면 테스트 시 특정 날짜를 제어할 수 있어, 일관적이고 신뢰할 수 있는 테스트 결과를 얻을 수 있습니다.

기본 매개변수를 사용하면 개발자 경험이 향상됩니다. 기본 동작(new Date()로 오늘 날짜를 얻는 것)을 유지하면서도, 테스트 중 특정 값을 제공할 수 있는 유연성을 유지할 수 있습니다.

#314

vitest와 jest에서 가짜 타이머를 사용하는 방법. 내부적으로는 @sinonjs/fake-timers를 사용. vitest와 jest 모두 시스템 시간을 조작할 수 있도록 하여 테스트가 일관되게 실행되도록 하고 다양한 시간과 날짜를 시뮬레이션하여 다양한 조건에서 코드가 예상대로 작동하는지 확인할 수 있음.

describe('isSameDate', () => {
  beforeEach(() => {
    vi.useFakeTimers()
    vi.setSystemTime('2024-07-20')
  })

  afterEach(() => {
    vi.useRealTimers()
  })

  it('현재 날짜와 동일한 날짜를 전달하면 true를 반환한다', () => {
    expect(isSameDate('2024-07-20')).toBe(true)
  })

  it('현재 날짜와 다른 날짜를 전달하면 false를 반환한다', () => {
    expect(isSameDate('2024-07-19')).toBe(false)
    expect(isSameDate('2024-07-21')).toBe(false)
  })
})

#315