Packages
noora
0.53.0
0.84.1
0.84.0
0.83.2
0.83.1
0.83.0
0.82.7
0.82.6
0.82.5
0.82.4
0.82.3
0.82.2
0.82.1
0.82.0
0.81.4
0.81.3
0.81.2
0.81.1
0.81.0
0.80.1
0.80.0
0.79.1
0.79.0
0.78.1
0.78.0
0.77.4
0.77.3
0.77.2
0.77.1
0.77.0
0.76.0
0.75.0
0.74.0
0.73.0
0.72.0
0.71.0
0.70.0
0.69.1
0.69.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.2
0.64.1
0.64.0
0.63.2
0.63.1
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.0
0.54.0
0.53.1
0.53.0
0.52.1
0.52.0
0.51.0
0.50.1
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.3
0.44.2
0.44.1
0.44.0
0.43.0
0.42.0
0.41.0
0.40.6
0.40.5
0.40.4
0.40.3
0.40.2
0.40.1
0.40.0
0.39.1
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.1
0.32.0
0.31.0
0.30.0
0.29.2
0.29.1
0.29.0
0.28.5
0.28.4
0.28.3
0.28.2
0.28.1
0.28.0
0.27.0
0.26.1
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.0
0.1.0
0.1.0-rc.2
0.1.0-rc.1
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
A component library for Phoenix LiveView applications
Current section
Files
Jump to
Current section
Files
js/DatePicker/CalendarNavigation.test.js
import { describe, it, expect, vi, beforeEach } from "vitest";
import { CalendarNavigation } from "./CalendarNavigation.js";
describe("CalendarNavigation", () => {
describe("canNavigatePrevStart", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("returns false when startCalendarMonth is null", () => {
nav.startCalendarMonth = null;
expect(nav.canNavigatePrevStart(null)).toBe(false);
});
it("returns true when no minDate is provided", () => {
expect(nav.canNavigatePrevStart(null)).toBe(true);
});
it("returns true when start month is after minDate", () => {
const minDate = { year: 2024, month: 1, day: 1 };
expect(nav.canNavigatePrevStart(minDate)).toBe(true);
});
it("returns false when start month equals minDate month", () => {
const minDate = { year: 2024, month: 3, day: 15 };
expect(nav.canNavigatePrevStart(minDate)).toBe(false);
});
it("returns false when start month is before minDate", () => {
const minDate = { year: 2024, month: 5, day: 1 };
expect(nav.canNavigatePrevStart(minDate)).toBe(false);
});
it("returns true when year is greater than minDate year", () => {
const minDate = { year: 2023, month: 12, day: 1 };
expect(nav.canNavigatePrevStart(minDate)).toBe(true);
});
});
describe("canNavigateNextStart", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("returns false when startCalendarMonth is null", () => {
nav.startCalendarMonth = null;
expect(nav.canNavigateNextStart()).toBe(false);
});
it("returns false when endCalendarMonth is null", () => {
nav.endCalendarMonth = null;
expect(nav.canNavigateNextStart()).toBe(false);
});
it("returns true when there is at least one month gap", () => {
// Start: March, End: June - navigating to April still leaves gap
expect(nav.canNavigateNextStart()).toBe(true);
});
it("returns false when calendars are adjacent months", () => {
nav.startCalendarMonth = { year: 2024, month: 5 };
nav.endCalendarMonth = { year: 2024, month: 6 };
expect(nav.canNavigateNextStart()).toBe(false);
});
it("handles year boundary correctly", () => {
nav.startCalendarMonth = { year: 2024, month: 11 };
nav.endCalendarMonth = { year: 2025, month: 2 };
// November -> December still before February
expect(nav.canNavigateNextStart()).toBe(true);
});
});
describe("canNavigatePrevEnd", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("returns false when startCalendarMonth is null", () => {
nav.startCalendarMonth = null;
expect(nav.canNavigatePrevEnd()).toBe(false);
});
it("returns false when endCalendarMonth is null", () => {
nav.endCalendarMonth = null;
expect(nav.canNavigatePrevEnd()).toBe(false);
});
it("returns true when there is at least one month gap", () => {
// Start: March, End: June - navigating to May still leaves gap
expect(nav.canNavigatePrevEnd()).toBe(true);
});
it("returns false when calendars are adjacent months", () => {
nav.startCalendarMonth = { year: 2024, month: 5 };
nav.endCalendarMonth = { year: 2024, month: 6 };
expect(nav.canNavigatePrevEnd()).toBe(false);
});
it("handles year boundary correctly", () => {
nav.startCalendarMonth = { year: 2024, month: 10 };
nav.endCalendarMonth = { year: 2025, month: 1 };
// January -> December still after October
expect(nav.canNavigatePrevEnd()).toBe(true);
});
});
describe("canNavigateNextEnd", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("returns false when endCalendarMonth is null", () => {
nav.endCalendarMonth = null;
expect(nav.canNavigateNextEnd(null)).toBe(false);
});
it("returns true when no maxDate is provided", () => {
expect(nav.canNavigateNextEnd(null)).toBe(true);
});
it("returns true when end month is before maxDate", () => {
const maxDate = { year: 2024, month: 12, day: 31 };
expect(nav.canNavigateNextEnd(maxDate)).toBe(true);
});
it("returns false when end month equals maxDate month", () => {
const maxDate = { year: 2024, month: 6, day: 15 };
expect(nav.canNavigateNextEnd(maxDate)).toBe(false);
});
it("returns false when end month is after maxDate", () => {
const maxDate = { year: 2024, month: 5, day: 1 };
expect(nav.canNavigateNextEnd(maxDate)).toBe(false);
});
it("returns true when year is less than maxDate year", () => {
const maxDate = { year: 2025, month: 1, day: 1 };
expect(nav.canNavigateNextEnd(maxDate)).toBe(true);
});
});
describe("navigatePrevStart", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("moves start calendar back one month", () => {
nav.navigatePrevStart();
expect(nav.startCalendarMonth).toEqual({ year: 2024, month: 2 });
});
it("calls onNavigate callback", () => {
nav.navigatePrevStart();
expect(onNavigate).toHaveBeenCalledTimes(1);
});
it("handles year boundary (January to December)", () => {
nav.startCalendarMonth = { year: 2024, month: 1 };
nav.navigatePrevStart();
expect(nav.startCalendarMonth).toEqual({ year: 2023, month: 12 });
});
it("does nothing when startCalendarMonth is null", () => {
nav.startCalendarMonth = null;
nav.navigatePrevStart();
expect(nav.startCalendarMonth).toBeNull();
expect(onNavigate).not.toHaveBeenCalled();
});
});
describe("navigateNextStart", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("moves start calendar forward one month when possible", () => {
nav.navigateNextStart();
expect(nav.startCalendarMonth).toEqual({ year: 2024, month: 4 });
});
it("calls onNavigate callback", () => {
nav.navigateNextStart();
expect(onNavigate).toHaveBeenCalledTimes(1);
});
it("handles year boundary (December to January)", () => {
nav.startCalendarMonth = { year: 2024, month: 12 };
nav.endCalendarMonth = { year: 2025, month: 3 };
nav.navigateNextStart();
expect(nav.startCalendarMonth).toEqual({ year: 2025, month: 1 });
});
it("does nothing when calendars would become adjacent", () => {
nav.startCalendarMonth = { year: 2024, month: 5 };
nav.endCalendarMonth = { year: 2024, month: 6 };
nav.navigateNextStart();
// Should not change since they're already adjacent
expect(nav.startCalendarMonth).toEqual({ year: 2024, month: 5 });
expect(onNavigate).not.toHaveBeenCalled();
});
});
describe("navigatePrevEnd", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("moves end calendar back one month when possible", () => {
nav.navigatePrevEnd();
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 5 });
});
it("calls onNavigate callback", () => {
nav.navigatePrevEnd();
expect(onNavigate).toHaveBeenCalledTimes(1);
});
it("handles year boundary (January to December)", () => {
nav.startCalendarMonth = { year: 2024, month: 10 };
nav.endCalendarMonth = { year: 2025, month: 1 };
nav.navigatePrevEnd();
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 12 });
});
it("does nothing when calendars would become adjacent", () => {
nav.startCalendarMonth = { year: 2024, month: 5 };
nav.endCalendarMonth = { year: 2024, month: 6 };
nav.navigatePrevEnd();
// Should not change since they're already adjacent
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 6 });
expect(onNavigate).not.toHaveBeenCalled();
});
});
describe("navigateNextEnd", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("moves end calendar forward one month", () => {
nav.navigateNextEnd();
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 7 });
});
it("calls onNavigate callback", () => {
nav.navigateNextEnd();
expect(onNavigate).toHaveBeenCalledTimes(1);
});
it("handles year boundary (December to January)", () => {
nav.endCalendarMonth = { year: 2024, month: 12 };
nav.navigateNextEnd();
expect(nav.endCalendarMonth).toEqual({ year: 2025, month: 1 });
});
it("does nothing when endCalendarMonth is null", () => {
nav.endCalendarMonth = null;
nav.navigateNextEnd();
expect(nav.endCalendarMonth).toBeNull();
expect(onNavigate).not.toHaveBeenCalled();
});
});
describe("updateForSelection", () => {
let nav;
let onNavigate;
beforeEach(() => {
onNavigate = vi.fn();
nav = new CalendarNavigation(
{ year: 2024, month: 3, day: 1 },
{ year: 2024, month: 6, day: 1 },
onNavigate,
);
});
it("updates calendars to show selection range in different months", () => {
nav.updateForSelection(
{ year: 2024, month: 8 },
{ year: 2024, month: 11 },
);
expect(nav.startCalendarMonth).toEqual({ year: 2024, month: 8 });
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 11 });
});
it("adjusts when selection is in the same month", () => {
nav.updateForSelection(
{ year: 2024, month: 9 },
{ year: 2024, month: 9 },
);
// Should show previous month in start calendar
expect(nav.startCalendarMonth).toEqual({ year: 2024, month: 8 });
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 9 });
});
it("handles year boundary for same-month selection in January", () => {
nav.updateForSelection(
{ year: 2024, month: 1 },
{ year: 2024, month: 1 },
);
expect(nav.startCalendarMonth).toEqual({ year: 2023, month: 12 });
expect(nav.endCalendarMonth).toEqual({ year: 2024, month: 1 });
});
it("handles selection spanning years", () => {
nav.updateForSelection(
{ year: 2024, month: 11 },
{ year: 2025, month: 2 },
);
expect(nav.startCalendarMonth).toEqual({ year: 2024, month: 11 });
expect(nav.endCalendarMonth).toEqual({ year: 2025, month: 2 });
});
});
});