1 | import type { Locale } from "date-fns";
|
2 |
|
3 | import {
|
4 | addDays,
|
5 | addWeeks,
|
6 | addMonths,
|
7 | addYears,
|
8 | startOfISOWeek,
|
9 | endOfISOWeek,
|
10 | startOfWeek,
|
11 | endOfWeek
|
12 | } from "date-fns";
|
13 |
|
14 | import type { DayPickerProps, MoveFocusBy, MoveFocusDir } from "../types";
|
15 |
|
16 | import { dateLib } from "..";
|
17 | import { getFocusableDate } from "./getFocusableDate";
|
18 |
|
19 | const focusedDate = new Date(2023, 0, 1);
|
20 | const options: Pick<DayPickerProps, "locale" | "ISOWeek" | "weekStartsOn"> = {
|
21 | locale: undefined,
|
22 | ISOWeek: false,
|
23 | weekStartsOn: 0
|
24 | };
|
25 |
|
26 | const calendarStartMonth = new Date(2022, 0, 1);
|
27 | const calendarEndMonth = new Date(2024, 0, 1);
|
28 |
|
29 | const testCases: {
|
30 | moveBy: MoveFocusBy;
|
31 | moveDir: MoveFocusDir;
|
32 | expectedFn: (date: Date | number, amount: number) => Date;
|
33 | }[] = [
|
34 | { moveBy: "day", moveDir: "after", expectedFn: addDays },
|
35 | { moveBy: "day", moveDir: "before", expectedFn: addDays },
|
36 | { moveBy: "month", moveDir: "after", expectedFn: addMonths },
|
37 | { moveBy: "month", moveDir: "before", expectedFn: addMonths },
|
38 | { moveBy: "week", moveDir: "after", expectedFn: addWeeks },
|
39 | { moveBy: "week", moveDir: "before", expectedFn: addWeeks },
|
40 | { moveBy: "year", moveDir: "after", expectedFn: addYears },
|
41 | { moveBy: "year", moveDir: "before", expectedFn: addYears }
|
42 | ];
|
43 |
|
44 | testCases.forEach(({ moveBy, moveDir, expectedFn }) => {
|
45 | test(`should move ${moveDir} by ${moveBy}`, () => {
|
46 | const expectedDate = expectedFn(focusedDate, moveDir === "after" ? 1 : -1);
|
47 | const result = getFocusableDate(
|
48 | moveBy,
|
49 | moveDir,
|
50 | focusedDate,
|
51 | calendarStartMonth,
|
52 | calendarEndMonth,
|
53 | options,
|
54 | dateLib
|
55 | );
|
56 | expect(result).toEqual(expectedDate);
|
57 | });
|
58 | });
|
59 |
|
60 | const weekTestCases: {
|
61 | moveBy: MoveFocusBy;
|
62 | moveDir: MoveFocusDir;
|
63 | expectedFn: (
|
64 | date: number | Date,
|
65 | options?:
|
66 | | {
|
67 | locale?: Locale | undefined;
|
68 | weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined;
|
69 | }
|
70 | | undefined
|
71 | ) => Date;
|
72 | }[] = [
|
73 | { moveBy: "endOfWeek", moveDir: "after", expectedFn: endOfWeek },
|
74 | { moveBy: "startOfWeek", moveDir: "after", expectedFn: startOfWeek }
|
75 | ];
|
76 |
|
77 | weekTestCases.forEach(({ moveBy, moveDir, expectedFn }) => {
|
78 | test(`should move ${moveDir} by ${moveBy}`, () => {
|
79 | const expectedDate = expectedFn(focusedDate);
|
80 | const result = getFocusableDate(
|
81 | moveBy,
|
82 | moveDir,
|
83 | focusedDate,
|
84 | calendarStartMonth,
|
85 | calendarEndMonth,
|
86 | options,
|
87 | dateLib
|
88 | );
|
89 |
|
90 | expect(result).toEqual(expectedDate);
|
91 | });
|
92 | });
|
93 |
|
94 | const ISOWeekTestCases: {
|
95 | moveBy: MoveFocusBy;
|
96 | moveDir: MoveFocusDir;
|
97 | expectedFn: (date: Date | number) => Date;
|
98 | }[] = [
|
99 | { moveBy: "endOfWeek", moveDir: "after", expectedFn: endOfISOWeek },
|
100 | { moveBy: "startOfWeek", moveDir: "after", expectedFn: startOfISOWeek }
|
101 | ];
|
102 |
|
103 | ISOWeekTestCases.forEach(({ moveBy, moveDir, expectedFn }) => {
|
104 | test(`should move ${moveDir} by ${moveBy} when ISOWeek is true`, () => {
|
105 | const expectedDate = expectedFn(focusedDate);
|
106 | const result = getFocusableDate(
|
107 | moveBy,
|
108 | moveDir,
|
109 | focusedDate,
|
110 | calendarStartMonth,
|
111 | calendarEndMonth,
|
112 | { ...options, ISOWeek: true },
|
113 | dateLib
|
114 | );
|
115 | expect(result).toEqual(expectedDate);
|
116 | });
|
117 | });
|
118 |
|
119 | test("should not move before startMonth", () => {
|
120 | const result = getFocusableDate(
|
121 | "day",
|
122 | "before",
|
123 | new Date(2022, 0, 2),
|
124 | calendarStartMonth,
|
125 | calendarEndMonth,
|
126 | options,
|
127 | dateLib
|
128 | );
|
129 | expect(result).toEqual(calendarStartMonth);
|
130 | });
|
131 |
|
132 | test("should not move after endMonth", () => {
|
133 | const result = getFocusableDate(
|
134 | "day",
|
135 | "after",
|
136 | new Date(2023, 11, 31),
|
137 | calendarStartMonth,
|
138 | calendarEndMonth,
|
139 | options,
|
140 | dateLib
|
141 | );
|
142 | expect(result).toEqual(calendarEndMonth);
|
143 | });
|