For date validation, I used luxon for my app. For each function I have made unit test. My unit test passed locally but when I deployed my code in gitlab, Most of my test failed. The expected result is so different than received. I don't understand what's the wrong. This my CD/CI pipeline images. Image-1, image-2, Image-3 and there are more. Basically all my test failed
My all test passed in code-sandbox
These are my all functions:
import {
DateTime
} from 'luxon'
export const DEFAULT_DATE_FORMAT = 'd.M.yyyy'
export const SHORT_TIME_FORMAT = 'HH:mm'
export const ISO_DATE_FORMAT = 'yyyy-MM-dd'
export const DATE_TIME_FORMAT = 'd.M.yyyy HH:mm'
export const DATE_MONTH_FORMAT = 'd.M'
export const WEEKDAYS = [
'SUNDAY',
'MONDAY',
'TUESDAY',
'WEDNESDAY',
'THURSDAY',
'FRIDAY',
'SATURDAY',
]
export const dateToStrings = (date: string | number | Date): DateTime =>
DateTime.fromISO(new Date(date).toISOString())
export const formatDateTime = (date: string | number | Date): string =>
dateToStrings(date).toFormat(DATE_TIME_FORMAT)
export const formatDateMonthYear = (date: string | number | Date): string =>
dateToStrings(date).toFormat(DEFAULT_DATE_FORMAT)
export const formatTime = (date: string | number | Date): string =>
dateToStrings(date).toFormat(SHORT_TIME_FORMAT)
export const NextDayFormatYearMonthDate = (date: string | number | Date): string =>
dateToStrings(date).plus({
days: 1
}).toFormat(ISO_DATE_FORMAT)
export const PreviousDayFormatYearMonthDate = (date: string | number | Date): string =>
dateToStrings(date).plus({
days: -1
}).toFormat(ISO_DATE_FORMAT)
export const dateDifference = (date: string | number | Date): number => {
const diff = dateToStrings(date).diff(DateTime.now(), 'days').toObject()
return Math.abs(Math.ceil(diff.days as number))
}
export const formatYearMonthDate = (date: Date | string | undefined): string => {
if (!date) {
// if date is undefined, return empty string
return ''
} else {
return dateToStrings(date).toFormat(ISO_DATE_FORMAT)
}
}
export const weekNumber = (date: string | Date): number =>
dateToStrings(date).startOf('week').weekNumber
export const nextWeek = (date: string | Date): string =>
dateToStrings(date).startOf('week').plus({
days: 7
}).toFormat(ISO_DATE_FORMAT)
export const previousWeek = (date: string | Date): string =>
dateToStrings(date).startOf('week').plus({
days: -7
}).toFormat(ISO_DATE_FORMAT)
export const firstDateOfWeek = (date: string | Date): string =>
dateToStrings(date).startOf('week').toFormat(ISO_DATE_FORMAT)
export const lastDateOfWeek = (date: string | Date): string =>
dateToStrings(date).startOf('week').plus({
days: 6
}).toFormat(ISO_DATE_FORMAT)
export const firstMondayOfTheWeekWithGMT = (date: Date): Date =>
dateToStrings(date).startOf('week').toJSDate()
export const formatDateMonth = (date: string | Date): string =>
dateToStrings(date).toFormat(DATE_MONTH_FORMAT)
export const shortDateString = (date: Date): string => {
const shortForm = dateToStrings(date).setLocale('fi').toFormat('EEE')
return shortForm.length > 1 ? `${shortForm.charAt(0).toUpperCase()}${shortForm.slice(1)}` : ''
}
export const hasSameDay = (date1: Date, date2: Date): boolean =>
dateToStrings(date1).hasSame(dateToStrings(date2), 'day')
export const isToday = (date: string | number | Date): boolean => {
return dateToStrings(date).toISODate() === DateTime.local().toISODate()
}
export const compareDays = (
date1: Date | string | number,
date2: Date | string | number,
): number => {
const compareWithDay = dateToStrings(date1).diff(dateToStrings(date2), ['days']).toObject()
return Math.abs(Math.ceil(compareWithDay.days as number))
}
This is my all tests
import {
formatDateTime,
formatDateMonthYear,
formatTime,
NextDayFormatYearMonthDate,
PreviousDayFormatYearMonthDate,
dateDifference,
formatYearMonthDate,
weekNumber,
nextWeek,
previousWeek,
firstDateOfWeek,
lastDateOfWeek,
formatDateMonth,
shortDateString,
compareDays,
DATE_MONTH_FORMAT,
DEFAULT_DATE_FORMAT,
SHORT_TIME_FORMAT,
ISO_DATE_FORMAT,
DATE_TIME_FORMAT,
} from 'utils/date'
import { DateTime } from 'luxon'
const toDateString = 'Mon Feb 07 2022 00:00:00 GMT 0200 (Eastern European Standard Time)'
const toISOString = '2018-05-01T13:44:48.708709Z'
const today = new Date()
const tomorrow = new Date(today.getTime() 24 * 60 * 60 * 1000)
const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000)
describe('formatDateTime', () => {
it('Should return format date time when date is string', () => {
expect(formatDateTime('2022-02-11T06:44:57 00:00')).toBe('7.2.2022 00:00')
})
it('Should return format date time when date is toISOString', () => {
expect(formatDateTime(toISOString)).toBe('1.5.2018 16:44')
})
it('Should return format date time when date is today', () => {
expect(formatDateTime(today)).toBe(
DateTime.fromISO(new Date().toISOString()).toFormat(DATE_TIME_FORMAT),
)
})
})
describe('formatDateMonthYear', () => {
it('Should return format date when date is string', () => {
expect(formatDateMonthYear(toDateString)).toBe('7.2.2022')
})
it('Should return format date when date is ISO String', () => {
expect(formatDateMonthYear(toISOString)).toBe('1.5.2018')
})
it('Should return format date when date is today', () => {
expect(formatDateMonthYear(today)).toBe(
DateTime.fromISO(new Date().toISOString()).toFormat(DEFAULT_DATE_FORMAT),
)
})
})
describe('formatTime', () => {
it('Should return 00:00 when there is no time', () => {
expect(formatTime(toDateString)).toBe('00:00')
})
it('Should return format time', () => {
expect(formatTime(toISOString)).toBe('16:44')
})
it('Should return format time when date is today', () => {
expect(formatTime(today)).toBe(
DateTime.fromISO(new Date().toISOString()).toFormat(SHORT_TIME_FORMAT),
)
})
})
describe('NextDayFormatYearMonthDate ', () => {
it('Should return next day format year when date is string', () => {
expect(NextDayFormatYearMonthDate(toDateString)).toBe('2022-02-08')
})
it('Should return next day format year when date is ISOString', () => {
expect(NextDayFormatYearMonthDate(toISOString)).toBe('2018-05-02')
})
it('Should return next day format year when date is today', () => {
expect(NextDayFormatYearMonthDate(today)).toBe(
DateTime.fromISO(new Date().toISOString()).plus({ days: 1 }).toFormat(ISO_DATE_FORMAT),
)
})
})
describe('PreviousDayFormatYearMonthDate', () => {
it('Should return next day format year when date is string', () => {
expect(PreviousDayFormatYearMonthDate(toDateString)).toBe('2022-02-06')
})
it('Should return next day format year when date is ISOString', () => {
expect(PreviousDayFormatYearMonthDate(toISOString)).toBe('2018-04-30')
})
it('Should return next day format year when date is today', () => {
expect(PreviousDayFormatYearMonthDate(today)).toBe(
DateTime.fromISO(new Date().toISOString()).plus({ days: -1 }).toFormat(ISO_DATE_FORMAT),
)
})
})
describe('dateDifference', () => {
it('Should return 0 when date is today', () => {
expect(dateDifference(today)).toBe(0)
})
it('Should return 1 when date is not today', () => {
expect(dateDifference(tomorrow)).toBe(1)
})
it('Should return 1 when date is not today', () => {
expect(dateDifference(yesterday)).toBe(1)
})
})
describe('formatYearMonthDate', () => {
it('Should return format date when date is string', () => {
expect(formatYearMonthDate(toDateString)).toBe('2022-02-07')
})
it('Should return format date when date is ISO String', () => {
expect(formatYearMonthDate(toISOString)).toBe('2018-05-01')
})
it('Should return format date when date is today', () => {
expect(formatYearMonthDate(today)).toBe(
DateTime.fromISO(new Date().toISOString()).toFormat(ISO_DATE_FORMAT),
)
})
it('Should return empty string when date is undefined', () => {
expect(formatYearMonthDate(undefined)).toBe('')
})
})
describe('weekNumber', () => {
it('Should return week number when date is string', () => {
expect(weekNumber(toDateString)).toBe(6)
})
it('Should return week number when date is ISO String', () => {
expect(weekNumber(toISOString)).toBe(18)
})
it('Should return week number when date is today', () => {
expect(weekNumber(today)).toBe(DateTime.fromISO(new Date().toISOString()).weekNumber)
})
})
describe('nextWeek', () => {
it('Should return next week date when date is string', () => {
expect(nextWeek(toDateString)).toBe('2022-02-14')
})
it('Should return next week date when date is ISO String', () => {
expect(nextWeek(toISOString)).toBe('2018-05-07')
})
})
describe('previousWeek', () => {
it('Should return previous week date when date is string', () => {
expect(previousWeek(toDateString)).toBe('2022-01-31')
})
it('Should return previous week date when date is ISO String', () => {
expect(previousWeek(toISOString)).toBe('2018-04-23')
})
})
describe('firstDateOfWeek', () => {
it('Should return first date of the week when date is string', () => {
expect(firstDateOfWeek(toDateString)).toBe('2022-02-07')
})
it('Should return first date of the week when date is ISO String', () => {
expect(firstDateOfWeek(toISOString)).toBe('2018-04-30')
})
})
describe('lastDateOfWeek', () => {
it('Should return first date of the week when date is string', () => {
expect(lastDateOfWeek(toDateString)).toBe('2022-02-13')
})
it('Should return first date of the week when date is ISO String', () => {
expect(lastDateOfWeek(toISOString)).toBe('2018-05-06')
})
})
describe('formatDateMonth', () => {
it('Should return format date month when date is string', () => {
expect(formatDateMonth(toDateString)).toBe('7.2')
})
it('Should return format date month when date is ISO String', () => {
expect(formatDateMonth(toISOString)).toBe('1.5')
})
it('Should return format date month when date is today', () => {
expect(formatDateMonth(today)).toBe(
DateTime.fromISO(new Date().toISOString()).toFormat(DATE_MONTH_FORMAT),
)
})
})
describe('shortDateString', () => {
it('Should return first two letters Finnish weekdays when date is string', () => {
expect(shortDateString(new Date(toDateString))).toBe('Ma')
})
it('Should return first two letters Finnish weekdays when date is ISO String', () => {
expect(shortDateString(new Date(toISOString))).toBe('Ti')
})
})
describe('compareDays', () => {
it('Should return 0 if the dates are same', () => {
expect(compareDays(new Date(toDateString), new Date(toDateString))).toBe(0)
})
it('Should return 0 if the dates are same', () => {
expect(compareDays(new Date(toDateString), new Date(toISOString))).toBe(1378)
})
it('Should return 0 if the dates are string', () => {
expect(compareDays(toDateString, toISOString)).toBe(1378)
})
})
CodePudding user response:
The difference has to do with the timezone of your local computer and the timezone of the GitLab runner. The GitLab runners use UTC timezone.
Take this case for example:
const toDateString = 'Mon Feb 07 2022 00:00:00 GMT 0200 (Eastern European Standard Time)'
// ...
describe('formatTime', () => {
it('Should return 00:00 when there is no time', () => {
expect(formatTime(toDateString)).toBe('00:00')
})
In your unit test results:
Expected: "00:00"
Received: "22:00"
This would pass if your local timezone is UTC 2, but would fail if your timezone is UTC. Mon Feb 07 2022 00:00:00 GMT 0200
is Sun Feb 06 2022 22:00:00
in UTC time.
From the luxon docs: (emphasis added)
A DateTime comprises of:
[...]
A time zone. Each instance is considered in the context of a specific zone (by default the local system's zone).
[...]
You'll probably want to normalize your tests to use a particular timezone. See this question for hints on how to change the timezone of the datetime objects.