@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,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
- });