Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test runs only with pattern: os != 'android'
- Manifest: browser/components/urlbar/tests/unit/xpcshell.toml
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
// Tests `UrlbarShared.formatDate()` and `parseDate()`.
"use strict";
add_setup(async function init() {
// This test deals with `Intl` formating of dates and times, which depends on
// the system locale, and assumes it's en-US. Make sure it's actually en-US.
await QuickSuggestTestUtils.setRegionAndLocale({
locale: "en-US",
skipSuggestReset: true,
});
Assert.equal(
new Intl.Locale(Services.locale.appLocaleAsBCP47).getWeekInfo().firstDay,
7,
"Sanity check: First day of week in en-US is 7 (Sunday)"
);
});
// Main test for `UrlbarShared.formatDate()`.
add_task(async function formatDate() {
// For each test, we'll set `now`, call `formatDate` with `date` and
// `options`, and check the return value against `expected`.
let tests = [
{
desc: "> 12 months ago",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2013-05-11T04:00:00-07:00",
cases: [
{
expected: {
formattedDate: "May 11, 2013",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "12 months ago (most recent possible date)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2024-10-31T23:59:59-07:00",
cases: [
{
expected: {
formattedDate: "Oct 31, 2024",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "11 months ago (oldest possible date)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2024-11-01T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "11 months ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Nov 1, 2024",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "5 weeks ago (most recent possible date)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-09-13T23:59:59-07:00",
cases: [
{
expected: {
formattedDate: "1 month ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Sep 13",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "4 weeks ago (oldest possible date)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-09-14T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "4 weeks ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Sep 14",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "7 days ago",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-08T23:59:59-07:00",
cases: [
{
expected: {
formattedDate: "1 week ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 8",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "6 days ago",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-09T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "6 days ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 9",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "2 days ago",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-13T23:59:59-07:00",
cases: [
{
expected: {
formattedDate: "2 days ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 13",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "yesterday",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-14T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "yesterday",
formattedTime: undefined,
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
capitalizeRelativeDate: true,
},
expected: {
formattedDate: "Yesterday",
formattedTime: undefined,
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 14",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "today (past)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-15T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "today",
formattedTime: undefined,
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
capitalizeRelativeDate: true,
},
expected: {
formattedDate: "Today",
formattedTime: undefined,
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 15",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "today (now)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-15T12:00:00-07:00",
cases: [
{
expected: {
formattedDate: "today",
formattedTime: undefined,
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
capitalizeRelativeDate: true,
},
expected: {
formattedDate: "Today",
formattedTime: undefined,
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 15",
formattedTime: undefined,
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "today (future)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-15T20:00:00-07:00",
cases: [
{
expected: {
formattedDate: "today",
formattedTime: "8:00 PM",
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
capitalizeRelativeDate: true,
includeTimeZone: true,
},
expected: {
formattedDate: "Today",
formattedTime: "8:00 PM GMT-7",
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Oct 15",
formattedTime: "8:00 PM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "tomorrow",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-16T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "tomorrow",
formattedTime: "12:00 AM",
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
capitalizeRelativeDate: true,
includeTimeZone: true,
},
expected: {
formattedDate: "Tomorrow",
formattedTime: "12:00 AM GMT-7",
isRelative: true,
dateFormatType:
UrlbarShared.DATE_FORMAT_TYPE.YESTERDAY_TODAY_TOMORROW,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Thu",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
forceAbsoluteDate: true,
forceMonthAndDayWhenAbsolute: true,
},
expected: {
formattedDate: "Oct 16",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "6 days from now",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-21T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "Tue",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
includeTimeZone: true,
},
expected: {
formattedDate: "Tue",
formattedTime: "12:00 AM GMT-7",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
forceAbsoluteDate: true,
},
expected: {
formattedDate: "Tue",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
forceMonthAndDayWhenAbsolute: true,
},
expected: {
formattedDate: "Oct 21",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "7 days from now",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-22T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "Oct 22",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
includeTimeZone: true,
},
expected: {
formattedDate: "Oct 22",
formattedTime: "12:00 AM GMT-7",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "last day this year",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-12-31T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "Dec 31",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
includeTimeZone: true,
},
expected: {
formattedDate: "Dec 31",
formattedTime: "12:00 AM GMT-7",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "first day next year",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2026-01-01T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "Jan 1, 2026",
formattedTime: "12:00 AM",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
{
options: {
includeTimeZone: true,
},
expected: {
formattedDate: "Jan 1, 2026",
formattedTime: "12:00 AM GMT-7",
isRelative: false,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.ABSOLUTE,
},
},
],
},
{
desc: "> 4 weeks ago but still in same month",
now: "2025-03-31T12:00:00-07:00[-07:00]",
date: "2025-03-01T00:00:00-07:00",
cases: [
{
expected: {
formattedDate: "5 weeks ago",
formattedTime: undefined,
isRelative: true,
dateFormatType: UrlbarShared.DATE_FORMAT_TYPE.DAYS_WEEKS_MONTHS_AGO,
},
},
],
},
];
for (let { desc, now, date, cases } of tests) {
UrlbarTestUtils.stubNowZonedDateTime(now);
for (let { options, expected } of cases) {
let actual = UrlbarShared.formatDate(new Date(date), options);
// There's another task that tests `parseDate()`, so just check that the
// `parseDateResult` is present rather than its properties.
Assert.ok(actual.parseDateResult, "parseDateResult should be present");
delete actual.parseDateResult;
Assert.deepEqual(
actual,
expected,
"formatDate test: " + JSON.stringify({ desc, now, date, options })
);
}
}
});
// Main test for `UrlbarShared.parseDate()`.
add_task(async function parseDate_main() {
// For each test, we'll set `now`, call `parseDate` with `date`, and check the
// return value against `expected`.
doParseDateTests([
{
desc: "far past",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2013-05-11T04:00:00-07:00",
expected: {
daysAgo: 4540,
weeksAgo: 649,
monthsAgo: 149,
isFuture: false,
},
},
{
desc: "the last day of last year",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2024-12-31T12:00:00-07:00",
expected: {
daysAgo: 288,
weeksAgo: 41,
monthsAgo: 10,
isFuture: false,
},
},
{
desc: "the first day of this year",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-01-01T12:00:00-07:00",
expected: {
daysAgo: 287,
weeksAgo: 41,
monthsAgo: 9,
isFuture: false,
},
},
{
desc: "the last day of the month before last",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-08-31T12:00:00-07:00",
expected: {
daysAgo: 45,
weeksAgo: 6,
monthsAgo: 2,
isFuture: false,
},
},
{
desc: "the first day of last month",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-09-01T12:00:00-07:00",
expected: {
daysAgo: 44,
weeksAgo: 6,
monthsAgo: 1,
isFuture: false,
},
},
{
desc: "the last day of last month",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-09-30T12:00:00-07:00",
expected: {
daysAgo: 15,
weeksAgo: 2,
monthsAgo: 1,
isFuture: false,
},
},
{
desc: "the first day of this month",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-01T12:00:00-07:00",
expected: {
daysAgo: 14,
weeksAgo: 2,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the last day of the week before last",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-04T12:00:00-07:00",
expected: {
daysAgo: 11,
weeksAgo: 2,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the first day of last week",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-05T12:00:00-07:00",
expected: {
daysAgo: 10,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the last day of last week",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-11T12:00:00-07:00",
expected: {
daysAgo: 4,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the first day of this week",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-12T12:00:00-07:00",
expected: {
daysAgo: 3,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the day before yesterday",
now: [
"2025-10-15T00:00:00-07:00[-07:00]",
"2025-10-15T23:59:59-07:00[-07:00]",
],
date: ["2025-10-13T00:00:00-07:00", "2025-10-13T23:59:59-07:00"],
expected: {
daysAgo: 2,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "yesterday",
now: [
"2025-10-15T00:00:00-07:00[-07:00]",
"2025-10-15T23:59:59-07:00[-07:00]",
],
date: ["2025-10-14T00:00:00-07:00", "2025-10-14T23:59:59-07:00"],
expected: {
daysAgo: 1,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "today (past)",
now: [
"2025-10-15T12:00:00-07:00[-07:00]",
"2025-10-15T23:59:59-07:00[-07:00]",
],
date: ["2025-10-15T00:00:00-07:00", "2025-10-15T11:59:59-07:00"],
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "today (now)",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-15T12:00:00-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "today (future)",
now: [
"2025-10-15T00:00:00-07:00[-07:00]",
"2025-10-15T12:00:00-07:00[-07:00]",
],
date: ["2025-10-15T12:00:01-07:00", "2025-10-15T23:59:59-07:00"],
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "tomorrow",
now: [
"2025-10-15T00:00:00-07:00[-07:00]",
"2025-10-15T23:59:59-07:00[-07:00]",
],
date: ["2025-10-16T00:00:00-07:00", "2025-10-16T23:59:59-07:00"],
expected: {
daysAgo: -1,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the day after tomorrow",
now: [
"2025-10-15T00:00:00-07:00[-07:00]",
"2025-10-15T23:59:59-07:00[-07:00]",
],
date: ["2025-10-17T00:00:00-07:00", "2025-10-17T23:59:59-07:00"],
expected: {
daysAgo: -2,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the last day of this week",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-18T12:00:00-07:00",
expected: {
daysAgo: -3,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the first day of next week",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-19T12:00:00-07:00",
expected: {
daysAgo: -4,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the last day of next week",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-25T12:00:00-07:00",
expected: {
daysAgo: -10,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the first day of the week after next",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-26T12:00:00-07:00",
expected: {
daysAgo: -11,
weeksAgo: -2,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the last day of this month",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-10-31T12:00:00-07:00",
expected: {
daysAgo: -16,
weeksAgo: -2,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the first day of next month",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-11-01T12:00:00-07:00",
expected: {
daysAgo: -17,
weeksAgo: -2,
monthsAgo: -1,
isFuture: true,
},
},
{
desc: "the last day of next month",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-11-30T12:00:00-07:00",
expected: {
daysAgo: -46,
weeksAgo: -7,
monthsAgo: -1,
isFuture: true,
},
},
{
desc: "the first day of the month after next",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-12-01T12:00:00-07:00",
expected: {
daysAgo: -47,
weeksAgo: -7,
monthsAgo: -2,
isFuture: true,
},
},
{
desc: "the last day of this year",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2025-12-31T12:00:00-07:00",
expected: {
daysAgo: -77,
weeksAgo: -11,
monthsAgo: -2,
isFuture: true,
},
},
{
desc: "the first day of next year",
now: "2025-10-15T12:00:00-07:00[-07:00]",
date: "2026-01-01T12:00:00-07:00",
expected: {
daysAgo: -78,
weeksAgo: -11,
monthsAgo: -3,
isFuture: true,
},
},
{
desc: "far future",
now: "2025-10-15T00:00:00-07:00[-07:00]",
date: "3013-05-11T04:00:00-07:00",
expected: {
daysAgo: -360702,
weeksAgo: -51529,
monthsAgo: -11851,
isFuture: true,
},
},
]);
});
// `UrlbarShared.parseDate()` test where "now" is the first day in a week.
add_task(async function parseDate_nowIsFirstDayInWeek() {
let now = "2025-10-12T12:00:00-07:00[-07:00]";
doParseDateTests([
{
now,
desc: "the last day of the week before last",
date: "2025-10-04T23:59:59-07:00",
expected: {
daysAgo: 8,
weeksAgo: 2,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the first day of last week",
date: "2025-10-05T00:00:00-07:00",
expected: {
daysAgo: 7,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the last day of last week",
date: "2025-10-11T23:59:59-07:00",
expected: {
daysAgo: 1,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the first day of this week",
date: "2025-10-12T00:00:00-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the last day of this week",
date: "2025-10-18T23:59:59-07:00",
expected: {
daysAgo: -6,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the first day of next week",
date: "2025-10-19T00:00:00-07:00",
expected: {
daysAgo: -7,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the last day of next week",
date: "2025-10-25T23:59:59-07:00",
expected: {
daysAgo: -13,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the first day of the week after next",
date: "2025-10-26T00:00:00-07:00",
expected: {
daysAgo: -14,
weeksAgo: -2,
monthsAgo: 0,
isFuture: true,
},
},
]);
});
// `UrlbarShared.parseDate()` test where "now" is the last day in a week.
add_task(async function parseDate_nowIsLastDayInWeek() {
let now = "2025-10-18T12:00:00-07:00[-07:00]";
doParseDateTests([
{
now,
desc: "the last day of the week before last",
date: "2025-10-04T23:59:59-07:00",
expected: {
daysAgo: 14,
weeksAgo: 2,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the first day of last week",
date: "2025-10-05T00:00:00-07:00",
expected: {
daysAgo: 13,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the last day of last week",
date: "2025-10-11T23:59:59-07:00",
expected: {
daysAgo: 7,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the first day of this week",
date: "2025-10-12T00:00:00-07:00",
expected: {
daysAgo: 6,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the last day of this week",
date: "2025-10-18T23:59:59-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the first day of next week",
date: "2025-10-19T00:00:00-07:00",
expected: {
daysAgo: -1,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the last day of next week",
date: "2025-10-25T23:59:59-07:00",
expected: {
daysAgo: -7,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the first day of the week after next",
date: "2025-10-26T00:00:00-07:00",
expected: {
daysAgo: -8,
weeksAgo: -2,
monthsAgo: 0,
isFuture: true,
},
},
]);
});
// `UrlbarShared.parseDate()` test where "now" is the first day in a month.
add_task(async function parseDate_nowIsFirstDayInMonth() {
let now = "2025-10-01T12:00:00-07:00[-07:00]";
doParseDateTests([
{
now,
desc: "the last day of the month before last",
date: "2025-08-31T23:59:59-07:00",
expected: {
daysAgo: 31,
weeksAgo: 4,
monthsAgo: 2,
isFuture: false,
},
},
{
now,
desc: "the first day of last month",
date: "2025-09-01T00:00:00-07:00",
expected: {
daysAgo: 30,
weeksAgo: 4,
monthsAgo: 1,
isFuture: false,
},
},
{
now,
desc: "the last day of last month",
date: "2025-09-30T23:59:59-07:00",
expected: {
daysAgo: 1,
weeksAgo: 0,
monthsAgo: 1,
isFuture: false,
},
},
{
now,
desc: "the first day of this month",
date: "2025-10-01T00:00:00-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the last day of this month",
date: "2025-10-31T23:59:59-07:00",
expected: {
daysAgo: -30,
weeksAgo: -4,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the first day of next month",
date: "2025-11-01T00:00:00-07:00",
expected: {
daysAgo: -31,
weeksAgo: -4,
monthsAgo: -1,
isFuture: true,
},
},
{
now,
desc: "the last day of next month",
date: "2025-11-30T23:59:59-07:00",
expected: {
daysAgo: -60,
weeksAgo: -9,
monthsAgo: -1,
isFuture: true,
},
},
{
now,
desc: "the first day of the month after next",
date: "2025-12-01T00:00:00-07:00",
expected: {
daysAgo: -61,
weeksAgo: -9,
monthsAgo: -2,
isFuture: true,
},
},
]);
});
// `UrlbarShared.parseDate()` test where "now" is the last day in a month.
add_task(async function parseDate_nowDayInMonth_last() {
let now = "2025-10-31T12:00:00-07:00[-07:00]";
doParseDateTests([
{
now,
desc: "the last day of the month before last",
date: "2025-08-31T23:59:59-07:00",
expected: {
daysAgo: 61,
weeksAgo: 8,
monthsAgo: 2,
isFuture: false,
},
},
{
now,
desc: "the first day of last month",
date: "2025-09-01T00:00:00-07:00",
expected: {
daysAgo: 60,
weeksAgo: 8,
monthsAgo: 1,
isFuture: false,
},
},
{
now,
desc: "the last day of last month",
date: "2025-09-30T23:59:59-07:00",
expected: {
daysAgo: 31,
weeksAgo: 4,
monthsAgo: 1,
isFuture: false,
},
},
{
now,
desc: "the first day of this month",
date: "2025-10-01T00:00:00-07:00",
expected: {
daysAgo: 30,
weeksAgo: 4,
monthsAgo: 0,
isFuture: false,
},
},
{
now,
desc: "the last day of this month",
date: "2025-10-31T23:59:59-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
now,
desc: "the first day of next month",
date: "2025-11-01T00:00:00-07:00",
expected: {
daysAgo: -1,
weeksAgo: 0,
monthsAgo: -1,
isFuture: true,
},
},
{
now,
desc: "the last day of next month",
date: "2025-11-30T23:59:59-07:00",
expected: {
daysAgo: -30,
weeksAgo: -5,
monthsAgo: -1,
isFuture: true,
},
},
{
now,
desc: "the first day of the month after next",
date: "2025-12-01T00:00:00-07:00",
expected: {
daysAgo: -31,
weeksAgo: -5,
monthsAgo: -2,
isFuture: true,
},
},
]);
});
// `UrlbarShared.parseDate()` test where the first day of the week is not Sunday
// as it is in en-US.
add_task(async function parseDate_firstDayOfWeek() {
doParseDateTests([
{
desc: "the last day of the week before last",
now: "2025-10-15T12:00:00-07:00[-07:00]", // Wednesday
date: "2025-10-05T23:59:59-07:00", // two Sunday's ago
firstDayOfWeek: 1, // Monday
expected: {
daysAgo: 10,
weeksAgo: 2,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the first day of last week",
now: "2025-10-15T12:00:00-07:00[-07:00]", // Wednesday
date: "2025-10-06T00:00:00-07:00", // two Monday's ago
firstDayOfWeek: 1, // Monday
expected: {
daysAgo: 9,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the last day of last week",
now: "2025-10-15T12:00:00-07:00[-07:00]", // Wednesday
date: "2025-10-12T23:59:59-07:00", // one Sunday ago
firstDayOfWeek: 1, // Monday
expected: {
daysAgo: 3,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the first day of this week",
now: "2025-10-15T12:00:00-07:00[-07:00]", // Wednesday
date: "2025-10-13T00:00:00-07:00", // one Monday ago
firstDayOfWeek: 1, // Monday
expected: {
daysAgo: 2,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "the last day of this week",
now: "2025-10-15T12:00:00-07:00[-07:00]", // Wednesday
date: "2025-10-19T23:59:59-07:00", // one Sunday from now
firstDayOfWeek: 1, // Monday
expected: {
daysAgo: -4,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "the first day of next week",
now: "2025-10-15T12:00:00-07:00[-07:00]", // Wednesday
date: "2025-10-20T00:00:00-07:00", // one Monday from now
firstDayOfWeek: 1, // Monday
expected: {
daysAgo: -5,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
]);
});
// Tests `UrlbarShaared.parseDate()` with dates across time zone changes.
add_task(function parseDate_timeZoneTransition() {
// This task is based around 2025-11-02, when Daylight Saving Time ends in the
// U.S. On 2025-11-02 at 2:00 am, the time changes to 1:00 am Standard Time.
doParseDateTests([
{
desc: "`now` and `date` both in PDT (daylight saving)",
now: "2025-10-02T12:00:00-07:00[America/Los_Angeles]",
date: "2025-10-01T00:00:00-07:00",
expected: {
daysAgo: 1,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
// `now` in PST, `date` in PDT
{
desc: "`now` in PST, `date` in PDT -- 1",
now: "2025-11-03T00:00:00-08:00[America/Los_Angeles]",
date: "2025-11-01T00:00:00-07:00",
expected: {
daysAgo: 2,
// Nov 3, 2025 is a Monday; Nov 1, 2025 is a Saturday => last week
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "`now` in PST, `date` in PDT -- 2",
now: "2025-11-02T12:00:00-08:00[America/Los_Angeles]",
date: "2025-11-01T00:00:00-07:00",
expected: {
daysAgo: 1,
// Nov 2, 2025 is a Sunday; Nov 1, 2025 is a Saturday => last week
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "`now` in PST, `date` in PDT -- 3",
now: "2025-11-02T01:00:00-08:00[America/Los_Angeles]",
date: "2025-11-01T00:00:00-07:00",
expected: {
daysAgo: 1,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "`now` in PST, `date` in PDT -- 4",
now: "2025-11-02T23:59:59-08:00[America/Los_Angeles]",
date: "2025-11-01T00:00:00-07:00",
expected: {
daysAgo: 1,
weeksAgo: 1,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "`now` in PST, `date` in PDT -- 5",
now: "2025-11-02T01:00:00-08:00[America/Los_Angeles]",
date: "2025-11-02T00:00:00-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
{
desc: "`now` in PST, `date` in PDT -- 6",
now: "2025-11-02T01:00:00-08:00[America/Los_Angeles]",
date: "2025-11-02T01:00:00-07:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
// `now` in PDT, `date` in PST
{
desc: "`now` in PDT, `date` in PST -- 1",
now: "2025-11-02T01:00:00-07:00[America/Los_Angeles]",
date: "2025-11-02T01:00:00-08:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "`now` in PDT, `date` in PST -- 2",
now: "2025-11-02T00:00:00-07:00[America/Los_Angeles]",
date: "2025-11-02T01:00:00-08:00",
expected: {
daysAgo: 0,
weeksAgo: 0,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "`now` in PDT, `date` in PST -- 3",
now: "2025-11-01T00:00:00-07:00[America/Los_Angeles]",
date: "2025-11-02T23:59:59-08:00",
expected: {
daysAgo: -1,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "`now` in PDT, `date` in PST -- 4",
now: "2025-11-01T00:00:00-07:00[America/Los_Angeles]",
date: "2025-11-02T01:00:00-08:00",
expected: {
daysAgo: -1,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "`now` in PDT, `date` in PST -- 5",
now: "2025-11-01T00:00:00-07:00[America/Los_Angeles]",
date: "2025-11-02T12:00:00-08:00",
expected: {
daysAgo: -1,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
{
desc: "`now` in PDT, `date` in PST -- 6",
now: "2025-11-01T00:00:00-07:00[America/Los_Angeles]",
date: "2025-11-03T00:00:00-08:00",
expected: {
daysAgo: -2,
weeksAgo: -1,
monthsAgo: 0,
isFuture: true,
},
},
// `now` and `date` both in PST (standard time)
{
desc: "`now` and `date` both in PST (standard time)",
now: "2025-11-11T12:00:00-08:00[America/Los_Angeles]",
date: "2025-11-10T00:00:00-08:00",
expected: {
daysAgo: 1,
weeksAgo: 0,
monthsAgo: 0,
isFuture: false,
},
},
]);
});
function doParseDateTests(tests) {
for (let { desc, now, date, firstDayOfWeek, expected } of tests) {
UrlbarTestUtils.stubFirstDayOfWeek(firstDayOfWeek);
let nows = typeof now == "string" ? [now] : now;
let dates = typeof date == "string" ? [date] : date;
for (let n of nows) {
let zonedNow = UrlbarTestUtils.stubNowZonedDateTime(n);
for (let d of dates) {
Assert.deepEqual(
UrlbarShared.parseDate(new Date(d)),
{
...expected,
zonedNow,
zonedDate: new Date(d)
.toTemporalInstant()
.toZonedDateTimeISO(zonedNow),
},
"parseDate test: " + JSON.stringify({ desc, now: n, date: d })
);
}
}
UrlbarTestUtils.stubFirstDayOfWeek(null);
}
}