mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 18:56:39 +00:00
Add tests for common/datetime (#23658)
This commit is contained in:
parent
31ed0f7bea
commit
853059ac73
@ -22,7 +22,9 @@ export const createDurationData = (
|
|||||||
hours: Number(parts[0]) || 0,
|
hours: Number(parts[0]) || 0,
|
||||||
minutes: Number(parts[1]) || 0,
|
minutes: Number(parts[1]) || 0,
|
||||||
seconds: seconds_whole,
|
seconds: seconds_whole,
|
||||||
milliseconds: Math.floor((seconds - seconds_whole) * 1000),
|
milliseconds: Math.floor(
|
||||||
|
Number((seconds - seconds_whole).toFixed(4)) * 1000
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { seconds: duration };
|
return { seconds: duration };
|
||||||
|
38
test/common/datetime/absolute_time.test.ts
Normal file
38
test/common/datetime/absolute_time.test.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import type { HassConfig } from "home-assistant-js-websocket";
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { absoluteTime } from "../../../src/common/datetime/absolute_time";
|
||||||
|
import {
|
||||||
|
TimeFormat,
|
||||||
|
TimeZone,
|
||||||
|
type FrontendLocaleData,
|
||||||
|
} from "../../../src/data/translation";
|
||||||
|
|
||||||
|
const locale: FrontendLocaleData = {
|
||||||
|
language: "en-US",
|
||||||
|
time_zone: TimeZone.server,
|
||||||
|
time_format: TimeFormat.twenty_four,
|
||||||
|
} as any;
|
||||||
|
const config: HassConfig = { time_zone: "UTC" } as any;
|
||||||
|
|
||||||
|
describe("absoluteTime", () => {
|
||||||
|
it("should format time correctly for same day", () => {
|
||||||
|
const from = new Date();
|
||||||
|
from.setUTCHours(13, 23);
|
||||||
|
const result = absoluteTime(from, locale, config);
|
||||||
|
expect(result).toBe("13:23");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should format date correctly for same year", () => {
|
||||||
|
const from = new Date();
|
||||||
|
from.setUTCMonth(9, 20);
|
||||||
|
from.setUTCHours(13, 23);
|
||||||
|
const result = absoluteTime(from, locale, config);
|
||||||
|
expect(result).toBe("Oct 20, 13:23");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should format date with year correctly", () => {
|
||||||
|
const from = new Date(2024, 1, 29, 13, 23);
|
||||||
|
const result = absoluteTime(from, locale, config);
|
||||||
|
expect(result).toBe("Feb 29, 2024, 13:23");
|
||||||
|
});
|
||||||
|
});
|
76
test/common/datetime/calc_date.test.ts
Normal file
76
test/common/datetime/calc_date.test.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import type { HassConfig } from "home-assistant-js-websocket";
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { addDays } from "date-fns";
|
||||||
|
import {
|
||||||
|
calcDate,
|
||||||
|
calcDateProperty,
|
||||||
|
calcDateDifferenceProperty,
|
||||||
|
shiftDateRange,
|
||||||
|
} from "../../../src/common/datetime/calc_date";
|
||||||
|
import {
|
||||||
|
type FrontendLocaleData,
|
||||||
|
TimeZone,
|
||||||
|
} from "../../../src/data/translation";
|
||||||
|
|
||||||
|
const locale: FrontendLocaleData = {
|
||||||
|
language: "en-US",
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
} as any;
|
||||||
|
const localeServer: FrontendLocaleData = {
|
||||||
|
language: "en-US",
|
||||||
|
time_zone: TimeZone.server,
|
||||||
|
} as any;
|
||||||
|
const config: HassConfig = { time_zone: "UTC" } as any;
|
||||||
|
|
||||||
|
describe("calcDate", () => {
|
||||||
|
it("should calculate date correctly", () => {
|
||||||
|
const date = new Date(2024, 1, 28);
|
||||||
|
const result = calcDate(date, addDays, locale, config, 1);
|
||||||
|
expect(result).toEqual(new Date(2024, 1, 29));
|
||||||
|
});
|
||||||
|
it("should calculate date correctly with server time zone", () => {
|
||||||
|
const date = new Date(2024, 1, 28);
|
||||||
|
const result = calcDate(date, addDays, localeServer, config, 1);
|
||||||
|
expect(result).toEqual(new Date(2024, 1, 29));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("calcDateProperty", () => {
|
||||||
|
it("should calculate date property correctly", () => {
|
||||||
|
const date = new Date(2023, 0, 1);
|
||||||
|
const options = "test-options";
|
||||||
|
const result = calcDateProperty(
|
||||||
|
date,
|
||||||
|
(d, o) => (o === options ? d.getDate() : false),
|
||||||
|
locale,
|
||||||
|
config,
|
||||||
|
options
|
||||||
|
);
|
||||||
|
expect(result).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("calcDateDifferenceProperty", () => {
|
||||||
|
it("should calculate date difference property correctly", () => {
|
||||||
|
const startDate = new Date(2023, 0, 1);
|
||||||
|
const endDate = new Date(2023, 0, 2);
|
||||||
|
const result = calcDateDifferenceProperty(
|
||||||
|
endDate,
|
||||||
|
startDate,
|
||||||
|
(d, o) => d.getDate() - o.getDate(),
|
||||||
|
locale,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
expect(result).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("shiftDateRange", () => {
|
||||||
|
it("should shift date range correctly", () => {
|
||||||
|
const startDate = new Date(2024, 0, 1);
|
||||||
|
const endDate = new Date(2024, 0, 31);
|
||||||
|
const result = shiftDateRange(startDate, endDate, true, locale, config);
|
||||||
|
expect(result.start).toEqual(new Date(2024, 1, 1));
|
||||||
|
expect(result.end).toEqual(new Date(2024, 1, 29, 23, 59, 59, 999));
|
||||||
|
});
|
||||||
|
});
|
45
test/common/datetime/create_duration_data.test.ts
Normal file
45
test/common/datetime/create_duration_data.test.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { createDurationData } from "../../../src/common/datetime/create_duration_data";
|
||||||
|
|
||||||
|
describe("createDurationData", () => {
|
||||||
|
it("should return undefined for undefined input", () => {
|
||||||
|
expect(createDurationData(undefined)).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse string duration correctly", () => {
|
||||||
|
expect(createDurationData("1:30:15.001")).toEqual({
|
||||||
|
hours: 1,
|
||||||
|
minutes: 30,
|
||||||
|
seconds: 15,
|
||||||
|
milliseconds: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(createDurationData("20")).toEqual({
|
||||||
|
seconds: 20,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return undefined for invalid string duration", () => {
|
||||||
|
expect(createDurationData("1:30:15:20")).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse number duration correctly", () => {
|
||||||
|
expect(createDurationData(3600)).toEqual({ seconds: 3600 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse object duration without days correctly", () => {
|
||||||
|
expect(createDurationData({ hours: 1, minutes: 30 })).toEqual({
|
||||||
|
hours: 1,
|
||||||
|
minutes: 30,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle days in object duration correctly", () => {
|
||||||
|
expect(createDurationData({ days: 1, hours: 1 })).toEqual({
|
||||||
|
hours: 25,
|
||||||
|
minutes: undefined,
|
||||||
|
seconds: undefined,
|
||||||
|
milliseconds: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
42
test/common/datetime/first_weekday.test.ts
Normal file
42
test/common/datetime/first_weekday.test.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import {
|
||||||
|
firstWeekday,
|
||||||
|
firstWeekdayIndex,
|
||||||
|
} from "../../../src/common/datetime/first_weekday";
|
||||||
|
import {
|
||||||
|
type FrontendLocaleData,
|
||||||
|
FirstWeekday,
|
||||||
|
} from "../../../src/data/translation";
|
||||||
|
|
||||||
|
const locale: FrontendLocaleData = {
|
||||||
|
language: "en-US",
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
} as any;
|
||||||
|
const mondayLocale: FrontendLocaleData = {
|
||||||
|
language: "en-US",
|
||||||
|
first_weekday: FirstWeekday.monday,
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
describe("firstWeekday", () => {
|
||||||
|
it("should return the correct weekday based on locale", () => {
|
||||||
|
expect(firstWeekday(locale)).toBe("sunday");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return the correct weekday index based on locale", () => {
|
||||||
|
expect(firstWeekdayIndex(locale)).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return the correct weekday when first_weekday is specified", () => {
|
||||||
|
expect(firstWeekday(mondayLocale)).toBe("monday");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return the correct weekday index when first_weekday is specified", () => {
|
||||||
|
expect(firstWeekdayIndex(mondayLocale)).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return the default weekday when first_weekday is not valid", () => {
|
||||||
|
expect(
|
||||||
|
firstWeekdayIndex({ language: "en-US", first_weekday: "invalid" } as any)
|
||||||
|
).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,16 @@
|
|||||||
import { assert, describe, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
import {
|
||||||
import { formatDate } from "../../../src/common/datetime/format_date";
|
formatDate,
|
||||||
|
formatDateWeekdayDay,
|
||||||
|
formatDateShort,
|
||||||
|
formatDateNumeric,
|
||||||
|
formatDateVeryShort,
|
||||||
|
formatDateMonthYear,
|
||||||
|
formatDateMonth,
|
||||||
|
formatDateYear,
|
||||||
|
formatDateWeekday,
|
||||||
|
formatDateWeekdayShort,
|
||||||
|
} from "../../../src/common/datetime/format_date";
|
||||||
import {
|
import {
|
||||||
NumberFormat,
|
NumberFormat,
|
||||||
TimeFormat,
|
TimeFormat,
|
||||||
@ -13,21 +23,244 @@ import { demoConfig } from "../../../src/fake_data/demo_config";
|
|||||||
describe("formatDate", () => {
|
describe("formatDate", () => {
|
||||||
const dateObj = new Date(2017, 10, 18, 11, 12, 13, 1400);
|
const dateObj = new Date(2017, 10, 18, 11, 12, 13, 1400);
|
||||||
|
|
||||||
it("Formats English dates", () => {
|
describe("formatDate", () => {
|
||||||
assert.strictEqual(
|
it("Formats English dates", () => {
|
||||||
formatDate(
|
expect(
|
||||||
dateObj,
|
formatDate(
|
||||||
{
|
dateObj,
|
||||||
language: "en",
|
{
|
||||||
number_format: NumberFormat.language,
|
language: "en",
|
||||||
time_format: TimeFormat.language,
|
number_format: NumberFormat.language,
|
||||||
date_format: DateFormat.language,
|
time_format: TimeFormat.language,
|
||||||
time_zone: TimeZone.local,
|
date_format: DateFormat.language,
|
||||||
first_weekday: FirstWeekday.language,
|
time_zone: TimeZone.local,
|
||||||
},
|
first_weekday: FirstWeekday.language,
|
||||||
demoConfig
|
},
|
||||||
),
|
demoConfig
|
||||||
"November 18, 2017"
|
)
|
||||||
);
|
).toBe("November 18, 2017");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateWeekdayDay", () => {
|
||||||
|
it("Formats weekday and day", () => {
|
||||||
|
expect(
|
||||||
|
formatDateWeekdayDay(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("Saturday, November 18");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateShort", () => {
|
||||||
|
it("Formats short date", () => {
|
||||||
|
expect(
|
||||||
|
formatDateShort(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("Nov 18, 2017");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateNumeric", () => {
|
||||||
|
it("Formats numeric date", () => {
|
||||||
|
expect(
|
||||||
|
formatDateNumeric(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "de",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("18.11.2017");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Formats numeric date in DMY format", () => {
|
||||||
|
expect(
|
||||||
|
formatDateNumeric(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.DMY,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("18/11/2017");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Formats numeric date in MDY format", () => {
|
||||||
|
expect(
|
||||||
|
formatDateNumeric(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.MDY,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("11/18/2017");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Formats numeric date in YMD format", () => {
|
||||||
|
expect(
|
||||||
|
formatDateNumeric(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.YMD,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("2017/11/18");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateVeryShort", () => {
|
||||||
|
it("Formats very short date", () => {
|
||||||
|
expect(
|
||||||
|
formatDateVeryShort(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("Nov 18");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateMonthYear", () => {
|
||||||
|
it("Formats month and year", () => {
|
||||||
|
expect(
|
||||||
|
formatDateMonthYear(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("November 2017");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateMonth", () => {
|
||||||
|
it("Formats month", () => {
|
||||||
|
expect(
|
||||||
|
formatDateMonth(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("November");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateYear", () => {
|
||||||
|
it("Formats year", () => {
|
||||||
|
expect(
|
||||||
|
formatDateYear(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("2017");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateWeekday", () => {
|
||||||
|
it("Formats weekday", () => {
|
||||||
|
expect(
|
||||||
|
formatDateWeekday(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("Saturday");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDateWeekdayShort", () => {
|
||||||
|
it("Formats short weekday", () => {
|
||||||
|
expect(
|
||||||
|
formatDateWeekdayShort(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("Sat");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import { assert, describe, it } from "vitest";
|
|||||||
import {
|
import {
|
||||||
formatDateTime,
|
formatDateTime,
|
||||||
formatDateTimeWithSeconds,
|
formatDateTimeWithSeconds,
|
||||||
|
formatDateTimeNumeric,
|
||||||
} from "../../../src/common/datetime/format_date_time";
|
} from "../../../src/common/datetime/format_date_time";
|
||||||
import {
|
import {
|
||||||
NumberFormat,
|
NumberFormat,
|
||||||
@ -87,3 +88,40 @@ describe("formatDateTimeWithSeconds", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("formatDateTimeNumeric", () => {
|
||||||
|
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 400);
|
||||||
|
|
||||||
|
it("Formats English numeric date times", () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
formatDateTimeNumeric(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.am_pm,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
),
|
||||||
|
"11/18/2017, 11:12 PM"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
formatDateTimeNumeric(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.twenty_four,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
),
|
||||||
|
"11/18/2017, 23:12"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import "@formatjs/intl-durationformat/polyfill-force";
|
import "@formatjs/intl-durationformat/polyfill-force";
|
||||||
import { assert, describe, it } from "vitest";
|
import { expect, describe, it } from "vitest";
|
||||||
import { formatDuration } from "../../../src/common/datetime/format_duration";
|
import {
|
||||||
|
formatDuration,
|
||||||
|
formatDurationLong,
|
||||||
|
formatDurationDigital,
|
||||||
|
formatNumericDuration,
|
||||||
|
} from "../../../src/common/datetime/format_duration";
|
||||||
import type { FrontendLocaleData } from "../../../src/data/translation";
|
import type { FrontendLocaleData } from "../../../src/data/translation";
|
||||||
import {
|
import {
|
||||||
DateFormat,
|
DateFormat,
|
||||||
@ -21,24 +26,89 @@ const LOCALE: FrontendLocaleData = {
|
|||||||
|
|
||||||
describe("formatDuration", () => {
|
describe("formatDuration", () => {
|
||||||
it("works", () => {
|
it("works", () => {
|
||||||
assert.strictEqual(formatDuration(LOCALE, "0.25", "min"), "0m 15s");
|
expect(formatDuration(LOCALE, "0.25", "min")).toBe("0m 15s");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "0.5", "min"), "0m 30s");
|
expect(formatDuration(LOCALE, "0.5", "min")).toBe("0m 30s");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "1", "min"), "1m");
|
expect(formatDuration(LOCALE, "1", "min")).toBe("1m");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "20", "min"), "20m");
|
expect(formatDuration(LOCALE, "20", "min")).toBe("20m");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "95.5", "min"), "95m 30s");
|
expect(formatDuration(LOCALE, "95.5", "min")).toBe("95m 30s");
|
||||||
|
|
||||||
assert.strictEqual(formatDuration(LOCALE, "0.25", "h"), "0h 15m");
|
expect(formatDuration(LOCALE, "0.25", "h")).toBe("0h 15m");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "0.5", "h"), "0h 30m");
|
expect(formatDuration(LOCALE, "0.5", "h")).toBe("0h 30m");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "1", "h"), "1h");
|
expect(formatDuration(LOCALE, "1", "h")).toBe("1h");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "20", "h"), "20h");
|
expect(formatDuration(LOCALE, "20", "h")).toBe("20h");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "95.5", "h"), "95h 30m");
|
expect(formatDuration(LOCALE, "95.5", "h")).toBe("95h 30m");
|
||||||
|
|
||||||
assert.strictEqual(formatDuration(LOCALE, "0", "d"), "0d");
|
expect(formatDuration(LOCALE, "0", "d")).toBe("0d");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "0.4", "d"), "0d 9h");
|
expect(formatDuration(LOCALE, "0.4", "d")).toBe("0d 9h");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "1", "d"), "1d");
|
expect(formatDuration(LOCALE, "1", "d")).toBe("1d");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "20", "d"), "20d");
|
expect(formatDuration(LOCALE, "20", "d")).toBe("20d");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "95.5", "d"), "95d 12h");
|
expect(formatDuration(LOCALE, "95.5", "d")).toBe("95d 12h");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "95.75", "d", 0), "96d");
|
expect(formatDuration(LOCALE, "95.75", "d", 0)).toBe("96d");
|
||||||
assert.strictEqual(formatDuration(LOCALE, "95.75", "d", 2), "95d 18h");
|
expect(formatDuration(LOCALE, "95.75", "d", 2)).toBe("95d 18h");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throws error for invalid duration unit", () => {
|
||||||
|
expect(() => formatDuration(LOCALE, "1", "invalid_unit" as any)).toThrow(
|
||||||
|
"Invalid duration unit"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDurationLong", () => {
|
||||||
|
it("formats long duration", () => {
|
||||||
|
const duration = { days: 1, hours: 2, minutes: 3, seconds: 4 };
|
||||||
|
expect(formatDurationLong(LOCALE, duration)).toBe(
|
||||||
|
"1 day, 2 hours, 3 minutes, 4 seconds"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatDurationDigital", () => {
|
||||||
|
it("formats digital duration", () => {
|
||||||
|
const duration = { hours: 1, minutes: 2, seconds: 3 };
|
||||||
|
expect(formatDurationDigital(LOCALE, duration)).toBe("1:02:03");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatNumericDuration", () => {
|
||||||
|
it("formats numeric duration", () => {
|
||||||
|
const duration = { days: 1, hours: 2, minutes: 3, seconds: 4 };
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe("1 day 2:03:04");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("formats duration with only days", () => {
|
||||||
|
const duration = { days: 1 };
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe("1 day 0:00:00");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("formats duration with only hours", () => {
|
||||||
|
const duration = { hours: 1 };
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe("1:00:00");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("formats duration with only minutes", () => {
|
||||||
|
const duration = { minutes: 1 };
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe("1:00");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("formats duration with only seconds", () => {
|
||||||
|
const duration = { seconds: 1 };
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe("1 second");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("formats duration with only milliseconds", () => {
|
||||||
|
const duration = { milliseconds: 1 };
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe("1 millisecond");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not format duration with 0", () => {
|
||||||
|
const duration = {
|
||||||
|
days: 0,
|
||||||
|
hours: 0,
|
||||||
|
minutes: 0,
|
||||||
|
seconds: 0,
|
||||||
|
milliseconds: 0,
|
||||||
|
};
|
||||||
|
expect(formatNumericDuration(LOCALE, duration)).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { assert, describe, it } from "vitest";
|
import { expect, describe, it } from "vitest";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
formatTime,
|
formatTime,
|
||||||
formatTimeWithSeconds,
|
formatTimeWithSeconds,
|
||||||
formatTimeWeekday,
|
formatTimeWeekday,
|
||||||
|
formatTime24h,
|
||||||
} from "../../../src/common/datetime/format_time";
|
} from "../../../src/common/datetime/format_time";
|
||||||
import {
|
import {
|
||||||
NumberFormat,
|
NumberFormat,
|
||||||
@ -18,7 +19,7 @@ describe("formatTime", () => {
|
|||||||
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 1400);
|
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 1400);
|
||||||
|
|
||||||
it("Formats English times", () => {
|
it("Formats English times", () => {
|
||||||
assert.strictEqual(
|
expect(
|
||||||
formatTime(
|
formatTime(
|
||||||
dateObj,
|
dateObj,
|
||||||
{
|
{
|
||||||
@ -30,10 +31,9 @@ describe("formatTime", () => {
|
|||||||
first_weekday: FirstWeekday.language,
|
first_weekday: FirstWeekday.language,
|
||||||
},
|
},
|
||||||
demoConfig
|
demoConfig
|
||||||
),
|
)
|
||||||
"11:12 PM"
|
).toBe("11:12 PM");
|
||||||
);
|
expect(
|
||||||
assert.strictEqual(
|
|
||||||
formatTime(
|
formatTime(
|
||||||
dateObj,
|
dateObj,
|
||||||
{
|
{
|
||||||
@ -45,9 +45,8 @@ describe("formatTime", () => {
|
|||||||
first_weekday: FirstWeekday.language,
|
first_weekday: FirstWeekday.language,
|
||||||
},
|
},
|
||||||
demoConfig
|
demoConfig
|
||||||
),
|
)
|
||||||
"23:12"
|
).toBe("23:12");
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -55,7 +54,7 @@ describe("formatTimeWithSeconds", () => {
|
|||||||
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 400);
|
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 400);
|
||||||
|
|
||||||
it("Formats English times with seconds", () => {
|
it("Formats English times with seconds", () => {
|
||||||
assert.strictEqual(
|
expect(
|
||||||
formatTimeWithSeconds(
|
formatTimeWithSeconds(
|
||||||
dateObj,
|
dateObj,
|
||||||
{
|
{
|
||||||
@ -67,10 +66,9 @@ describe("formatTimeWithSeconds", () => {
|
|||||||
first_weekday: FirstWeekday.language,
|
first_weekday: FirstWeekday.language,
|
||||||
},
|
},
|
||||||
demoConfig
|
demoConfig
|
||||||
),
|
)
|
||||||
"11:12:13 PM"
|
).toBe("11:12:13 PM");
|
||||||
);
|
expect(
|
||||||
assert.strictEqual(
|
|
||||||
formatTimeWithSeconds(
|
formatTimeWithSeconds(
|
||||||
dateObj,
|
dateObj,
|
||||||
{
|
{
|
||||||
@ -82,9 +80,8 @@ describe("formatTimeWithSeconds", () => {
|
|||||||
first_weekday: FirstWeekday.language,
|
first_weekday: FirstWeekday.language,
|
||||||
},
|
},
|
||||||
demoConfig
|
demoConfig
|
||||||
),
|
)
|
||||||
"23:12:13"
|
).toBe("23:12:13");
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,7 +89,7 @@ describe("formatTimeWeekday", () => {
|
|||||||
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 1400);
|
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 1400);
|
||||||
|
|
||||||
it("Formats English times", () => {
|
it("Formats English times", () => {
|
||||||
assert.strictEqual(
|
expect(
|
||||||
formatTimeWeekday(
|
formatTimeWeekday(
|
||||||
dateObj,
|
dateObj,
|
||||||
{
|
{
|
||||||
@ -104,10 +101,9 @@ describe("formatTimeWeekday", () => {
|
|||||||
first_weekday: FirstWeekday.language,
|
first_weekday: FirstWeekday.language,
|
||||||
},
|
},
|
||||||
demoConfig
|
demoConfig
|
||||||
),
|
)
|
||||||
"Saturday 11:12 PM"
|
).toBe("Saturday 11:12 PM");
|
||||||
);
|
expect(
|
||||||
assert.strictEqual(
|
|
||||||
formatTimeWeekday(
|
formatTimeWeekday(
|
||||||
dateObj,
|
dateObj,
|
||||||
{
|
{
|
||||||
@ -119,8 +115,28 @@ describe("formatTimeWeekday", () => {
|
|||||||
first_weekday: FirstWeekday.language,
|
first_weekday: FirstWeekday.language,
|
||||||
},
|
},
|
||||||
demoConfig
|
demoConfig
|
||||||
),
|
)
|
||||||
"Saturday 23:12"
|
).toBe("Saturday 23:12");
|
||||||
);
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatTime24h", () => {
|
||||||
|
const dateObj = new Date(2017, 10, 18, 23, 12, 13, 1400);
|
||||||
|
|
||||||
|
it("Formats English times in 24h format", () => {
|
||||||
|
expect(
|
||||||
|
formatTime24h(
|
||||||
|
dateObj,
|
||||||
|
{
|
||||||
|
language: "en",
|
||||||
|
number_format: NumberFormat.language,
|
||||||
|
time_format: TimeFormat.twenty_four,
|
||||||
|
date_format: DateFormat.language,
|
||||||
|
time_zone: TimeZone.local,
|
||||||
|
first_weekday: FirstWeekday.language,
|
||||||
|
},
|
||||||
|
demoConfig
|
||||||
|
)
|
||||||
|
).toBe("23:12");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
65
test/common/datetime/localize_date.test.ts
Normal file
65
test/common/datetime/localize_date.test.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import {
|
||||||
|
localizeWeekdays,
|
||||||
|
localizeMonths,
|
||||||
|
} from "../../../src/common/datetime/localize_date";
|
||||||
|
|
||||||
|
describe("localizeWeekdays", () => {
|
||||||
|
it("should return long weekday names in English", () => {
|
||||||
|
const weekdays = localizeWeekdays("en-US", false);
|
||||||
|
expect(weekdays).toEqual([
|
||||||
|
"Sunday",
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return short weekday names in English", () => {
|
||||||
|
const weekdays = localizeWeekdays("en-US", true);
|
||||||
|
expect(weekdays).toEqual(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more tests for different languages if needed
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("localizeMonths", () => {
|
||||||
|
it("should return long month names in English", () => {
|
||||||
|
const months = localizeMonths("en-US", false);
|
||||||
|
expect(months).toEqual([
|
||||||
|
"January",
|
||||||
|
"February",
|
||||||
|
"March",
|
||||||
|
"April",
|
||||||
|
"May",
|
||||||
|
"June",
|
||||||
|
"July",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"October",
|
||||||
|
"November",
|
||||||
|
"December",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return short month names in English", () => {
|
||||||
|
const months = localizeMonths("en-US", true);
|
||||||
|
expect(months).toEqual([
|
||||||
|
"Jan",
|
||||||
|
"Feb",
|
||||||
|
"Mar",
|
||||||
|
"Apr",
|
||||||
|
"May",
|
||||||
|
"Jun",
|
||||||
|
"Jul",
|
||||||
|
"Aug",
|
||||||
|
"Sep",
|
||||||
|
"Oct",
|
||||||
|
"Nov",
|
||||||
|
"Dec",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
@ -9,5 +9,10 @@ describe("secondsToDuration", () => {
|
|||||||
assert.strictEqual(secondsToDuration(3665), "1:01:05");
|
assert.strictEqual(secondsToDuration(3665), "1:01:05");
|
||||||
assert.strictEqual(secondsToDuration(39665), "11:01:05");
|
assert.strictEqual(secondsToDuration(39665), "11:01:05");
|
||||||
assert.strictEqual(secondsToDuration(932093), "258:54:53");
|
assert.strictEqual(secondsToDuration(932093), "258:54:53");
|
||||||
|
assert.strictEqual(secondsToDuration(59), "59");
|
||||||
|
assert.strictEqual(secondsToDuration(3600), "1:00:00");
|
||||||
|
assert.strictEqual(secondsToDuration(3660), "1:01:00");
|
||||||
|
assert.strictEqual(secondsToDuration(60), "1:00");
|
||||||
|
assert.strictEqual(secondsToDuration(61), "1:01");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
31
test/common/datetime/use_am_pm.test.ts
Normal file
31
test/common/datetime/use_am_pm.test.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { TimeFormat } from "../../../src/data/translation";
|
||||||
|
import { useAmPm } from "../../../src/common/datetime/use_am_pm";
|
||||||
|
|
||||||
|
describe("useAmPm", () => {
|
||||||
|
it("should return true for am_pm format", () => {
|
||||||
|
const locale = { time_format: TimeFormat.am_pm } as any;
|
||||||
|
expect(useAmPm(locale)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false for 24_hour format", () => {
|
||||||
|
const locale = { time_format: TimeFormat.twenty_four } as any;
|
||||||
|
expect(useAmPm(locale)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return true for language format with 12-hour clock", () => {
|
||||||
|
const locale = {
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
language: "en-US",
|
||||||
|
} as any;
|
||||||
|
expect(useAmPm(locale)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false for language format with 24-hour clock", () => {
|
||||||
|
const locale = {
|
||||||
|
time_format: TimeFormat.language,
|
||||||
|
language: "fr-FR",
|
||||||
|
} as any;
|
||||||
|
expect(useAmPm(locale)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user