@simplysm/core-common 13.0.0-beta.2 → 13.0.0-beta.21

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 (84) hide show
  1. package/dist/common.types.js +4 -4
  2. package/dist/errors/argument-error.js +1 -1
  3. package/dist/errors/not-implemented-error.js +1 -1
  4. package/dist/errors/timeout-error.js +1 -1
  5. package/dist/extensions/arr-ext.helpers.js +4 -4
  6. package/dist/extensions/arr-ext.js +9 -9
  7. package/dist/features/debounce-queue.js +2 -2
  8. package/dist/features/serial-queue.js +3 -3
  9. package/dist/index.js +30 -30
  10. package/dist/types/date-only.js +2 -2
  11. package/dist/types/date-time.js +2 -2
  12. package/dist/types/time.js +2 -2
  13. package/dist/types/uuid.js +1 -1
  14. package/dist/utils/bytes.js +1 -1
  15. package/dist/utils/json.js +8 -8
  16. package/dist/utils/obj.js +5 -5
  17. package/dist/utils/primitive.js +5 -5
  18. package/dist/utils/transferable.js +4 -4
  19. package/dist/utils/wait.js +1 -1
  20. package/package.json +7 -4
  21. package/.cache/typecheck-browser.tsbuildinfo +0 -1
  22. package/.cache/typecheck-node.tsbuildinfo +0 -1
  23. package/.cache/typecheck-tests-browser.tsbuildinfo +0 -1
  24. package/.cache/typecheck-tests-node.tsbuildinfo +0 -1
  25. package/src/common.types.ts +0 -91
  26. package/src/env.ts +0 -11
  27. package/src/errors/argument-error.ts +0 -40
  28. package/src/errors/not-implemented-error.ts +0 -32
  29. package/src/errors/sd-error.ts +0 -53
  30. package/src/errors/timeout-error.ts +0 -36
  31. package/src/extensions/arr-ext.helpers.ts +0 -53
  32. package/src/extensions/arr-ext.ts +0 -777
  33. package/src/extensions/arr-ext.types.ts +0 -258
  34. package/src/extensions/map-ext.ts +0 -86
  35. package/src/extensions/set-ext.ts +0 -68
  36. package/src/features/debounce-queue.ts +0 -116
  37. package/src/features/event-emitter.ts +0 -112
  38. package/src/features/serial-queue.ts +0 -94
  39. package/src/globals.ts +0 -12
  40. package/src/index.ts +0 -55
  41. package/src/types/date-only.ts +0 -329
  42. package/src/types/date-time.ts +0 -294
  43. package/src/types/lazy-gc-map.ts +0 -244
  44. package/src/types/time.ts +0 -210
  45. package/src/types/uuid.ts +0 -113
  46. package/src/utils/bytes.ts +0 -160
  47. package/src/utils/date-format.ts +0 -239
  48. package/src/utils/json.ts +0 -230
  49. package/src/utils/num.ts +0 -97
  50. package/src/utils/obj.ts +0 -956
  51. package/src/utils/path.ts +0 -40
  52. package/src/utils/primitive.ts +0 -33
  53. package/src/utils/str.ts +0 -252
  54. package/src/utils/template-strings.ts +0 -132
  55. package/src/utils/transferable.ts +0 -269
  56. package/src/utils/wait.ts +0 -40
  57. package/src/utils/xml.ts +0 -105
  58. package/src/zip/sd-zip.ts +0 -218
  59. package/tests/errors/errors.spec.ts +0 -196
  60. package/tests/extensions/array-extension.spec.ts +0 -790
  61. package/tests/extensions/map-extension.spec.ts +0 -147
  62. package/tests/extensions/set-extension.spec.ts +0 -74
  63. package/tests/types/date-only.spec.ts +0 -636
  64. package/tests/types/date-time.spec.ts +0 -391
  65. package/tests/types/lazy-gc-map.spec.ts +0 -692
  66. package/tests/types/time.spec.ts +0 -559
  67. package/tests/types/types.spec.ts +0 -55
  68. package/tests/types/uuid.spec.ts +0 -91
  69. package/tests/utils/bytes-utils.spec.ts +0 -230
  70. package/tests/utils/date-format.spec.ts +0 -371
  71. package/tests/utils/debounce-queue.spec.ts +0 -272
  72. package/tests/utils/json.spec.ts +0 -475
  73. package/tests/utils/number.spec.ts +0 -184
  74. package/tests/utils/object.spec.ts +0 -827
  75. package/tests/utils/path.spec.ts +0 -78
  76. package/tests/utils/primitive.spec.ts +0 -55
  77. package/tests/utils/sd-event-emitter.spec.ts +0 -216
  78. package/tests/utils/serial-queue.spec.ts +0 -365
  79. package/tests/utils/string.spec.ts +0 -294
  80. package/tests/utils/template-strings.spec.ts +0 -96
  81. package/tests/utils/transferable.spec.ts +0 -698
  82. package/tests/utils/wait.spec.ts +0 -145
  83. package/tests/utils/xml.spec.ts +0 -146
  84. package/tests/zip/sd-zip.spec.ts +0 -234
@@ -1,636 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { DateOnly } from "@simplysm/core-common";
3
-
4
- describe("DateOnly", () => {
5
- //#region 생성자
6
-
7
- describe("constructor", () => {
8
- it("인수 없이 생성하면 오늘 날짜를 반환한다", () => {
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("연월일로 생성한다", () => {
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("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("Date 타입으로 생성한다", () => {
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("Date 타입으로 생성할 때 시간은 무시한다", () => {
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("윤년 2월 29일을 생성한다", () => {
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("평년 2월 29일은 3월 1일로 자동 조정된다 (JS Date 동작)", () => {
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("유효하지 않은 월(13월)은 다음 해 1월로 자동 조정된다 (JS Date 동작)", () => {
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("yyyy-MM-dd 형식을 파싱한다", () => {
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("yyyyMMdd 형식을 파싱한다", () => {
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("ISO 8601 형식을 파싱한다", () => {
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("잘못된 형식이면 에러를 던진다", () => {
109
- expect(() => DateOnly.parse("invalid-date")).toThrow("날짜 형식을 파싱할 수 없습니다");
110
- });
111
-
112
- it("연말 경계(12월 31일)를 파싱한다", () => {
113
- const dateOnly = DateOnly.parse("2024-12-31");
114
-
115
- expect(dateOnly.year).toBe(2024);
116
- expect(dateOnly.month).toBe(12);
117
- expect(dateOnly.day).toBe(31);
118
- });
119
-
120
- it("연초 경계(1월 1일)를 파싱한다", () => {
121
- const dateOnly = DateOnly.parse("2025-01-01");
122
-
123
- expect(dateOnly.year).toBe(2025);
124
- expect(dateOnly.month).toBe(1);
125
- expect(dateOnly.day).toBe(1);
126
- });
127
-
128
- it("윤년 2월 29일을 파싱한다", () => {
129
- const dateOnly = DateOnly.parse("2024-02-29");
130
-
131
- expect(dateOnly.year).toBe(2024);
132
- expect(dateOnly.month).toBe(2);
133
- expect(dateOnly.day).toBe(29);
134
- });
135
-
136
- it("윤년 2월 28일을 파싱한다", () => {
137
- const dateOnly = DateOnly.parse("2024-02-28");
138
-
139
- expect(dateOnly.year).toBe(2024);
140
- expect(dateOnly.month).toBe(2);
141
- expect(dateOnly.day).toBe(28);
142
- });
143
- });
144
-
145
- //#endregion
146
-
147
- //#region Getters
148
-
149
- describe("Getters", () => {
150
- it("year를 반환한다", () => {
151
- const dateOnly = new DateOnly(2025, 1, 6);
152
- expect(dateOnly.year).toBe(2025);
153
- });
154
-
155
- it("month를 반환한다 (1~12)", () => {
156
- const dateOnly = new DateOnly(2025, 1, 6);
157
- expect(dateOnly.month).toBe(1);
158
- });
159
-
160
- it("day를 반환한다", () => {
161
- const dateOnly = new DateOnly(2025, 1, 6);
162
- expect(dateOnly.day).toBe(6);
163
- });
164
-
165
- it("tick을 반환한다", () => {
166
- const dateOnly = new DateOnly(2025, 1, 6);
167
- expect(dateOnly.tick).toBe(new Date(2025, 0, 6).getTime());
168
- });
169
-
170
- it("dayOfWeek를 반환한다 (일~토: 0~6)", () => {
171
- // 2025-01-06은 월요일 (1)
172
- const dateOnly = new DateOnly(2025, 1, 6);
173
- expect(dateOnly.dayOfWeek).toBe(1);
174
- });
175
-
176
- it("isValid를 반환한다", () => {
177
- const dateOnly = new DateOnly(2025, 1, 6);
178
- expect(dateOnly.isValid).toBe(true);
179
- });
180
-
181
- it("유효하지 않은 날짜는 isValid가 false를 반환한다", () => {
182
- const dateOnly = new DateOnly(NaN);
183
- expect(dateOnly.isValid).toBe(false);
184
- });
185
- });
186
-
187
- //#endregion
188
-
189
- //#region setX 메서드 (불변)
190
-
191
- describe("setYear()", () => {
192
- it("연도를 변경한 새 인스턴스를 반환한다", () => {
193
- const dateOnly = new DateOnly(2025, 1, 6);
194
- const newDateOnly = dateOnly.setYear(2026);
195
-
196
- expect(newDateOnly.year).toBe(2026);
197
- expect(newDateOnly.month).toBe(1);
198
- expect(newDateOnly.day).toBe(6);
199
- expect(dateOnly.year).toBe(2025); // 원본 불변
200
- });
201
-
202
- it("윤년 2월 29일에서 평년으로 setYear하면 3월 1일로 조정된다", () => {
203
- const dateOnly = new DateOnly(2024, 2, 29); // 2024년은 윤년
204
- const newDateOnly = dateOnly.setYear(2023); // 2023년은 평년
205
-
206
- expect(newDateOnly.year).toBe(2023);
207
- expect(newDateOnly.month).toBe(3);
208
- expect(newDateOnly.day).toBe(1); // 2월 29일 → 3월 1일로 조정
209
- });
210
- });
211
-
212
- describe("setMonth()", () => {
213
- it("월을 변경한 새 인스턴스를 반환한다", () => {
214
- const dateOnly = new DateOnly(2025, 1, 6);
215
- const newDateOnly = dateOnly.setMonth(2);
216
-
217
- expect(newDateOnly.year).toBe(2025);
218
- expect(newDateOnly.month).toBe(2);
219
- expect(newDateOnly.day).toBe(6);
220
- expect(dateOnly.month).toBe(1); // 원본 불변
221
- });
222
-
223
- it("대상 월의 마지막 날보다 큰 경우 마지막 날로 조정한다", () => {
224
- // 1월 31일 → 2월 (28일까지)
225
- const dateOnly = new DateOnly(2025, 1, 31);
226
- const newDateOnly = dateOnly.setMonth(2);
227
-
228
- expect(newDateOnly.month).toBe(2);
229
- expect(newDateOnly.day).toBe(28); // 2월 마지막 날
230
- });
231
-
232
- it("setMonth(13)은 다음 해 1월을 반환한다", () => {
233
- const dateOnly = new DateOnly(2025, 6, 15);
234
- const result = dateOnly.setMonth(13);
235
-
236
- expect(result.year).toBe(2026);
237
- expect(result.month).toBe(1);
238
- expect(result.day).toBe(15);
239
- });
240
-
241
- it("setMonth(0)은 이전 해 12월을 반환한다", () => {
242
- const dateOnly = new DateOnly(2025, 6, 15);
243
- const result = dateOnly.setMonth(0);
244
-
245
- expect(result.year).toBe(2024);
246
- expect(result.month).toBe(12);
247
- expect(result.day).toBe(15);
248
- });
249
-
250
- it("setMonth(-1)은 이전 해 11월을 반환한다", () => {
251
- const dateOnly = new DateOnly(2025, 6, 15);
252
- const result = dateOnly.setMonth(-1);
253
-
254
- expect(result.year).toBe(2024);
255
- expect(result.month).toBe(11);
256
- expect(result.day).toBe(15);
257
- });
258
- });
259
-
260
- describe("setDay()", () => {
261
- it("일을 변경한 새 인스턴스를 반환한다", () => {
262
- const dateOnly = new DateOnly(2025, 1, 6);
263
- const newDateOnly = dateOnly.setDay(15);
264
-
265
- expect(newDateOnly.year).toBe(2025);
266
- expect(newDateOnly.month).toBe(1);
267
- expect(newDateOnly.day).toBe(15);
268
- expect(dateOnly.day).toBe(6); // 원본 불변
269
- });
270
- });
271
-
272
- //#endregion
273
-
274
- //#region addX 메서드 (불변)
275
-
276
- describe("addYears()", () => {
277
- it("양수 연도를 더한다", () => {
278
- const dateOnly = new DateOnly(2025, 1, 6);
279
- const newDateOnly = dateOnly.addYears(2);
280
-
281
- expect(newDateOnly.year).toBe(2027);
282
- expect(newDateOnly.month).toBe(1);
283
- expect(newDateOnly.day).toBe(6);
284
- });
285
-
286
- it("음수 연도를 더한다 (빼기)", () => {
287
- const dateOnly = new DateOnly(2025, 1, 6);
288
- const newDateOnly = dateOnly.addYears(-1);
289
-
290
- expect(newDateOnly.year).toBe(2024);
291
- });
292
- });
293
-
294
- describe("addMonths()", () => {
295
- it("양수 월을 더한다", () => {
296
- const dateOnly = new DateOnly(2025, 1, 6);
297
- const newDateOnly = dateOnly.addMonths(3);
298
-
299
- expect(newDateOnly.year).toBe(2025);
300
- expect(newDateOnly.month).toBe(4);
301
- expect(newDateOnly.day).toBe(6);
302
- });
303
-
304
- it("음수 월을 더한다 (빼기)", () => {
305
- const dateOnly = new DateOnly(2025, 3, 6);
306
- const newDateOnly = dateOnly.addMonths(-2);
307
-
308
- expect(newDateOnly.month).toBe(1);
309
- });
310
-
311
- it("연도를 넘어가는 경우를 처리한다", () => {
312
- const dateOnly = new DateOnly(2025, 11, 6);
313
- const newDateOnly = dateOnly.addMonths(3);
314
-
315
- expect(newDateOnly.year).toBe(2026);
316
- expect(newDateOnly.month).toBe(2);
317
- });
318
- });
319
-
320
- describe("addDays()", () => {
321
- it("양수 일을 더한다", () => {
322
- const dateOnly = new DateOnly(2025, 1, 6);
323
- const newDateOnly = dateOnly.addDays(10);
324
-
325
- expect(newDateOnly.year).toBe(2025);
326
- expect(newDateOnly.month).toBe(1);
327
- expect(newDateOnly.day).toBe(16);
328
- });
329
-
330
- it("음수 일을 더한다 (빼기)", () => {
331
- const dateOnly = new DateOnly(2025, 1, 16);
332
- const newDateOnly = dateOnly.addDays(-10);
333
-
334
- expect(newDateOnly.day).toBe(6);
335
- });
336
-
337
- it("월을 넘어가는 경우를 처리한다", () => {
338
- const dateOnly = new DateOnly(2025, 1, 31);
339
- const newDateOnly = dateOnly.addDays(1);
340
-
341
- expect(newDateOnly.month).toBe(2);
342
- expect(newDateOnly.day).toBe(1);
343
- });
344
- });
345
-
346
- //#endregion
347
-
348
- //#region 포맷팅
349
-
350
- describe("toFormatString()", () => {
351
- it("yyyy-MM-dd 형식으로 포맷팅한다", () => {
352
- const dateOnly = new DateOnly(2025, 1, 6);
353
- expect(dateOnly.toFormatString("yyyy-MM-dd")).toBe("2025-01-06");
354
- });
355
-
356
- it("yyyyMMdd 형식으로 포맷팅한다", () => {
357
- const dateOnly = new DateOnly(2025, 1, 6);
358
- expect(dateOnly.toFormatString("yyyyMMdd")).toBe("20250106");
359
- });
360
-
361
- it("yyyy년 M월 d일 형식으로 포맷팅한다", () => {
362
- const dateOnly = new DateOnly(2025, 1, 6);
363
- expect(dateOnly.toFormatString("yyyy년 M월 d일")).toBe("2025년 1월 6일");
364
- });
365
-
366
- it("요일을 포함한 형식으로 포맷팅한다", () => {
367
- // 2025-01-06은 월요일
368
- const dateOnly = new DateOnly(2025, 1, 6);
369
- expect(dateOnly.toFormatString("yyyy-MM-dd (ddd)")).toBe("2025-01-06 (월)");
370
- });
371
- });
372
-
373
- describe("toString()", () => {
374
- it("기본 형식 yyyy-MM-dd로 반환한다", () => {
375
- const dateOnly = new DateOnly(2025, 1, 6);
376
- expect(dateOnly.toString()).toBe("2025-01-06");
377
- });
378
- });
379
-
380
- //#endregion
381
-
382
- //#region tick 비교
383
-
384
- describe("tick 비교", () => {
385
- it("같은 날짜는 같은 tick을 가진다", () => {
386
- const d1 = new DateOnly(2025, 3, 15);
387
- const d2 = new DateOnly(2025, 3, 15);
388
-
389
- expect(d1.tick).toBe(d2.tick);
390
- });
391
-
392
- it("다른 날짜는 다른 tick을 가진다", () => {
393
- const d1 = new DateOnly(2025, 3, 15);
394
- const d2 = new DateOnly(2025, 3, 16);
395
-
396
- expect(d1.tick).not.toBe(d2.tick);
397
- });
398
-
399
- it("tick으로 날짜 순서를 비교할 수 있다", () => {
400
- const d1 = new DateOnly(2025, 1, 1);
401
- const d2 = new DateOnly(2025, 6, 15);
402
- const d3 = new DateOnly(2025, 12, 31);
403
-
404
- expect(d1.tick).toBeLessThan(d2.tick);
405
- expect(d2.tick).toBeLessThan(d3.tick);
406
- });
407
-
408
- it("연도가 다른 날짜도 tick으로 비교할 수 있다", () => {
409
- const d2024 = new DateOnly(2024, 12, 31);
410
- const d2025 = new DateOnly(2025, 1, 1);
411
-
412
- expect(d2024.tick).toBeLessThan(d2025.tick);
413
- });
414
- });
415
-
416
- //#endregion
417
-
418
- //#region 주차 계산
419
-
420
- describe("getWeekSeqOfYear()", () => {
421
- describe("ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)", () => {
422
- it("연도 중간의 주차를 반환한다", () => {
423
- // 2025-01-06 (월요일)
424
- const dateOnly = new DateOnly(2025, 1, 6);
425
- const result = dateOnly.getWeekSeqOfYear();
426
-
427
- expect(result.year).toBe(2025);
428
- expect(result.weekSeq).toBe(2);
429
- });
430
-
431
- it("연초가 이번 연도 1주차에 속하는 경우를 처리한다", () => {
432
- // 2025-01-01 (수요일) - ISO 8601에서 1월 2일(목)이 같은 주에 있으므로 2025년 1주차
433
- const dateOnly = new DateOnly(2025, 1, 1);
434
- const result = dateOnly.getWeekSeqOfYear();
435
-
436
- expect(result.year).toBe(2025);
437
- expect(result.weekSeq).toBe(1);
438
- });
439
-
440
- it("연말이 다음 연도 주차에 속하는 경우를 처리한다", () => {
441
- // 2024-12-30 (월요일) - 같은 주에 2025년 1월 2일(목)이 있으므로 2025년 1주차
442
- const dateOnly = new DateOnly(2024, 12, 30);
443
- const result = dateOnly.getWeekSeqOfYear();
444
-
445
- expect(result.year).toBe(2025);
446
- expect(result.weekSeq).toBe(1);
447
- });
448
- });
449
-
450
- describe("미국식 (일요일 시작, 첫 주 최소 1일)", () => {
451
- it("연도 첫 날이 첫 주차에 속한다", () => {
452
- // 2025-01-01 (수요일)
453
- const dateOnly = new DateOnly(2025, 1, 1);
454
- const result = dateOnly.getWeekSeqOfYear(0, 1);
455
-
456
- expect(result.year).toBe(2025);
457
- expect(result.weekSeq).toBe(1);
458
- });
459
-
460
- it("연도 중간의 주차를 반환한다", () => {
461
- // 2025-01-12 (일요일) - 미국식 3주차 시작
462
- const dateOnly = new DateOnly(2025, 1, 12);
463
- const result = dateOnly.getWeekSeqOfYear(0, 1);
464
-
465
- expect(result.year).toBe(2025);
466
- expect(result.weekSeq).toBe(3);
467
- });
468
- });
469
-
470
- describe("윤년 처리", () => {
471
- it("윤년의 2월 29일을 처리한다", () => {
472
- // 2024년은 윤년, 2024-02-29 (목요일)
473
- const dateOnly = new DateOnly(2024, 2, 29);
474
- const result = dateOnly.getWeekSeqOfYear();
475
-
476
- expect(result.year).toBe(2024);
477
- expect(result.weekSeq).toBe(9);
478
- });
479
- });
480
- });
481
-
482
- describe("getWeekSeqOfMonth()", () => {
483
- describe("ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)", () => {
484
- it("월 중간의 주차를 반환한다", () => {
485
- // 2025-01-15 (수요일)
486
- const dateOnly = new DateOnly(2025, 1, 15);
487
- const result = dateOnly.getWeekSeqOfMonth();
488
-
489
- expect(result.year).toBe(2025);
490
- expect(result.monthSeq).toBe(1);
491
- expect(result.weekSeq).toBe(3);
492
- });
493
-
494
- it("월초가 이전 달 주차에 속하는 경우를 처리한다", () => {
495
- // 2025-02-01 (토요일) - 1월의 마지막 주에 속함
496
- const dateOnly = new DateOnly(2025, 2, 1);
497
- const result = dateOnly.getWeekSeqOfMonth();
498
-
499
- // 2월 1일이 토요일이고 첫 주 최소 4일 조건을 충족하지 못하면 1월 주차
500
- expect(result.monthSeq).toBe(1);
501
- });
502
-
503
- it("월말이 다음 달 주차에 속하는 경우를 처리한다", () => {
504
- // 2025-01-30 (목요일) - 2월 1주차에 속할 수 있음
505
- const dateOnly = new DateOnly(2025, 1, 30);
506
- const result = dateOnly.getWeekSeqOfMonth();
507
-
508
- expect(result.year).toBe(2025);
509
- });
510
- });
511
-
512
- describe("미국식 (일요일 시작, 첫 주 최소 1일)", () => {
513
- it("월 첫 날이 첫 주차에 속한다", () => {
514
- // 2025-01-01 (수요일)
515
- const dateOnly = new DateOnly(2025, 1, 1);
516
- const result = dateOnly.getWeekSeqOfMonth(0, 1);
517
-
518
- expect(result.year).toBe(2025);
519
- expect(result.monthSeq).toBe(1);
520
- expect(result.weekSeq).toBe(1);
521
- });
522
- });
523
- });
524
-
525
- describe("getBaseYearMonthSeqForWeekSeq()", () => {
526
- it("일반적인 날짜에서 현재 연월을 반환한다", () => {
527
- const dateOnly = new DateOnly(2025, 1, 15);
528
- const result = dateOnly.getBaseYearMonthSeqForWeekSeq();
529
-
530
- expect(result.year).toBe(2025);
531
- expect(result.monthSeq).toBe(1);
532
- });
533
-
534
- it("월 경계에서 이전 달을 반환할 수 있다", () => {
535
- // 주 시작 요일에 따라 이전/다음 달로 분류될 수 있음
536
- const dateOnly = new DateOnly(2025, 2, 1);
537
- const result = dateOnly.getBaseYearMonthSeqForWeekSeq();
538
-
539
- // 2025-02-01이 토요일이면 이전 달(1월) 주차에 속함
540
- expect(result.year).toBe(2025);
541
- });
542
- });
543
-
544
- describe("getWeekSeqStartDate()", () => {
545
- describe("ISO 8601 표준 (월요일 시작)", () => {
546
- it("주의 시작 날짜(월요일)를 반환한다", () => {
547
- // 2025-01-08 (수요일)
548
- const dateOnly = new DateOnly(2025, 1, 8);
549
- const result = dateOnly.getWeekSeqStartDate();
550
-
551
- expect(result.year).toBe(2025);
552
- expect(result.month).toBe(1);
553
- expect(result.day).toBe(6); // 월요일
554
- expect(result.dayOfWeek).toBe(1);
555
- });
556
-
557
- it("이미 월요일이면 같은 날짜를 반환한다", () => {
558
- // 2025-01-06 (월요일)
559
- const dateOnly = new DateOnly(2025, 1, 6);
560
- const result = dateOnly.getWeekSeqStartDate();
561
-
562
- expect(result.day).toBe(6);
563
- });
564
- });
565
-
566
- describe("미국식 (일요일 시작)", () => {
567
- it("주의 시작 날짜(일요일)를 반환한다", () => {
568
- // 2025-01-08 (수요일)
569
- const dateOnly = new DateOnly(2025, 1, 8);
570
- const result = dateOnly.getWeekSeqStartDate(0, 1);
571
-
572
- expect(result.year).toBe(2025);
573
- expect(result.month).toBe(1);
574
- expect(result.day).toBe(5); // 일요일
575
- expect(result.dayOfWeek).toBe(0);
576
- });
577
- });
578
- });
579
-
580
- describe("getDateByYearWeekSeq()", () => {
581
- describe("ISO 8601 표준", () => {
582
- it("연간 주차로부터 시작일을 반환한다", () => {
583
- // 2025년 2주차
584
- const result = DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 2 });
585
-
586
- expect(result.year).toBe(2025);
587
- expect(result.month).toBe(1);
588
- expect(result.day).toBe(6); // 2025-01-06 (월요일)
589
- });
590
-
591
- it("월간 주차로부터 시작일을 반환한다", () => {
592
- // 2025년 1월 3주차
593
- const result = DateOnly.getDateByYearWeekSeq({ year: 2025, month: 1, weekSeq: 3 });
594
-
595
- expect(result.year).toBe(2025);
596
- expect(result.month).toBe(1);
597
- expect(result.day).toBe(13); // 2025-01-13 (월요일)
598
- });
599
- });
600
-
601
- describe("미국식", () => {
602
- it("연간 주차로부터 시작일을 반환한다", () => {
603
- // 2025년 1주차 (미국식)
604
- const result = DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 1 }, 0, 1);
605
-
606
- expect(result.year).toBe(2024);
607
- expect(result.month).toBe(12);
608
- expect(result.day).toBe(29); // 2024-12-29 (일요일)
609
- });
610
- });
611
-
612
- describe("연도 경계 처리", () => {
613
- it("53주차가 있는 연도를 처리한다", () => {
614
- // 2020년은 53주까지 있음 (ISO 8601)
615
- const result = DateOnly.getDateByYearWeekSeq({ year: 2020, weekSeq: 53 });
616
-
617
- expect(result.year).toBe(2020);
618
- expect(result.month).toBe(12);
619
- expect(result.day).toBe(28); // 2020-12-28 (월요일)
620
- });
621
- });
622
-
623
- describe("윤년 처리", () => {
624
- it("윤년의 주차를 올바르게 계산한다", () => {
625
- // 2024년 (윤년) 10주차
626
- const result = DateOnly.getDateByYearWeekSeq({ year: 2024, weekSeq: 10 });
627
-
628
- expect(result.year).toBe(2024);
629
- expect(result.month).toBe(3);
630
- expect(result.day).toBe(4); // 2024-03-04 (월요일)
631
- });
632
- });
633
- });
634
-
635
- //#endregion
636
- });