@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.
- package/dist/common.types.d.ts +14 -14
- package/dist/common.types.js +2 -1
- package/dist/common.types.js.map +1 -6
- package/dist/env.d.ts +5 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +12 -8
- package/dist/env.js.map +1 -6
- package/dist/errors/argument-error.d.ts +10 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +31 -14
- package/dist/errors/argument-error.js.map +1 -6
- package/dist/errors/not-implemented-error.d.ts +8 -8
- package/dist/errors/not-implemented-error.js +30 -12
- package/dist/errors/not-implemented-error.js.map +1 -6
- package/dist/errors/sd-error.d.ts +10 -10
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/sd-error.js +45 -24
- package/dist/errors/sd-error.js.map +1 -6
- package/dist/errors/timeout-error.d.ts +10 -10
- package/dist/errors/timeout-error.js +34 -15
- package/dist/errors/timeout-error.js.map +1 -6
- package/dist/extensions/arr-ext.d.ts +2 -2
- package/dist/extensions/arr-ext.helpers.d.ts +10 -10
- package/dist/extensions/arr-ext.helpers.js +112 -89
- package/dist/extensions/arr-ext.helpers.js.map +1 -6
- package/dist/extensions/arr-ext.js +458 -422
- package/dist/extensions/arr-ext.js.map +1 -6
- package/dist/extensions/arr-ext.types.d.ts +57 -57
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/arr-ext.types.js +6 -1
- package/dist/extensions/arr-ext.types.js.map +1 -6
- package/dist/extensions/map-ext.d.ts +16 -16
- package/dist/extensions/map-ext.js +27 -22
- package/dist/extensions/map-ext.js.map +1 -6
- package/dist/extensions/set-ext.d.ts +11 -11
- package/dist/extensions/set-ext.js +32 -25
- package/dist/extensions/set-ext.js.map +1 -6
- package/dist/features/debounce-queue.d.ts +17 -17
- package/dist/features/debounce-queue.js +98 -70
- package/dist/features/debounce-queue.js.map +1 -6
- package/dist/features/event-emitter.d.ts +20 -20
- package/dist/features/event-emitter.js +101 -78
- package/dist/features/event-emitter.js.map +1 -6
- package/dist/features/serial-queue.d.ts +11 -11
- package/dist/features/serial-queue.js +78 -57
- package/dist/features/serial-queue.js.map +1 -6
- package/dist/globals.d.ts +4 -4
- package/dist/globals.js +9 -1
- package/dist/globals.js.map +1 -6
- package/dist/index.js +28 -27
- package/dist/index.js.map +1 -6
- package/dist/types/date-only.d.ts +64 -64
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +263 -252
- package/dist/types/date-only.js.map +1 -6
- package/dist/types/date-time.d.ts +36 -36
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +196 -288
- package/dist/types/date-time.js.map +1 -6
- package/dist/types/lazy-gc-map.d.ts +26 -26
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +202 -159
- package/dist/types/lazy-gc-map.js.map +1 -6
- package/dist/types/time.d.ts +23 -23
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +169 -158
- package/dist/types/time.js.map +1 -6
- package/dist/types/uuid.d.ts +11 -11
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +95 -70
- package/dist/types/uuid.js.map +1 -6
- package/dist/utils/bytes.d.ts +17 -17
- package/dist/utils/bytes.js +137 -81
- package/dist/utils/bytes.js.map +1 -6
- package/dist/utils/date-format.d.ts +40 -40
- package/dist/utils/date-format.js +187 -101
- package/dist/utils/date-format.js.map +1 -6
- package/dist/utils/error.d.ts +4 -4
- package/dist/utils/error.js +11 -6
- package/dist/utils/error.js.map +1 -6
- package/dist/utils/json.d.ts +19 -19
- package/dist/utils/json.js +187 -135
- package/dist/utils/json.js.map +1 -6
- package/dist/utils/num.d.ts +20 -20
- package/dist/utils/num.js +76 -34
- package/dist/utils/num.js.map +1 -6
- package/dist/utils/obj.d.ts +111 -111
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +706 -496
- package/dist/utils/obj.js.map +1 -6
- package/dist/utils/path.d.ts +10 -10
- package/dist/utils/path.js +35 -18
- package/dist/utils/path.js.map +1 -6
- package/dist/utils/primitive.d.ts +5 -5
- package/dist/utils/primitive.js +34 -14
- package/dist/utils/primitive.js.map +1 -6
- package/dist/utils/str.d.ts +38 -38
- package/dist/utils/str.js +217 -113
- package/dist/utils/str.js.map +1 -6
- package/dist/utils/template-strings.d.ts +26 -26
- package/dist/utils/template-strings.js +113 -40
- package/dist/utils/template-strings.js.map +1 -6
- package/dist/utils/transferable.d.ts +18 -18
- package/dist/utils/transferable.js +218 -151
- package/dist/utils/transferable.js.map +1 -6
- package/dist/utils/wait.d.ts +9 -9
- package/dist/utils/wait.js +30 -15
- package/dist/utils/wait.js.map +1 -6
- package/dist/utils/xml.d.ts +13 -13
- package/dist/utils/xml.js +84 -46
- package/dist/utils/xml.js.map +1 -6
- package/dist/utils/zip.d.ts +22 -22
- package/dist/utils/zip.js +172 -148
- package/dist/utils/zip.js.map +1 -6
- package/package.json +5 -7
- package/src/common.types.ts +14 -14
- package/src/env.ts +9 -1
- package/src/errors/argument-error.ts +15 -15
- package/src/errors/not-implemented-error.ts +9 -9
- package/src/errors/sd-error.ts +12 -12
- package/src/errors/timeout-error.ts +12 -12
- package/src/extensions/arr-ext.helpers.ts +16 -16
- package/src/extensions/arr-ext.ts +35 -35
- package/src/extensions/arr-ext.types.ts +57 -57
- package/src/extensions/map-ext.ts +16 -16
- package/src/extensions/set-ext.ts +11 -11
- package/src/features/debounce-queue.ts +23 -23
- package/src/features/event-emitter.ts +25 -25
- package/src/features/serial-queue.ts +13 -13
- package/src/globals.ts +4 -4
- package/src/index.ts +5 -5
- package/src/types/date-only.ts +84 -83
- package/src/types/date-time.ts +43 -42
- package/src/types/lazy-gc-map.ts +44 -44
- package/src/types/time.ts +29 -29
- package/src/types/uuid.ts +15 -15
- package/src/utils/bytes.ts +35 -35
- package/src/utils/date-format.ts +59 -59
- package/src/utils/error.ts +4 -4
- package/src/utils/json.ts +41 -41
- package/src/utils/num.ts +20 -20
- package/src/utils/obj.ts +138 -138
- package/src/utils/path.ts +10 -10
- package/src/utils/primitive.ts +6 -6
- package/src/utils/str.ts +48 -48
- package/src/utils/template-strings.ts +29 -29
- package/src/utils/transferable.ts +38 -38
- package/src/utils/wait.ts +10 -10
- package/src/utils/xml.ts +19 -19
- package/src/utils/zip.ts +25 -25
- package/README.md +0 -160
- package/docs/errors.md +0 -119
- package/docs/extensions.md +0 -387
- package/docs/features.md +0 -143
- package/docs/types.md +0 -287
- package/docs/utils.md +0 -757
- package/tests/errors/errors.spec.ts +0 -80
- package/tests/extensions/array-extension.spec.ts +0 -654
- package/tests/extensions/map-extension.spec.ts +0 -117
- package/tests/extensions/set-extension.spec.ts +0 -67
- package/tests/types/date-only.spec.ts +0 -533
- package/tests/types/date-time.spec.ts +0 -246
- package/tests/types/lazy-gc-map.spec.ts +0 -606
- package/tests/types/time.spec.ts +0 -428
- package/tests/types/uuid.spec.ts +0 -74
- package/tests/utils/bytes-utils.spec.ts +0 -197
- package/tests/utils/date-format.spec.ts +0 -350
- package/tests/utils/debounce-queue.spec.ts +0 -226
- package/tests/utils/json.spec.ts +0 -400
- package/tests/utils/number.spec.ts +0 -136
- package/tests/utils/object.spec.ts +0 -810
- package/tests/utils/path.spec.ts +0 -70
- package/tests/utils/primitive.spec.ts +0 -43
- package/tests/utils/sd-event-emitter.spec.ts +0 -189
- package/tests/utils/serial-queue.spec.ts +0 -305
- package/tests/utils/string.spec.ts +0 -265
- package/tests/utils/template-strings.spec.ts +0 -48
- package/tests/utils/transferable.spec.ts +0 -639
- package/tests/utils/wait.spec.ts +0 -123
- package/tests/utils/xml.spec.ts +0 -146
- package/tests/utils/zip.spec.ts +0 -221
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { dt } from "@simplysm/core-common";
|
|
3
|
-
import { normalizeMonth } from "../../src/utils/date-format";
|
|
4
|
-
|
|
5
|
-
describe("formatDateTime", () => {
|
|
6
|
-
//#region Year pattern
|
|
7
|
-
|
|
8
|
-
describe("Year pattern", () => {
|
|
9
|
-
it("outputs 4-digit year with yyyy format", () => {
|
|
10
|
-
expect(dt.format("yyyy", { year: 2025 })).toBe("2025");
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it("outputs 2-digit year with yy format", () => {
|
|
14
|
-
expect(dt.format("yy", { year: 2025 })).toBe("25");
|
|
15
|
-
expect(dt.format("yy", { year: 2000 })).toBe("00");
|
|
16
|
-
expect(dt.format("yy", { year: 1999 })).toBe("99");
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
|
|
22
|
-
//#region Month pattern
|
|
23
|
-
|
|
24
|
-
describe("Month pattern", () => {
|
|
25
|
-
it("outputs 2-digit month with MM format", () => {
|
|
26
|
-
expect(dt.format("MM", { month: 1 })).toBe("01");
|
|
27
|
-
expect(dt.format("MM", { month: 9 })).toBe("09");
|
|
28
|
-
expect(dt.format("MM", { month: 12 })).toBe("12");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("outputs month without padding with M format", () => {
|
|
32
|
-
expect(dt.format("M", { month: 1 })).toBe("1");
|
|
33
|
-
expect(dt.format("M", { month: 9 })).toBe("9");
|
|
34
|
-
expect(dt.format("M", { month: 12 })).toBe("12");
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
//#endregion
|
|
39
|
-
|
|
40
|
-
//#region Day pattern
|
|
41
|
-
|
|
42
|
-
describe("Day pattern", () => {
|
|
43
|
-
it("outputs 2-digit day with dd format", () => {
|
|
44
|
-
expect(dt.format("dd", { day: 1 })).toBe("01");
|
|
45
|
-
expect(dt.format("dd", { day: 9 })).toBe("09");
|
|
46
|
-
expect(dt.format("dd", { day: 31 })).toBe("31");
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("outputs day without padding with d format", () => {
|
|
50
|
-
expect(dt.format("d", { day: 1 })).toBe("1");
|
|
51
|
-
expect(dt.format("d", { day: 9 })).toBe("9");
|
|
52
|
-
expect(dt.format("d", { day: 31 })).toBe("31");
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
//#endregion
|
|
57
|
-
|
|
58
|
-
//#region Day of week pattern
|
|
59
|
-
|
|
60
|
-
describe("Day of week pattern", () => {
|
|
61
|
-
it("outputs day of week in Korean with ddd format", () => {
|
|
62
|
-
// 2025-01-18 is Saturday
|
|
63
|
-
expect(dt.format("ddd", { year: 2025, month: 1, day: 18 })).toBe("토");
|
|
64
|
-
// 2025-01-19 is Sunday
|
|
65
|
-
expect(dt.format("ddd", { year: 2025, month: 1, day: 19 })).toBe("일");
|
|
66
|
-
// 2025-01-20 is Monday
|
|
67
|
-
expect(dt.format("ddd", { year: 2025, month: 1, day: 20 })).toBe("월");
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
//#endregion
|
|
72
|
-
|
|
73
|
-
//#region Hour pattern
|
|
74
|
-
|
|
75
|
-
describe("Hour pattern", () => {
|
|
76
|
-
it("outputs 12-hour format with padding using hh format", () => {
|
|
77
|
-
expect(dt.format("hh", { hour: 0 })).toBe("12");
|
|
78
|
-
expect(dt.format("hh", { hour: 1 })).toBe("01");
|
|
79
|
-
expect(dt.format("hh", { hour: 12 })).toBe("12");
|
|
80
|
-
expect(dt.format("hh", { hour: 13 })).toBe("01");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("outputs 12-hour format without padding using h format", () => {
|
|
84
|
-
expect(dt.format("h", { hour: 0 })).toBe("12");
|
|
85
|
-
expect(dt.format("h", { hour: 1 })).toBe("1");
|
|
86
|
-
expect(dt.format("h", { hour: 9 })).toBe("9");
|
|
87
|
-
expect(dt.format("h", { hour: 10 })).toBe("10");
|
|
88
|
-
expect(dt.format("h", { hour: 12 })).toBe("12");
|
|
89
|
-
expect(dt.format("h", { hour: 13 })).toBe("1");
|
|
90
|
-
expect(dt.format("h", { hour: 23 })).toBe("11");
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("outputs 24-hour format with padding using HH format", () => {
|
|
94
|
-
expect(dt.format("HH", { hour: 0 })).toBe("00");
|
|
95
|
-
expect(dt.format("HH", { hour: 9 })).toBe("09");
|
|
96
|
-
expect(dt.format("HH", { hour: 23 })).toBe("23");
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("outputs 24-hour format without padding using H format", () => {
|
|
100
|
-
expect(dt.format("H", { hour: 0 })).toBe("0");
|
|
101
|
-
expect(dt.format("H", { hour: 9 })).toBe("9");
|
|
102
|
-
expect(dt.format("H", { hour: 23 })).toBe("23");
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("outputs AM/PM with tt format", () => {
|
|
106
|
-
expect(dt.format("tt", { hour: 0 })).toBe("AM");
|
|
107
|
-
expect(dt.format("tt", { hour: 11 })).toBe("AM");
|
|
108
|
-
expect(dt.format("tt", { hour: 12 })).toBe("PM");
|
|
109
|
-
expect(dt.format("tt", { hour: 23 })).toBe("PM");
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
//#endregion
|
|
114
|
-
|
|
115
|
-
//#region Minute pattern
|
|
116
|
-
|
|
117
|
-
describe("Minute pattern", () => {
|
|
118
|
-
it("outputs 2-digit minute with mm format", () => {
|
|
119
|
-
expect(dt.format("mm", { minute: 0 })).toBe("00");
|
|
120
|
-
expect(dt.format("mm", { minute: 5 })).toBe("05");
|
|
121
|
-
expect(dt.format("mm", { minute: 59 })).toBe("59");
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("outputs minute without padding with m format", () => {
|
|
125
|
-
expect(dt.format("m", { minute: 0 })).toBe("0");
|
|
126
|
-
expect(dt.format("m", { minute: 5 })).toBe("5");
|
|
127
|
-
expect(dt.format("m", { minute: 59 })).toBe("59");
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
//#endregion
|
|
132
|
-
|
|
133
|
-
//#region Second pattern
|
|
134
|
-
|
|
135
|
-
describe("Second pattern", () => {
|
|
136
|
-
it("outputs 2-digit second with ss format", () => {
|
|
137
|
-
expect(dt.format("ss", { second: 0 })).toBe("00");
|
|
138
|
-
expect(dt.format("ss", { second: 5 })).toBe("05");
|
|
139
|
-
expect(dt.format("ss", { second: 59 })).toBe("59");
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("outputs second without padding with s format", () => {
|
|
143
|
-
expect(dt.format("s", { second: 0 })).toBe("0");
|
|
144
|
-
expect(dt.format("s", { second: 5 })).toBe("5");
|
|
145
|
-
expect(dt.format("s", { second: 59 })).toBe("59");
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
//#endregion
|
|
150
|
-
|
|
151
|
-
//#region Millisecond pattern
|
|
152
|
-
|
|
153
|
-
describe("Millisecond pattern", () => {
|
|
154
|
-
it("outputs 3-digit millisecond with fff format", () => {
|
|
155
|
-
expect(dt.format("fff", { millisecond: 0 })).toBe("000");
|
|
156
|
-
expect(dt.format("fff", { millisecond: 5 })).toBe("005");
|
|
157
|
-
expect(dt.format("fff", { millisecond: 50 })).toBe("050");
|
|
158
|
-
expect(dt.format("fff", { millisecond: 500 })).toBe("500");
|
|
159
|
-
expect(dt.format("fff", { millisecond: 999 })).toBe("999");
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("outputs 2-digit millisecond with ff format", () => {
|
|
163
|
-
expect(dt.format("ff", { millisecond: 0 })).toBe("00");
|
|
164
|
-
expect(dt.format("ff", { millisecond: 5 })).toBe("00");
|
|
165
|
-
expect(dt.format("ff", { millisecond: 50 })).toBe("05");
|
|
166
|
-
expect(dt.format("ff", { millisecond: 500 })).toBe("50");
|
|
167
|
-
expect(dt.format("ff", { millisecond: 999 })).toBe("99");
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("outputs 1-digit millisecond with f format", () => {
|
|
171
|
-
expect(dt.format("f", { millisecond: 0 })).toBe("0");
|
|
172
|
-
expect(dt.format("f", { millisecond: 5 })).toBe("0");
|
|
173
|
-
expect(dt.format("f", { millisecond: 100 })).toBe("1");
|
|
174
|
-
expect(dt.format("f", { millisecond: 500 })).toBe("5");
|
|
175
|
-
expect(dt.format("f", { millisecond: 999 })).toBe("9");
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
//#endregion
|
|
180
|
-
|
|
181
|
-
//#region Timezone pattern
|
|
182
|
-
|
|
183
|
-
describe("Timezone pattern", () => {
|
|
184
|
-
describe("Positive offset (East)", () => {
|
|
185
|
-
it("outputs +HH:mm format with zzz format", () => {
|
|
186
|
-
// UTC+9 (540 minutes)
|
|
187
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: 540 })).toBe("+09:00");
|
|
188
|
-
// UTC+5:30 (330 minutes)
|
|
189
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: 330 })).toBe("+05:30");
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it("outputs +HH format with zz format", () => {
|
|
193
|
-
expect(dt.format("zz", { timezoneOffsetMinutes: 540 })).toBe("+09");
|
|
194
|
-
expect(dt.format("zz", { timezoneOffsetMinutes: 60 })).toBe("+01");
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it("outputs +H format without padding with z format", () => {
|
|
198
|
-
expect(dt.format("z", { timezoneOffsetMinutes: 540 })).toBe("+9");
|
|
199
|
-
expect(dt.format("z", { timezoneOffsetMinutes: 60 })).toBe("+1");
|
|
200
|
-
expect(dt.format("z", { timezoneOffsetMinutes: 600 })).toBe("+10");
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
describe("Negative offset (West)", () => {
|
|
205
|
-
it("outputs -HH:mm format with zzz format", () => {
|
|
206
|
-
// UTC-5 (-300 minutes) - Integer hour offset
|
|
207
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: -300 })).toBe("-05:00");
|
|
208
|
-
// UTC-8 (-480 minutes) - Integer hour offset
|
|
209
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: -480 })).toBe("-08:00");
|
|
210
|
-
// UTC-3:30 (-210 minutes) - Newfoundland Standard Time
|
|
211
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: -210 })).toBe("-03:30");
|
|
212
|
-
// UTC-9:30 (-570 minutes) - Marquesas Islands
|
|
213
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: -570 })).toBe("-09:30");
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it("outputs -HH format with zz format", () => {
|
|
217
|
-
expect(dt.format("zz", { timezoneOffsetMinutes: -300 })).toBe("-05");
|
|
218
|
-
expect(dt.format("zz", { timezoneOffsetMinutes: -60 })).toBe("-01");
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it("outputs -H format without padding with z format", () => {
|
|
222
|
-
expect(dt.format("z", { timezoneOffsetMinutes: -300 })).toBe("-5");
|
|
223
|
-
expect(dt.format("z", { timezoneOffsetMinutes: -60 })).toBe("-1");
|
|
224
|
-
expect(dt.format("z", { timezoneOffsetMinutes: -720 })).toBe("-12");
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
describe("UTC (0 offset)", () => {
|
|
229
|
-
it("outputs +00:00 with zzz format", () => {
|
|
230
|
-
expect(dt.format("zzz", { timezoneOffsetMinutes: 0 })).toBe("+00:00");
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
//#endregion
|
|
236
|
-
|
|
237
|
-
//#endregion
|
|
238
|
-
|
|
239
|
-
//#region Complex format
|
|
240
|
-
|
|
241
|
-
describe("Complex format", () => {
|
|
242
|
-
it("handles full date/time format", () => {
|
|
243
|
-
const result = dt.format("yyyy-MM-dd HH:mm:ss.fff", {
|
|
244
|
-
year: 2025,
|
|
245
|
-
month: 1,
|
|
246
|
-
day: 18,
|
|
247
|
-
hour: 14,
|
|
248
|
-
minute: 30,
|
|
249
|
-
second: 45,
|
|
250
|
-
millisecond: 123,
|
|
251
|
-
});
|
|
252
|
-
expect(result).toBe("2025-01-18 14:30:45.123");
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it("handles 12-hour format", () => {
|
|
256
|
-
const result = dt.format("yyyy-MM-dd tt h:mm:ss", {
|
|
257
|
-
year: 2025,
|
|
258
|
-
month: 1,
|
|
259
|
-
day: 18,
|
|
260
|
-
hour: 14,
|
|
261
|
-
minute: 5,
|
|
262
|
-
second: 9,
|
|
263
|
-
});
|
|
264
|
-
expect(result).toBe("2025-01-18 PM 2:05:09");
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
it("handles format with timezone", () => {
|
|
268
|
-
const result = dt.format("yyyy-MM-ddTHH:mm:sszzz", {
|
|
269
|
-
year: 2025,
|
|
270
|
-
month: 1,
|
|
271
|
-
day: 18,
|
|
272
|
-
hour: 14,
|
|
273
|
-
minute: 30,
|
|
274
|
-
second: 0,
|
|
275
|
-
timezoneOffsetMinutes: 540,
|
|
276
|
-
});
|
|
277
|
-
expect(result).toBe("2025-01-18T14:30:00+09:00");
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
//#endregion
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
describe("normalizeMonth", () => {
|
|
285
|
-
//#region Normal range
|
|
286
|
-
|
|
287
|
-
describe("Normal range (1-12)", () => {
|
|
288
|
-
it("returns unchanged if month is within 1-12 range", () => {
|
|
289
|
-
expect(normalizeMonth(2025, 1, 15)).toEqual({ year: 2025, month: 1, day: 15 });
|
|
290
|
-
expect(normalizeMonth(2025, 6, 15)).toEqual({ year: 2025, month: 6, day: 15 });
|
|
291
|
-
expect(normalizeMonth(2025, 12, 15)).toEqual({ year: 2025, month: 12, day: 15 });
|
|
292
|
-
});
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
//#endregion
|
|
296
|
-
|
|
297
|
-
//#region Month overflow
|
|
298
|
-
|
|
299
|
-
describe("Month overflow (13 or more)", () => {
|
|
300
|
-
it("month 13 becomes January next year", () => {
|
|
301
|
-
expect(normalizeMonth(2025, 13, 15)).toEqual({ year: 2026, month: 1, day: 15 });
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it("month 25 becomes January 2 years later", () => {
|
|
305
|
-
expect(normalizeMonth(2025, 25, 15)).toEqual({ year: 2027, month: 1, day: 15 });
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
//#endregion
|
|
310
|
-
|
|
311
|
-
//#region Month underflow
|
|
312
|
-
|
|
313
|
-
describe("Month underflow (0 or less)", () => {
|
|
314
|
-
it("month 0 becomes December previous year", () => {
|
|
315
|
-
expect(normalizeMonth(2025, 0, 15)).toEqual({ year: 2024, month: 12, day: 15 });
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
it("month -1 becomes November previous year", () => {
|
|
319
|
-
expect(normalizeMonth(2025, -1, 15)).toEqual({ year: 2024, month: 11, day: 15 });
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it("month -13 becomes November 2 years ago", () => {
|
|
323
|
-
expect(normalizeMonth(2025, -13, 15)).toEqual({ year: 2023, month: 11, day: 15 });
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
//#endregion
|
|
328
|
-
|
|
329
|
-
//#region Day adjustment
|
|
330
|
-
|
|
331
|
-
describe("Day adjustment (target month's last day)", () => {
|
|
332
|
-
it("day 31 adjusted to 28 when changing to February (non-leap year)", () => {
|
|
333
|
-
expect(normalizeMonth(2025, 2, 31)).toEqual({ year: 2025, month: 2, day: 28 });
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
it("day 31 adjusted to 29 when changing to February (leap year)", () => {
|
|
337
|
-
expect(normalizeMonth(2024, 2, 31)).toEqual({ year: 2024, month: 2, day: 29 });
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
it("day 31 adjusted to 30 when changing to April", () => {
|
|
341
|
-
expect(normalizeMonth(2025, 4, 31)).toEqual({ year: 2025, month: 4, day: 30 });
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
it("day unchanged if less than target month's day count", () => {
|
|
345
|
-
expect(normalizeMonth(2025, 3, 15)).toEqual({ year: 2025, month: 3, day: 15 });
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
//#endregion
|
|
350
|
-
});
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { DebounceQueue, wait, SdError } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
const time = wait.time;
|
|
5
|
-
|
|
6
|
-
describe("DebounceQueue", () => {
|
|
7
|
-
//#region Debounce behavior
|
|
8
|
-
|
|
9
|
-
describe("Debounce behavior", () => {
|
|
10
|
-
it("Executes only last request", async () => {
|
|
11
|
-
const queue = new DebounceQueue(50);
|
|
12
|
-
const calls: number[] = [];
|
|
13
|
-
|
|
14
|
-
queue.run(() => {
|
|
15
|
-
calls.push(1);
|
|
16
|
-
});
|
|
17
|
-
queue.run(() => {
|
|
18
|
-
calls.push(2);
|
|
19
|
-
});
|
|
20
|
-
queue.run(() => {
|
|
21
|
-
calls.push(3);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// Wait for debounce
|
|
25
|
-
await time(100);
|
|
26
|
-
|
|
27
|
-
// Only last request executed
|
|
28
|
-
expect(calls).toEqual([3]);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("Executes after delay", async () => {
|
|
32
|
-
const queue = new DebounceQueue(100);
|
|
33
|
-
const calls: number[] = [];
|
|
34
|
-
|
|
35
|
-
queue.run(() => {
|
|
36
|
-
calls.push(1);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// After 50ms not yet executed
|
|
40
|
-
await time(50);
|
|
41
|
-
expect(calls).toEqual([]);
|
|
42
|
-
|
|
43
|
-
// After 100ms executed
|
|
44
|
-
await time(100);
|
|
45
|
-
expect(calls).toEqual([1]);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("Executes immediately if no delay", async () => {
|
|
49
|
-
const queue = new DebounceQueue();
|
|
50
|
-
const calls: number[] = [];
|
|
51
|
-
|
|
52
|
-
queue.run(() => {
|
|
53
|
-
calls.push(1);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Small wait (event loop)
|
|
57
|
-
await time(10);
|
|
58
|
-
|
|
59
|
-
expect(calls).toEqual([1]);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("If new request arrives during execution, executes after completion", async () => {
|
|
63
|
-
const queue = new DebounceQueue(10);
|
|
64
|
-
const calls: number[] = [];
|
|
65
|
-
|
|
66
|
-
queue.run(async () => {
|
|
67
|
-
calls.push(1);
|
|
68
|
-
await time(50); // Wait during execution
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Wait for first execution start
|
|
72
|
-
await time(20);
|
|
73
|
-
|
|
74
|
-
// Add new request during execution
|
|
75
|
-
queue.run(() => {
|
|
76
|
-
calls.push(2);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Wait for all work to complete
|
|
80
|
-
await time(100);
|
|
81
|
-
|
|
82
|
-
expect(calls).toEqual([1, 2]);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
//#endregion
|
|
87
|
-
|
|
88
|
-
//#region Error handling
|
|
89
|
-
|
|
90
|
-
describe("Error handling", () => {
|
|
91
|
-
it("Emits error event on error", async () => {
|
|
92
|
-
const queue = new DebounceQueue(10);
|
|
93
|
-
const errors: SdError[] = [];
|
|
94
|
-
|
|
95
|
-
queue.on("error", (err) => {
|
|
96
|
-
errors.push(err);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
queue.run(() => {
|
|
100
|
-
throw new Error("test error");
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
await time(50);
|
|
104
|
-
|
|
105
|
-
expect(errors).toHaveLength(1);
|
|
106
|
-
expect(errors[0]).toBeInstanceOf(SdError);
|
|
107
|
-
expect(errors[0].message).toContain("Error occurred while executing task");
|
|
108
|
-
expect(errors[0].message).toContain("test error");
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("Next request executes normally even if error occurred", async () => {
|
|
112
|
-
const queue = new DebounceQueue(10);
|
|
113
|
-
const calls: number[] = [];
|
|
114
|
-
const errors: SdError[] = [];
|
|
115
|
-
|
|
116
|
-
// Add error listener to prevent unhandled rejection
|
|
117
|
-
queue.on("error", (err) => {
|
|
118
|
-
errors.push(err);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
queue.run(() => {
|
|
122
|
-
throw new Error("error");
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
await time(50);
|
|
126
|
-
|
|
127
|
-
queue.run(() => {
|
|
128
|
-
calls.push(1);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
await time(50);
|
|
132
|
-
|
|
133
|
-
expect(calls).toEqual([1]);
|
|
134
|
-
expect(errors).toHaveLength(1);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("pendingFn executes even if error occurred during execution", async () => {
|
|
138
|
-
const queue = new DebounceQueue(10);
|
|
139
|
-
const calls: number[] = [];
|
|
140
|
-
const errors: SdError[] = [];
|
|
141
|
-
|
|
142
|
-
queue.on("error", (err) => {
|
|
143
|
-
errors.push(err);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// First request: error occurs
|
|
147
|
-
queue.run(() => {
|
|
148
|
-
calls.push(1);
|
|
149
|
-
throw new Error("error 1");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
await time(20);
|
|
153
|
-
|
|
154
|
-
// Add new request during execution
|
|
155
|
-
queue.run(() => {
|
|
156
|
-
calls.push(2);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
await time(100);
|
|
160
|
-
|
|
161
|
-
expect(calls).toEqual([1, 2]);
|
|
162
|
-
expect(errors).toHaveLength(1);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
//#endregion
|
|
167
|
-
|
|
168
|
-
//#region dispose
|
|
169
|
-
|
|
170
|
-
describe("dispose()", () => {
|
|
171
|
-
it("Clears pending tasks and timers", async () => {
|
|
172
|
-
const queue = new DebounceQueue(100);
|
|
173
|
-
const calls: number[] = [];
|
|
174
|
-
|
|
175
|
-
queue.run(() => {
|
|
176
|
-
calls.push(1);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
// Dispose during debounce wait
|
|
180
|
-
await time(50);
|
|
181
|
-
queue.dispose();
|
|
182
|
-
|
|
183
|
-
// After debounce time passes, still not executed
|
|
184
|
-
await time(100);
|
|
185
|
-
|
|
186
|
-
expect(calls).toEqual([]);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it("New tasks ignored after dispose", async () => {
|
|
190
|
-
const queue = new DebounceQueue(50);
|
|
191
|
-
const calls: number[] = [];
|
|
192
|
-
|
|
193
|
-
queue.run(() => {
|
|
194
|
-
calls.push(1);
|
|
195
|
-
});
|
|
196
|
-
queue.dispose();
|
|
197
|
-
|
|
198
|
-
// Add new task after dispose - ignored
|
|
199
|
-
queue.run(() => {
|
|
200
|
-
calls.push(2);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
await time(100);
|
|
204
|
-
|
|
205
|
-
// Tasks after dispose not executed
|
|
206
|
-
expect(calls).toEqual([]);
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
it("Auto-disposed with using statement", async () => {
|
|
210
|
-
const calls: number[] = [];
|
|
211
|
-
{
|
|
212
|
-
using queue = new DebounceQueue(100);
|
|
213
|
-
queue.run(() => {
|
|
214
|
-
calls.push(1);
|
|
215
|
-
});
|
|
216
|
-
await time(50);
|
|
217
|
-
} // dispose automatically called at using block end
|
|
218
|
-
await time(100);
|
|
219
|
-
// Disposed during debounce wait, not executed
|
|
220
|
-
expect(calls).toEqual([]);
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
//#endregion
|
|
225
|
-
|
|
226
|
-
});
|