@simplysm/core-common 13.0.99 → 14.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/dist/common.types.d.ts +14 -14
  2. package/dist/common.types.js +2 -1
  3. package/dist/common.types.js.map +1 -6
  4. package/dist/env.d.ts +5 -0
  5. package/dist/env.d.ts.map +1 -1
  6. package/dist/env.js +12 -8
  7. package/dist/env.js.map +1 -6
  8. package/dist/errors/argument-error.d.ts +10 -10
  9. package/dist/errors/argument-error.d.ts.map +1 -1
  10. package/dist/errors/argument-error.js +31 -14
  11. package/dist/errors/argument-error.js.map +1 -6
  12. package/dist/errors/not-implemented-error.d.ts +8 -8
  13. package/dist/errors/not-implemented-error.js +30 -12
  14. package/dist/errors/not-implemented-error.js.map +1 -6
  15. package/dist/errors/sd-error.d.ts +10 -10
  16. package/dist/errors/sd-error.d.ts.map +1 -1
  17. package/dist/errors/sd-error.js +45 -24
  18. package/dist/errors/sd-error.js.map +1 -6
  19. package/dist/errors/timeout-error.d.ts +10 -10
  20. package/dist/errors/timeout-error.js +34 -15
  21. package/dist/errors/timeout-error.js.map +1 -6
  22. package/dist/extensions/arr-ext.d.ts +2 -2
  23. package/dist/extensions/arr-ext.helpers.d.ts +10 -10
  24. package/dist/extensions/arr-ext.helpers.js +112 -89
  25. package/dist/extensions/arr-ext.helpers.js.map +1 -6
  26. package/dist/extensions/arr-ext.js +458 -422
  27. package/dist/extensions/arr-ext.js.map +1 -6
  28. package/dist/extensions/arr-ext.types.d.ts +57 -57
  29. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  30. package/dist/extensions/arr-ext.types.js +6 -1
  31. package/dist/extensions/arr-ext.types.js.map +1 -6
  32. package/dist/extensions/map-ext.d.ts +16 -16
  33. package/dist/extensions/map-ext.js +27 -22
  34. package/dist/extensions/map-ext.js.map +1 -6
  35. package/dist/extensions/set-ext.d.ts +11 -11
  36. package/dist/extensions/set-ext.js +32 -25
  37. package/dist/extensions/set-ext.js.map +1 -6
  38. package/dist/features/debounce-queue.d.ts +17 -17
  39. package/dist/features/debounce-queue.js +98 -70
  40. package/dist/features/debounce-queue.js.map +1 -6
  41. package/dist/features/event-emitter.d.ts +20 -20
  42. package/dist/features/event-emitter.js +101 -78
  43. package/dist/features/event-emitter.js.map +1 -6
  44. package/dist/features/serial-queue.d.ts +11 -11
  45. package/dist/features/serial-queue.js +78 -57
  46. package/dist/features/serial-queue.js.map +1 -6
  47. package/dist/globals.d.ts +4 -4
  48. package/dist/globals.js +9 -1
  49. package/dist/globals.js.map +1 -6
  50. package/dist/index.js +28 -27
  51. package/dist/index.js.map +1 -6
  52. package/dist/types/date-only.d.ts +64 -64
  53. package/dist/types/date-only.d.ts.map +1 -1
  54. package/dist/types/date-only.js +263 -252
  55. package/dist/types/date-only.js.map +1 -6
  56. package/dist/types/date-time.d.ts +36 -36
  57. package/dist/types/date-time.d.ts.map +1 -1
  58. package/dist/types/date-time.js +196 -288
  59. package/dist/types/date-time.js.map +1 -6
  60. package/dist/types/lazy-gc-map.d.ts +26 -26
  61. package/dist/types/lazy-gc-map.d.ts.map +1 -1
  62. package/dist/types/lazy-gc-map.js +202 -159
  63. package/dist/types/lazy-gc-map.js.map +1 -6
  64. package/dist/types/time.d.ts +23 -23
  65. package/dist/types/time.d.ts.map +1 -1
  66. package/dist/types/time.js +169 -158
  67. package/dist/types/time.js.map +1 -6
  68. package/dist/types/uuid.d.ts +11 -11
  69. package/dist/types/uuid.d.ts.map +1 -1
  70. package/dist/types/uuid.js +95 -70
  71. package/dist/types/uuid.js.map +1 -6
  72. package/dist/utils/bytes.d.ts +17 -17
  73. package/dist/utils/bytes.js +137 -81
  74. package/dist/utils/bytes.js.map +1 -6
  75. package/dist/utils/date-format.d.ts +40 -40
  76. package/dist/utils/date-format.js +187 -101
  77. package/dist/utils/date-format.js.map +1 -6
  78. package/dist/utils/error.d.ts +4 -4
  79. package/dist/utils/error.js +11 -6
  80. package/dist/utils/error.js.map +1 -6
  81. package/dist/utils/json.d.ts +19 -19
  82. package/dist/utils/json.js +187 -135
  83. package/dist/utils/json.js.map +1 -6
  84. package/dist/utils/num.d.ts +20 -20
  85. package/dist/utils/num.js +76 -34
  86. package/dist/utils/num.js.map +1 -6
  87. package/dist/utils/obj.d.ts +111 -111
  88. package/dist/utils/obj.d.ts.map +1 -1
  89. package/dist/utils/obj.js +706 -496
  90. package/dist/utils/obj.js.map +1 -6
  91. package/dist/utils/path.d.ts +10 -10
  92. package/dist/utils/path.js +35 -18
  93. package/dist/utils/path.js.map +1 -6
  94. package/dist/utils/primitive.d.ts +5 -5
  95. package/dist/utils/primitive.js +34 -14
  96. package/dist/utils/primitive.js.map +1 -6
  97. package/dist/utils/str.d.ts +38 -38
  98. package/dist/utils/str.js +217 -113
  99. package/dist/utils/str.js.map +1 -6
  100. package/dist/utils/template-strings.d.ts +26 -26
  101. package/dist/utils/template-strings.js +113 -40
  102. package/dist/utils/template-strings.js.map +1 -6
  103. package/dist/utils/transferable.d.ts +18 -18
  104. package/dist/utils/transferable.js +218 -151
  105. package/dist/utils/transferable.js.map +1 -6
  106. package/dist/utils/wait.d.ts +9 -9
  107. package/dist/utils/wait.js +30 -15
  108. package/dist/utils/wait.js.map +1 -6
  109. package/dist/utils/xml.d.ts +13 -13
  110. package/dist/utils/xml.js +84 -46
  111. package/dist/utils/xml.js.map +1 -6
  112. package/dist/utils/zip.d.ts +22 -22
  113. package/dist/utils/zip.js +172 -148
  114. package/dist/utils/zip.js.map +1 -6
  115. package/package.json +5 -7
  116. package/src/common.types.ts +14 -14
  117. package/src/env.ts +9 -1
  118. package/src/errors/argument-error.ts +15 -15
  119. package/src/errors/not-implemented-error.ts +9 -9
  120. package/src/errors/sd-error.ts +12 -12
  121. package/src/errors/timeout-error.ts +12 -12
  122. package/src/extensions/arr-ext.helpers.ts +16 -16
  123. package/src/extensions/arr-ext.ts +35 -35
  124. package/src/extensions/arr-ext.types.ts +57 -57
  125. package/src/extensions/map-ext.ts +16 -16
  126. package/src/extensions/set-ext.ts +11 -11
  127. package/src/features/debounce-queue.ts +23 -23
  128. package/src/features/event-emitter.ts +25 -25
  129. package/src/features/serial-queue.ts +13 -13
  130. package/src/globals.ts +4 -4
  131. package/src/index.ts +5 -5
  132. package/src/types/date-only.ts +84 -83
  133. package/src/types/date-time.ts +43 -42
  134. package/src/types/lazy-gc-map.ts +44 -44
  135. package/src/types/time.ts +29 -29
  136. package/src/types/uuid.ts +15 -15
  137. package/src/utils/bytes.ts +35 -35
  138. package/src/utils/date-format.ts +59 -59
  139. package/src/utils/error.ts +4 -4
  140. package/src/utils/json.ts +41 -41
  141. package/src/utils/num.ts +20 -20
  142. package/src/utils/obj.ts +138 -138
  143. package/src/utils/path.ts +10 -10
  144. package/src/utils/primitive.ts +6 -6
  145. package/src/utils/str.ts +48 -48
  146. package/src/utils/template-strings.ts +29 -29
  147. package/src/utils/transferable.ts +38 -38
  148. package/src/utils/wait.ts +10 -10
  149. package/src/utils/xml.ts +19 -19
  150. package/src/utils/zip.ts +25 -25
  151. package/README.md +0 -160
  152. package/docs/errors.md +0 -119
  153. package/docs/extensions.md +0 -387
  154. package/docs/features.md +0 -143
  155. package/docs/types.md +0 -287
  156. package/docs/utils.md +0 -757
  157. package/tests/errors/errors.spec.ts +0 -80
  158. package/tests/extensions/array-extension.spec.ts +0 -654
  159. package/tests/extensions/map-extension.spec.ts +0 -117
  160. package/tests/extensions/set-extension.spec.ts +0 -67
  161. package/tests/types/date-only.spec.ts +0 -533
  162. package/tests/types/date-time.spec.ts +0 -246
  163. package/tests/types/lazy-gc-map.spec.ts +0 -606
  164. package/tests/types/time.spec.ts +0 -428
  165. package/tests/types/uuid.spec.ts +0 -74
  166. package/tests/utils/bytes-utils.spec.ts +0 -197
  167. package/tests/utils/date-format.spec.ts +0 -350
  168. package/tests/utils/debounce-queue.spec.ts +0 -226
  169. package/tests/utils/json.spec.ts +0 -400
  170. package/tests/utils/number.spec.ts +0 -136
  171. package/tests/utils/object.spec.ts +0 -810
  172. package/tests/utils/path.spec.ts +0 -70
  173. package/tests/utils/primitive.spec.ts +0 -43
  174. package/tests/utils/sd-event-emitter.spec.ts +0 -189
  175. package/tests/utils/serial-queue.spec.ts +0 -305
  176. package/tests/utils/string.spec.ts +0 -265
  177. package/tests/utils/template-strings.spec.ts +0 -48
  178. package/tests/utils/transferable.spec.ts +0 -639
  179. package/tests/utils/wait.spec.ts +0 -123
  180. package/tests/utils/xml.spec.ts +0 -146
  181. package/tests/utils/zip.spec.ts +0 -221
@@ -1,533 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { DateOnly } from "@simplysm/core-common";
3
-
4
- describe("DateOnly", () => {
5
- //#region Constructor
6
-
7
- describe("constructor", () => {
8
- it("Returns today's date when created without arguments", () => {
9
- const now = new Date();
10
- const dateOnly = new DateOnly();
11
-
12
- expect(dateOnly.year).toBe(now.getFullYear());
13
- expect(dateOnly.month).toBe(now.getMonth() + 1);
14
- expect(dateOnly.day).toBe(now.getDate());
15
- });
16
-
17
- it("Creates with year/month/day", () => {
18
- const dateOnly = new DateOnly(2025, 1, 6);
19
-
20
- expect(dateOnly.year).toBe(2025);
21
- expect(dateOnly.month).toBe(1);
22
- expect(dateOnly.day).toBe(6);
23
- });
24
-
25
- it("Creates with tick (millisecond)", () => {
26
- const tick = new Date(2025, 0, 6).getTime();
27
- const dateOnly = new DateOnly(tick);
28
-
29
- expect(dateOnly.year).toBe(2025);
30
- expect(dateOnly.month).toBe(1);
31
- expect(dateOnly.day).toBe(6);
32
- });
33
-
34
- it("Creates with Date type", () => {
35
- const date = new Date(2025, 0, 6, 15, 30, 45);
36
- const dateOnly = new DateOnly(date);
37
-
38
- expect(dateOnly.year).toBe(2025);
39
- expect(dateOnly.month).toBe(1);
40
- expect(dateOnly.day).toBe(6);
41
- });
42
-
43
- it("Ignores time when creating from Date type", () => {
44
- const date1 = new Date(2025, 0, 6, 0, 0, 0);
45
- const date2 = new Date(2025, 0, 6, 23, 59, 59);
46
-
47
- const dateOnly1 = new DateOnly(date1);
48
- const dateOnly2 = new DateOnly(date2);
49
-
50
- expect(dateOnly1.tick).toBe(dateOnly2.tick);
51
- });
52
-
53
- it("Creates February 29 in leap year", () => {
54
- const dateOnly = new DateOnly(2024, 2, 29);
55
-
56
- expect(dateOnly.year).toBe(2024);
57
- expect(dateOnly.month).toBe(2);
58
- expect(dateOnly.day).toBe(29);
59
- expect(dateOnly.isValid).toBe(true);
60
- });
61
-
62
- it("Adjusts February 29 to March 1 in non-leap year (JS Date behavior)", () => {
63
- const dateOnly = new DateOnly(2023, 2, 29);
64
-
65
- expect(dateOnly.year).toBe(2023);
66
- expect(dateOnly.month).toBe(3);
67
- expect(dateOnly.day).toBe(1);
68
- });
69
-
70
- it("Adjusts invalid month (13) to January next year (JS Date behavior)", () => {
71
- const dateOnly = new DateOnly(2024, 13, 1);
72
-
73
- expect(dateOnly.year).toBe(2025);
74
- expect(dateOnly.month).toBe(1);
75
- expect(dateOnly.day).toBe(1);
76
- });
77
- });
78
-
79
- //#endregion
80
-
81
- //#region parse
82
-
83
- describe("parse()", () => {
84
- it("Parses yyyy-MM-dd format", () => {
85
- const dateOnly = DateOnly.parse("2025-01-06");
86
-
87
- expect(dateOnly.year).toBe(2025);
88
- expect(dateOnly.month).toBe(1);
89
- expect(dateOnly.day).toBe(6);
90
- });
91
-
92
- it("Parses yyyyMMdd format", () => {
93
- const dateOnly = DateOnly.parse("20250106");
94
-
95
- expect(dateOnly.year).toBe(2025);
96
- expect(dateOnly.month).toBe(1);
97
- expect(dateOnly.day).toBe(6);
98
- });
99
-
100
- it("Parses ISO 8601 format", () => {
101
- const dateOnly = DateOnly.parse("2025-01-06T00:00:00Z");
102
-
103
- expect(dateOnly.year).toBe(2025);
104
- expect(dateOnly.month).toBe(1);
105
- expect(dateOnly.day).toBe(6);
106
- });
107
-
108
- it("Throws error for invalid format", () => {
109
- expect(() => DateOnly.parse("invalid-date")).toThrow("Failed to parse date format");
110
- });
111
-
112
- it("Parses February 29 in leap year", () => {
113
- const dateOnly = DateOnly.parse("2024-02-29");
114
-
115
- expect(dateOnly.year).toBe(2024);
116
- expect(dateOnly.month).toBe(2);
117
- expect(dateOnly.day).toBe(29);
118
- });
119
- });
120
-
121
- //#endregion
122
-
123
- //#region Getters
124
-
125
- describe("Getters", () => {
126
- it("Invalid date returns isValid as false", () => {
127
- const dateOnly = new DateOnly(NaN);
128
- expect(dateOnly.isValid).toBe(false);
129
- });
130
- });
131
-
132
- //#endregion
133
-
134
- //#region setX methods (immutable)
135
-
136
- describe("setYear()", () => {
137
- it("Returns new instance with year changed", () => {
138
- const dateOnly = new DateOnly(2025, 1, 6);
139
- const newDateOnly = dateOnly.setYear(2026);
140
-
141
- expect(newDateOnly.year).toBe(2026);
142
- expect(newDateOnly.month).toBe(1);
143
- expect(newDateOnly.day).toBe(6);
144
- expect(dateOnly.year).toBe(2025); // original immutable
145
- });
146
-
147
- it("Adjusts February 29 from leap year to non-leap year with setYear", () => {
148
- const dateOnly = new DateOnly(2024, 2, 29); // 2024 is leap year
149
- const newDateOnly = dateOnly.setYear(2023); // 2023 is non-leap year
150
-
151
- expect(newDateOnly.year).toBe(2023);
152
- expect(newDateOnly.month).toBe(3);
153
- expect(newDateOnly.day).toBe(1); // February 29 → March 1
154
- });
155
- });
156
-
157
- describe("setMonth()", () => {
158
- it("Returns new instance with month changed", () => {
159
- const dateOnly = new DateOnly(2025, 1, 6);
160
- const newDateOnly = dateOnly.setMonth(2);
161
-
162
- expect(newDateOnly.year).toBe(2025);
163
- expect(newDateOnly.month).toBe(2);
164
- expect(newDateOnly.day).toBe(6);
165
- expect(dateOnly.month).toBe(1); // original immutable
166
- });
167
-
168
- it("Adjusts to last day of month if target month has fewer days", () => {
169
- // January 31 → February (28 days max)
170
- const dateOnly = new DateOnly(2025, 1, 31);
171
- const newDateOnly = dateOnly.setMonth(2);
172
-
173
- expect(newDateOnly.month).toBe(2);
174
- expect(newDateOnly.day).toBe(28); // February's last day
175
- });
176
-
177
- it("setMonth(13) returns January next year", () => {
178
- const dateOnly = new DateOnly(2025, 6, 15);
179
- const result = dateOnly.setMonth(13);
180
-
181
- expect(result.year).toBe(2026);
182
- expect(result.month).toBe(1);
183
- expect(result.day).toBe(15);
184
- });
185
-
186
- it("setMonth(0) returns December previous year", () => {
187
- const dateOnly = new DateOnly(2025, 6, 15);
188
- const result = dateOnly.setMonth(0);
189
-
190
- expect(result.year).toBe(2024);
191
- expect(result.month).toBe(12);
192
- expect(result.day).toBe(15);
193
- });
194
-
195
- it("setMonth(-1) returns November previous year", () => {
196
- const dateOnly = new DateOnly(2025, 6, 15);
197
- const result = dateOnly.setMonth(-1);
198
-
199
- expect(result.year).toBe(2024);
200
- expect(result.month).toBe(11);
201
- expect(result.day).toBe(15);
202
- });
203
- });
204
-
205
- //#endregion
206
-
207
- //#region addX methods (immutable)
208
-
209
- describe("addYears()", () => {
210
- it("Adds positive years", () => {
211
- const dateOnly = new DateOnly(2025, 1, 6);
212
- const newDateOnly = dateOnly.addYears(2);
213
-
214
- expect(newDateOnly.year).toBe(2027);
215
- expect(newDateOnly.month).toBe(1);
216
- expect(newDateOnly.day).toBe(6);
217
- });
218
-
219
- it("Adds negative years (subtraction)", () => {
220
- const dateOnly = new DateOnly(2025, 1, 6);
221
- const newDateOnly = dateOnly.addYears(-1);
222
-
223
- expect(newDateOnly.year).toBe(2024);
224
- });
225
- });
226
-
227
- describe("addMonths()", () => {
228
- it("Adds positive months", () => {
229
- const dateOnly = new DateOnly(2025, 1, 6);
230
- const newDateOnly = dateOnly.addMonths(3);
231
-
232
- expect(newDateOnly.year).toBe(2025);
233
- expect(newDateOnly.month).toBe(4);
234
- expect(newDateOnly.day).toBe(6);
235
- });
236
-
237
- it("Adds negative months (subtraction)", () => {
238
- const dateOnly = new DateOnly(2025, 3, 6);
239
- const newDateOnly = dateOnly.addMonths(-2);
240
-
241
- expect(newDateOnly.month).toBe(1);
242
- });
243
-
244
- it("Handles year boundary when adding months", () => {
245
- const dateOnly = new DateOnly(2025, 11, 6);
246
- const newDateOnly = dateOnly.addMonths(3);
247
-
248
- expect(newDateOnly.year).toBe(2026);
249
- expect(newDateOnly.month).toBe(2);
250
- });
251
- });
252
-
253
- describe("addDays()", () => {
254
- it("Adds positive days", () => {
255
- const dateOnly = new DateOnly(2025, 1, 6);
256
- const newDateOnly = dateOnly.addDays(10);
257
-
258
- expect(newDateOnly.year).toBe(2025);
259
- expect(newDateOnly.month).toBe(1);
260
- expect(newDateOnly.day).toBe(16);
261
- });
262
-
263
- it("Adds negative days (subtraction)", () => {
264
- const dateOnly = new DateOnly(2025, 1, 16);
265
- const newDateOnly = dateOnly.addDays(-10);
266
-
267
- expect(newDateOnly.day).toBe(6);
268
- });
269
-
270
- it("Handles month boundary when adding days", () => {
271
- const dateOnly = new DateOnly(2025, 1, 31);
272
- const newDateOnly = dateOnly.addDays(1);
273
-
274
- expect(newDateOnly.month).toBe(2);
275
- expect(newDateOnly.day).toBe(1);
276
- });
277
- });
278
-
279
- //#endregion
280
-
281
- //#region Formatting
282
-
283
- describe("toFormatString()", () => {
284
- it("Formats to yyyy-MM-dd format", () => {
285
- const dateOnly = new DateOnly(2025, 1, 6);
286
- expect(dateOnly.toFormatString("yyyy-MM-dd")).toBe("2025-01-06");
287
- });
288
-
289
- it("Formats to yyyyMMdd format", () => {
290
- const dateOnly = new DateOnly(2025, 1, 6);
291
- expect(dateOnly.toFormatString("yyyyMMdd")).toBe("20250106");
292
- });
293
-
294
- it("Formats with Korean date format pattern (yyyy year M month d day)", () => {
295
- const dateOnly = new DateOnly(2025, 1, 6);
296
- expect(dateOnly.toFormatString("yyyy년 M월 d일")).toBe("2025년 1월 6일");
297
- });
298
-
299
- it("Formats with day of week", () => {
300
- // 2025-01-06 is Monday
301
- const dateOnly = new DateOnly(2025, 1, 6);
302
- expect(dateOnly.toFormatString("yyyy-MM-dd (ddd)")).toBe("2025-01-06 (월)");
303
- });
304
- });
305
-
306
- describe("toString()", () => {
307
- it("Returns default format yyyy-MM-dd", () => {
308
- const dateOnly = new DateOnly(2025, 1, 6);
309
- expect(dateOnly.toString()).toBe("2025-01-06");
310
- });
311
- });
312
-
313
- //#endregion
314
-
315
- //#region Week calculation
316
-
317
- describe("getWeekSeqOfYear()", () => {
318
- describe("ISO 8601 standard (Monday start, first week min 4 days)", () => {
319
- it("returns week sequence in middle of year", () => {
320
- // 2025-01-06 (Monday)
321
- const dateOnly = new DateOnly(2025, 1, 6);
322
- const result = dateOnly.getWeekSeqOfYear();
323
-
324
- expect(result.year).toBe(2025);
325
- expect(result.weekSeq).toBe(2);
326
- });
327
-
328
- it("handles year-start when within week 1 of current year", () => {
329
- // 2025-01-01 (Wednesday) - ISO 8601, January 2 (Thursday) is in same week, so 2025 week 1
330
- const dateOnly = new DateOnly(2025, 1, 1);
331
- const result = dateOnly.getWeekSeqOfYear();
332
-
333
- expect(result.year).toBe(2025);
334
- expect(result.weekSeq).toBe(1);
335
- });
336
-
337
- it("handles year-end when belonging to next year's week", () => {
338
- // 2024-12-30 (Monday) - Same week has 2025 January 2 (Thursday), so 2025 week 1
339
- const dateOnly = new DateOnly(2024, 12, 30);
340
- const result = dateOnly.getWeekSeqOfYear();
341
-
342
- expect(result.year).toBe(2025);
343
- expect(result.weekSeq).toBe(1);
344
- });
345
- });
346
-
347
- describe("US style (Sunday start, first week min 1 day)", () => {
348
- it("year's first day belongs to week 1", () => {
349
- // 2025-01-01 (Wednesday)
350
- const dateOnly = new DateOnly(2025, 1, 1);
351
- const result = dateOnly.getWeekSeqOfYear(0, 1);
352
-
353
- expect(result.year).toBe(2025);
354
- expect(result.weekSeq).toBe(1);
355
- });
356
-
357
- it("returns week sequence in middle of year", () => {
358
- // 2025-01-12 (Sunday) - US style week 3 start
359
- const dateOnly = new DateOnly(2025, 1, 12);
360
- const result = dateOnly.getWeekSeqOfYear(0, 1);
361
-
362
- expect(result.year).toBe(2025);
363
- expect(result.weekSeq).toBe(3);
364
- });
365
- });
366
-
367
- describe("Leap year handling", () => {
368
- it("handles February 29 in leap year", () => {
369
- // 2024 is leap year, 2024-02-29 (Thursday)
370
- const dateOnly = new DateOnly(2024, 2, 29);
371
- const result = dateOnly.getWeekSeqOfYear();
372
-
373
- expect(result.year).toBe(2024);
374
- expect(result.weekSeq).toBe(9);
375
- });
376
- });
377
- });
378
-
379
- describe("getWeekSeqOfMonth()", () => {
380
- describe("ISO 8601 standard (Monday start, first week min 4 days)", () => {
381
- it("returns week sequence in middle of month", () => {
382
- // 2025-01-15 (Wednesday)
383
- const dateOnly = new DateOnly(2025, 1, 15);
384
- const result = dateOnly.getWeekSeqOfMonth();
385
-
386
- expect(result.year).toBe(2025);
387
- expect(result.monthSeq).toBe(1);
388
- expect(result.weekSeq).toBe(3);
389
- });
390
-
391
- it("handles month-start when belonging to previous month's week", () => {
392
- // 2025-02-01 (Saturday) - Belongs to January's last week
393
- const dateOnly = new DateOnly(2025, 2, 1);
394
- const result = dateOnly.getWeekSeqOfMonth();
395
-
396
- // February 1 is Saturday, doesn't meet 4-day minimum, so January week
397
- expect(result.monthSeq).toBe(1);
398
- });
399
-
400
- it("handles month-end when potentially belonging to next month's week", () => {
401
- // 2025-01-30 (Thursday) - Can belong to February week
402
- const dateOnly = new DateOnly(2025, 1, 30);
403
- const result = dateOnly.getWeekSeqOfMonth();
404
-
405
- expect(result.year).toBe(2025);
406
- });
407
- });
408
-
409
- describe("US style (Sunday start, first week min 1 day)", () => {
410
- it("month's first day belongs to week 1", () => {
411
- // 2025-01-01 (Wednesday)
412
- const dateOnly = new DateOnly(2025, 1, 1);
413
- const result = dateOnly.getWeekSeqOfMonth(0, 1);
414
-
415
- expect(result.year).toBe(2025);
416
- expect(result.monthSeq).toBe(1);
417
- expect(result.weekSeq).toBe(1);
418
- });
419
- });
420
- });
421
-
422
- describe("getBaseYearMonthSeqForWeekSeq()", () => {
423
- it("returns current year-month for general date", () => {
424
- const dateOnly = new DateOnly(2025, 1, 15);
425
- const result = dateOnly.getBaseYearMonthSeqForWeekSeq();
426
-
427
- expect(result.year).toBe(2025);
428
- expect(result.monthSeq).toBe(1);
429
- });
430
-
431
- it("can return previous month at month boundary", () => {
432
- // May vary based on week start day
433
- const dateOnly = new DateOnly(2025, 2, 1);
434
- const result = dateOnly.getBaseYearMonthSeqForWeekSeq();
435
-
436
- // 2025-02-01 is Saturday, so may belong to January week
437
- expect(result.year).toBe(2025);
438
- });
439
- });
440
-
441
- describe("getWeekSeqStartDate()", () => {
442
- describe("ISO 8601 standard (Monday start)", () => {
443
- it("returns week start date (Monday)", () => {
444
- // 2025-01-08 (Wednesday)
445
- const dateOnly = new DateOnly(2025, 1, 8);
446
- const result = dateOnly.getWeekSeqStartDate();
447
-
448
- expect(result.year).toBe(2025);
449
- expect(result.month).toBe(1);
450
- expect(result.day).toBe(6); // Monday
451
- expect(result.dayOfWeek).toBe(1);
452
- });
453
-
454
- it("returns same date if already Monday", () => {
455
- // 2025-01-06 (Monday)
456
- const dateOnly = new DateOnly(2025, 1, 6);
457
- const result = dateOnly.getWeekSeqStartDate();
458
-
459
- expect(result.day).toBe(6);
460
- });
461
- });
462
-
463
- describe("US style (Sunday start)", () => {
464
- it("returns week start date (Sunday)", () => {
465
- // 2025-01-08 (Wednesday)
466
- const dateOnly = new DateOnly(2025, 1, 8);
467
- const result = dateOnly.getWeekSeqStartDate(0, 1);
468
-
469
- expect(result.year).toBe(2025);
470
- expect(result.month).toBe(1);
471
- expect(result.day).toBe(5); // Sunday
472
- expect(result.dayOfWeek).toBe(0);
473
- });
474
- });
475
- });
476
-
477
- describe("getDateByYearWeekSeq()", () => {
478
- describe("ISO 8601 standard", () => {
479
- it("returns start date from year week sequence", () => {
480
- // 2025 week 2
481
- const result = DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 2 });
482
-
483
- expect(result.year).toBe(2025);
484
- expect(result.month).toBe(1);
485
- expect(result.day).toBe(6); // 2025-01-06 (Monday)
486
- });
487
-
488
- it("returns start date from year-month week sequence", () => {
489
- // 2025 January week 3
490
- const result = DateOnly.getDateByYearWeekSeq({ year: 2025, month: 1, weekSeq: 3 });
491
-
492
- expect(result.year).toBe(2025);
493
- expect(result.month).toBe(1);
494
- expect(result.day).toBe(13); // 2025-01-13 (Monday)
495
- });
496
- });
497
-
498
- describe("US style", () => {
499
- it("returns start date from year week sequence", () => {
500
- // 2025 week 1 (US style)
501
- const result = DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 1 }, 0, 1);
502
-
503
- expect(result.year).toBe(2024);
504
- expect(result.month).toBe(12);
505
- expect(result.day).toBe(29); // 2024-12-29 (Sunday)
506
- });
507
- });
508
-
509
- describe("Year boundary handling", () => {
510
- it("handles year with 53 weeks", () => {
511
- // 2020 has 53 weeks (ISO 8601)
512
- const result = DateOnly.getDateByYearWeekSeq({ year: 2020, weekSeq: 53 });
513
-
514
- expect(result.year).toBe(2020);
515
- expect(result.month).toBe(12);
516
- expect(result.day).toBe(28); // 2020-12-28 (Monday)
517
- });
518
- });
519
-
520
- describe("Leap year handling", () => {
521
- it("correctly calculates week for leap year", () => {
522
- // 2024 (leap year) week 10
523
- const result = DateOnly.getDateByYearWeekSeq({ year: 2024, weekSeq: 10 });
524
-
525
- expect(result.year).toBe(2024);
526
- expect(result.month).toBe(3);
527
- expect(result.day).toBe(4); // 2024-03-04 (Monday)
528
- });
529
- });
530
- });
531
-
532
- //#endregion
533
- });