@simplysm/core-common 13.0.100 → 14.0.4

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 (184) hide show
  1. package/README.md +86 -92
  2. package/dist/common.types.d.ts +14 -14
  3. package/dist/common.types.js +2 -1
  4. package/dist/common.types.js.map +1 -6
  5. package/dist/env.d.ts +8 -1
  6. package/dist/env.d.ts.map +1 -1
  7. package/dist/env.js +13 -9
  8. package/dist/env.js.map +1 -6
  9. package/dist/errors/argument-error.d.ts +10 -10
  10. package/dist/errors/argument-error.d.ts.map +1 -1
  11. package/dist/errors/argument-error.js +31 -14
  12. package/dist/errors/argument-error.js.map +1 -6
  13. package/dist/errors/not-implemented-error.d.ts +8 -8
  14. package/dist/errors/not-implemented-error.js +30 -12
  15. package/dist/errors/not-implemented-error.js.map +1 -6
  16. package/dist/errors/sd-error.d.ts +10 -10
  17. package/dist/errors/sd-error.d.ts.map +1 -1
  18. package/dist/errors/sd-error.js +45 -24
  19. package/dist/errors/sd-error.js.map +1 -6
  20. package/dist/errors/timeout-error.d.ts +10 -10
  21. package/dist/errors/timeout-error.js +34 -15
  22. package/dist/errors/timeout-error.js.map +1 -6
  23. package/dist/extensions/arr-ext.d.ts +2 -2
  24. package/dist/extensions/arr-ext.helpers.d.ts +10 -10
  25. package/dist/extensions/arr-ext.helpers.js +112 -89
  26. package/dist/extensions/arr-ext.helpers.js.map +1 -6
  27. package/dist/extensions/arr-ext.js +458 -422
  28. package/dist/extensions/arr-ext.js.map +1 -6
  29. package/dist/extensions/arr-ext.types.d.ts +57 -57
  30. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  31. package/dist/extensions/arr-ext.types.js +6 -1
  32. package/dist/extensions/arr-ext.types.js.map +1 -6
  33. package/dist/extensions/map-ext.d.ts +16 -16
  34. package/dist/extensions/map-ext.js +27 -22
  35. package/dist/extensions/map-ext.js.map +1 -6
  36. package/dist/extensions/set-ext.d.ts +11 -11
  37. package/dist/extensions/set-ext.js +32 -25
  38. package/dist/extensions/set-ext.js.map +1 -6
  39. package/dist/features/debounce-queue.d.ts +17 -17
  40. package/dist/features/debounce-queue.js +98 -70
  41. package/dist/features/debounce-queue.js.map +1 -6
  42. package/dist/features/event-emitter.d.ts +20 -20
  43. package/dist/features/event-emitter.js +101 -78
  44. package/dist/features/event-emitter.js.map +1 -6
  45. package/dist/features/serial-queue.d.ts +11 -11
  46. package/dist/features/serial-queue.js +78 -57
  47. package/dist/features/serial-queue.js.map +1 -6
  48. package/dist/globals.d.ts +4 -4
  49. package/dist/globals.js +9 -1
  50. package/dist/globals.js.map +1 -6
  51. package/dist/index.js +28 -27
  52. package/dist/index.js.map +1 -6
  53. package/dist/types/date-only.d.ts +64 -64
  54. package/dist/types/date-only.d.ts.map +1 -1
  55. package/dist/types/date-only.js +263 -252
  56. package/dist/types/date-only.js.map +1 -6
  57. package/dist/types/date-time.d.ts +36 -36
  58. package/dist/types/date-time.d.ts.map +1 -1
  59. package/dist/types/date-time.js +196 -288
  60. package/dist/types/date-time.js.map +1 -6
  61. package/dist/types/lazy-gc-map.d.ts +26 -26
  62. package/dist/types/lazy-gc-map.d.ts.map +1 -1
  63. package/dist/types/lazy-gc-map.js +202 -159
  64. package/dist/types/lazy-gc-map.js.map +1 -6
  65. package/dist/types/time.d.ts +23 -23
  66. package/dist/types/time.d.ts.map +1 -1
  67. package/dist/types/time.js +169 -158
  68. package/dist/types/time.js.map +1 -6
  69. package/dist/types/uuid.d.ts +11 -11
  70. package/dist/types/uuid.d.ts.map +1 -1
  71. package/dist/types/uuid.js +95 -70
  72. package/dist/types/uuid.js.map +1 -6
  73. package/dist/utils/bytes.d.ts +17 -17
  74. package/dist/utils/bytes.js +137 -81
  75. package/dist/utils/bytes.js.map +1 -6
  76. package/dist/utils/date-format.d.ts +40 -40
  77. package/dist/utils/date-format.js +187 -101
  78. package/dist/utils/date-format.js.map +1 -6
  79. package/dist/utils/error.d.ts +4 -4
  80. package/dist/utils/error.js +11 -6
  81. package/dist/utils/error.js.map +1 -6
  82. package/dist/utils/json.d.ts +19 -19
  83. package/dist/utils/json.js +187 -135
  84. package/dist/utils/json.js.map +1 -6
  85. package/dist/utils/num.d.ts +20 -20
  86. package/dist/utils/num.js +76 -34
  87. package/dist/utils/num.js.map +1 -6
  88. package/dist/utils/obj.d.ts +111 -111
  89. package/dist/utils/obj.d.ts.map +1 -1
  90. package/dist/utils/obj.js +706 -496
  91. package/dist/utils/obj.js.map +1 -6
  92. package/dist/utils/path.d.ts +10 -10
  93. package/dist/utils/path.js +35 -18
  94. package/dist/utils/path.js.map +1 -6
  95. package/dist/utils/primitive.d.ts +5 -5
  96. package/dist/utils/primitive.js +34 -14
  97. package/dist/utils/primitive.js.map +1 -6
  98. package/dist/utils/str.d.ts +38 -38
  99. package/dist/utils/str.js +217 -113
  100. package/dist/utils/str.js.map +1 -6
  101. package/dist/utils/template-strings.d.ts +26 -26
  102. package/dist/utils/template-strings.js +113 -40
  103. package/dist/utils/template-strings.js.map +1 -6
  104. package/dist/utils/transferable.d.ts +18 -18
  105. package/dist/utils/transferable.js +218 -151
  106. package/dist/utils/transferable.js.map +1 -6
  107. package/dist/utils/wait.d.ts +9 -9
  108. package/dist/utils/wait.js +30 -15
  109. package/dist/utils/wait.js.map +1 -6
  110. package/dist/utils/xml.d.ts +13 -13
  111. package/dist/utils/xml.js +84 -46
  112. package/dist/utils/xml.js.map +1 -6
  113. package/dist/utils/zip.d.ts +22 -22
  114. package/dist/utils/zip.js +172 -148
  115. package/dist/utils/zip.js.map +1 -6
  116. package/docs/array-extensions.md +430 -0
  117. package/docs/env.md +52 -0
  118. package/docs/errors.md +41 -56
  119. package/docs/features.md +82 -97
  120. package/docs/type-utilities.md +91 -0
  121. package/docs/types.md +221 -201
  122. package/docs/utils.md +319 -435
  123. package/package.json +7 -5
  124. package/src/common.types.ts +14 -14
  125. package/src/env.ts +12 -3
  126. package/src/errors/argument-error.ts +15 -15
  127. package/src/errors/not-implemented-error.ts +9 -9
  128. package/src/errors/sd-error.ts +12 -12
  129. package/src/errors/timeout-error.ts +12 -12
  130. package/src/extensions/arr-ext.helpers.ts +16 -16
  131. package/src/extensions/arr-ext.ts +35 -35
  132. package/src/extensions/arr-ext.types.ts +57 -57
  133. package/src/extensions/map-ext.ts +16 -16
  134. package/src/extensions/set-ext.ts +11 -11
  135. package/src/features/debounce-queue.ts +23 -23
  136. package/src/features/event-emitter.ts +25 -25
  137. package/src/features/serial-queue.ts +13 -13
  138. package/src/globals.ts +4 -4
  139. package/src/index.ts +5 -5
  140. package/src/types/date-only.ts +84 -83
  141. package/src/types/date-time.ts +43 -42
  142. package/src/types/lazy-gc-map.ts +44 -44
  143. package/src/types/time.ts +29 -29
  144. package/src/types/uuid.ts +15 -15
  145. package/src/utils/bytes.ts +35 -35
  146. package/src/utils/date-format.ts +59 -59
  147. package/src/utils/error.ts +4 -4
  148. package/src/utils/json.ts +41 -41
  149. package/src/utils/num.ts +20 -20
  150. package/src/utils/obj.ts +138 -138
  151. package/src/utils/path.ts +10 -10
  152. package/src/utils/primitive.ts +6 -6
  153. package/src/utils/str.ts +48 -48
  154. package/src/utils/template-strings.ts +29 -29
  155. package/src/utils/transferable.ts +38 -38
  156. package/src/utils/wait.ts +10 -10
  157. package/src/utils/xml.ts +19 -19
  158. package/src/utils/zip.ts +25 -25
  159. package/docs/extensions.md +0 -387
  160. package/tests/errors/errors.spec.ts +0 -80
  161. package/tests/extensions/array-extension.spec.ts +0 -654
  162. package/tests/extensions/map-extension.spec.ts +0 -117
  163. package/tests/extensions/set-extension.spec.ts +0 -67
  164. package/tests/types/date-only.spec.ts +0 -533
  165. package/tests/types/date-time.spec.ts +0 -246
  166. package/tests/types/lazy-gc-map.spec.ts +0 -606
  167. package/tests/types/time.spec.ts +0 -428
  168. package/tests/types/uuid.spec.ts +0 -74
  169. package/tests/utils/bytes-utils.spec.ts +0 -197
  170. package/tests/utils/date-format.spec.ts +0 -350
  171. package/tests/utils/debounce-queue.spec.ts +0 -226
  172. package/tests/utils/json.spec.ts +0 -400
  173. package/tests/utils/number.spec.ts +0 -136
  174. package/tests/utils/object.spec.ts +0 -810
  175. package/tests/utils/path.spec.ts +0 -70
  176. package/tests/utils/primitive.spec.ts +0 -43
  177. package/tests/utils/sd-event-emitter.spec.ts +0 -189
  178. package/tests/utils/serial-queue.spec.ts +0 -305
  179. package/tests/utils/string.spec.ts +0 -265
  180. package/tests/utils/template-strings.spec.ts +0 -48
  181. package/tests/utils/transferable.spec.ts +0 -639
  182. package/tests/utils/wait.spec.ts +0 -123
  183. package/tests/utils/xml.spec.ts +0 -146
  184. package/tests/utils/zip.spec.ts +0 -221
@@ -1,400 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { json, DateTime, DateOnly, Time, Uuid } from "@simplysm/core-common";
3
-
4
- describe("JsonConvert", () => {
5
- //#region stringify
6
-
7
- describe("stringify()", () => {
8
- it("Serializes Date with __type__", () => {
9
- const date = new Date("2024-03-15T10:30:00.000Z");
10
- const str = json.stringify(date);
11
- const parsed = JSON.parse(str);
12
-
13
- expect(parsed.__type__).toBe("Date");
14
- expect(parsed.data).toBe("2024-03-15T10:30:00.000Z");
15
- });
16
-
17
- it("Serializes DateTime with __type__", () => {
18
- const dt = new DateTime(2024, 3, 15, 10, 30);
19
- const str = json.stringify(dt);
20
- const parsed = JSON.parse(str);
21
-
22
- expect(parsed.__type__).toBe("DateTime");
23
- expect(typeof parsed.data).toBe("string");
24
- });
25
-
26
- it("Serializes DateOnly with __type__", () => {
27
- const d = new DateOnly(2024, 3, 15);
28
- const str = json.stringify(d);
29
- const parsed = JSON.parse(str);
30
-
31
- expect(parsed.__type__).toBe("DateOnly");
32
- });
33
-
34
- it("Serializes Time with __type__", () => {
35
- const t = new Time(10, 30, 45);
36
- const str = json.stringify(t);
37
- const parsed = JSON.parse(str);
38
-
39
- expect(parsed.__type__).toBe("Time");
40
- });
41
-
42
- it("Serializes Uuid with __type__", () => {
43
- const uuid = new Uuid("12345678-9abc-def0-1234-56789abcdef0");
44
- const str = json.stringify(uuid);
45
- const parsed = JSON.parse(str);
46
-
47
- expect(parsed.__type__).toBe("Uuid");
48
- expect(parsed.data).toBe("12345678-9abc-def0-1234-56789abcdef0");
49
- });
50
-
51
- it("Serializes Set with __type__", () => {
52
- const set = new Set([1, 2, 3]);
53
- const str = json.stringify(set);
54
- const parsed = JSON.parse(str);
55
-
56
- expect(parsed.__type__).toBe("Set");
57
- expect(parsed.data).toEqual([1, 2, 3]);
58
- });
59
-
60
- it("Serializes Map with __type__", () => {
61
- const map = new Map([
62
- ["a", 1],
63
- ["b", 2],
64
- ]);
65
- const str = json.stringify(map);
66
- const parsed = JSON.parse(str);
67
-
68
- expect(parsed.__type__).toBe("Map");
69
- expect(parsed.data).toEqual([
70
- ["a", 1],
71
- ["b", 2],
72
- ]);
73
- });
74
-
75
- it("Serializes Error with __type__", () => {
76
- const error = new Error("test error");
77
- const str = json.stringify(error);
78
- const parsed = JSON.parse(str);
79
-
80
- expect(parsed.__type__).toBe("Error");
81
- expect(parsed.data.message).toBe("test error");
82
- expect(parsed.data.name).toBe("Error");
83
- });
84
-
85
- it("Serializes Error extended properties (code, detail, cause)", () => {
86
- const cause = new Error("cause error");
87
- const error = new Error("test error") as Error & { code: string; detail: object };
88
- error.code = "ERR_CODE";
89
- error.detail = { key: "value" };
90
- (error as Error & { cause: Error }).cause = cause;
91
-
92
- const str = json.stringify(error);
93
- const parsed = JSON.parse(str);
94
-
95
- expect(parsed.__type__).toBe("Error");
96
- expect(parsed.data.message).toBe("test error");
97
- expect(parsed.data.code).toBe("ERR_CODE");
98
- expect(parsed.data.detail).toEqual({ key: "value" });
99
- expect(parsed.data.cause.__type__).toBe("Error");
100
- expect(parsed.data.cause.data.message).toBe("cause error");
101
- });
102
-
103
- it("Hides Uint8Array with redactBytes option", () => {
104
- const obj = { data: new TextEncoder().encode("hello") };
105
- const str = json.stringify(obj, { redactBytes: true });
106
- const parsed = JSON.parse(str);
107
-
108
- expect(parsed.data.data).toBe("__hidden__");
109
- });
110
-
111
- it("Transforms values with replacer option", () => {
112
- const obj = { a: 1, b: 2, c: 3 };
113
- const str = json.stringify(obj, {
114
- replacer: (key, value) => {
115
- if (key === "b") return undefined;
116
- return value;
117
- },
118
- });
119
- const parsed = JSON.parse(str);
120
-
121
- expect(parsed.a).toBe(1);
122
- expect(parsed.b).toBeUndefined();
123
- expect(parsed.c).toBe(3);
124
- });
125
-
126
- it("No race condition on concurrent calls", async () => {
127
- // Serialize complex objects with Date simultaneously
128
- const createTestObject = (id: number) => ({
129
- id,
130
- date: new Date(`2024-0${(id % 9) + 1}-15T10:30:00.000Z`),
131
- nested: {
132
- innerDate: new Date(`2024-0${(id % 9) + 1}-20T15:45:00.000Z`),
133
- },
134
- array: [new Date(`2024-0${(id % 9) + 1}-25T08:00:00.000Z`)],
135
- });
136
-
137
- // 100 concurrent calls
138
- const promises = Array.from({ length: 100 }, (_, i) =>
139
- Promise.resolve().then(() => {
140
- const obj = createTestObject(i);
141
- const str = json.stringify(obj);
142
- const parsed = json.parse<typeof obj>(str);
143
-
144
- // Verify all Dates restored correctly
145
- expect(parsed.date).toBeInstanceOf(Date);
146
- expect(parsed.nested.innerDate).toBeInstanceOf(Date);
147
- expect(parsed.array[0]).toBeInstanceOf(Date);
148
-
149
- return { id: i, success: true };
150
- }),
151
- );
152
-
153
- const results = await Promise.all(promises);
154
-
155
- // Verify all calls succeeded
156
- expect(results.every((r) => r.success)).toBe(true);
157
- });
158
-
159
- it("Correctly serializes nested Date objects", () => {
160
- const obj = {
161
- level1: {
162
- level2: {
163
- level3: {
164
- date: new Date("2024-06-15T12:00:00.000Z"),
165
- },
166
- },
167
- },
168
- dates: [new Date("2024-01-01T00:00:00.000Z"), new Date("2024-12-31T23:59:59.000Z")],
169
- };
170
-
171
- const str = json.stringify(obj);
172
- const parsed = json.parse<typeof obj>(str);
173
-
174
- expect(parsed.level1.level2.level3.date).toBeInstanceOf(Date);
175
- expect(parsed.level1.level2.level3.date.toISOString()).toBe("2024-06-15T12:00:00.000Z");
176
- expect(parsed.dates[0]).toBeInstanceOf(Date);
177
- expect(parsed.dates[1]).toBeInstanceOf(Date);
178
- });
179
-
180
- it("Does not modify Date.prototype.toJSON", () => {
181
- const originalToJSON = Date.prototype.toJSON;
182
-
183
- // Call stringify
184
- const date = new Date("2024-03-15T10:30:00.000Z");
185
- json.stringify({ date });
186
-
187
- // Verify toJSON not changed
188
- expect(Date.prototype.toJSON).toBe(originalToJSON);
189
- });
190
-
191
- it("Circular reference object throws TypeError", () => {
192
- const obj: Record<string, unknown> = { name: "test" };
193
- obj["self"] = obj; // circular reference
194
-
195
- expect(() => json.stringify(obj)).toThrow(TypeError);
196
- expect(() => json.stringify(obj)).toThrow("Converting circular structure to JSON");
197
- });
198
-
199
- it("Detects circular reference in array", () => {
200
- const arr: unknown[] = [1, 2];
201
- arr.push(arr); // array circular reference
202
-
203
- expect(() => json.stringify(arr)).toThrow("Converting circular structure to JSON");
204
- });
205
-
206
- it("Serializes custom object with toJSON method", () => {
207
- const obj = {
208
- amount: 100,
209
- toJSON() {
210
- return `$${this.amount}`;
211
- },
212
- };
213
-
214
- const str = json.stringify(obj);
215
- expect(str).toBe('"$100"');
216
- });
217
-
218
- it("Recursively processes toJSON if returning object", () => {
219
- const obj = {
220
- data: "test",
221
- toJSON() {
222
- return { converted: true, date: new Date("2024-01-01T00:00:00.000Z") };
223
- },
224
- };
225
-
226
- const str = json.stringify(obj);
227
- const parsed = JSON.parse(str);
228
-
229
- expect(parsed.converted).toBe(true);
230
- expect(parsed.date.__type__).toBe("Date");
231
- });
232
- });
233
-
234
- //#endregion
235
-
236
- //#region parse
237
-
238
- describe("parse()", () => {
239
- it("Converts null to undefined", () => {
240
- expect(json.parse("null")).toBe(undefined);
241
- });
242
-
243
- it("Restores Date", () => {
244
- const str = '{"__type__":"Date","data":"2024-03-15T10:30:00.000Z"}';
245
- const result = json.parse(str);
246
-
247
- expect(result).toBeInstanceOf(Date);
248
- expect((result as Date).toISOString()).toBe("2024-03-15T10:30:00.000Z");
249
- });
250
-
251
- it("Restores DateTime", () => {
252
- const dt = new DateTime(2024, 3, 15, 10, 30);
253
- const str = json.stringify(dt);
254
- const result = json.parse(str);
255
-
256
- expect(result).toBeInstanceOf(DateTime);
257
- expect((result as DateTime).year).toBe(2024);
258
- expect((result as DateTime).month).toBe(3);
259
- expect((result as DateTime).day).toBe(15);
260
- });
261
-
262
- it("Restores DateOnly", () => {
263
- const d = new DateOnly(2024, 3, 15);
264
- const str = json.stringify(d);
265
- const result = json.parse(str);
266
-
267
- expect(result).toBeInstanceOf(DateOnly);
268
- expect((result as DateOnly).year).toBe(2024);
269
- });
270
-
271
- it("Restores Time", () => {
272
- const t = new Time(10, 30, 45);
273
- const str = json.stringify(t);
274
- const result = json.parse(str);
275
-
276
- expect(result).toBeInstanceOf(Time);
277
- expect((result as Time).hour).toBe(10);
278
- });
279
-
280
- it("Restores Uuid", () => {
281
- const str = '{"__type__":"Uuid","data":"12345678-9abc-def0-1234-56789abcdef0"}';
282
- const result = json.parse(str);
283
-
284
- expect(result).toBeInstanceOf(Uuid);
285
- expect((result as Uuid).toString()).toBe("12345678-9abc-def0-1234-56789abcdef0");
286
- });
287
-
288
- it("Restores Set", () => {
289
- const str = '{"__type__":"Set","data":[1,2,3]}';
290
- const result = json.parse(str);
291
-
292
- expect(result).toBeInstanceOf(Set);
293
- expect(Array.from(result as Set<number>)).toEqual([1, 2, 3]);
294
- });
295
-
296
- it("Restores Map", () => {
297
- const str = '{"__type__":"Map","data":[["a",1],["b",2]]}';
298
- const result = json.parse(str);
299
-
300
- expect(result).toBeInstanceOf(Map);
301
- expect((result as Map<string, number>).get("a")).toBe(1);
302
- });
303
-
304
- it("Restores Error (with extended properties)", () => {
305
- const cause = new Error("cause error");
306
- const error = new Error("test error") as Error & {
307
- code: string;
308
- detail: object;
309
- cause: Error;
310
- };
311
- error.code = "ERR_CODE";
312
- error.detail = { key: "value" };
313
- error.cause = cause;
314
-
315
- const str = json.stringify(error);
316
- const result = json.parse<typeof error>(str);
317
-
318
- expect(result).toBeInstanceOf(Error);
319
- expect(result.message).toBe("test error");
320
- expect(result.code).toBe("ERR_CODE");
321
- expect(result.detail).toEqual({ key: "value" });
322
- expect(result.cause).toBeInstanceOf(Error);
323
- expect(result.cause.message).toBe("cause error");
324
- });
325
-
326
- it("Restores Uint8Array", () => {
327
- const str = '{"__type__":"Uint8Array","data":"68656c6c6f"}';
328
- const result = json.parse(str);
329
-
330
- expect(result).toBeInstanceOf(Uint8Array);
331
- expect(new TextDecoder().decode(result as Uint8Array)).toBe("hello");
332
- });
333
-
334
- it("stringify/parse round-trip", () => {
335
- const original = {
336
- date: new Date("2024-03-15T10:30:00.000Z"),
337
- dateTime: new DateTime(2024, 3, 15),
338
- dateOnly: new DateOnly(2024, 3, 15),
339
- time: new Time(10, 30),
340
- uuid: new Uuid("12345678-9abc-def0-1234-56789abcdef0"),
341
- set: new Set([1, 2, 3]),
342
- map: new Map([["a", 1]]),
343
- bytes: new TextEncoder().encode("hello"),
344
- };
345
-
346
- const str = json.stringify(original);
347
- const result = json.parse<typeof original>(str);
348
-
349
- expect(result.date).toBeInstanceOf(Date);
350
- expect(result.dateTime).toBeInstanceOf(DateTime);
351
- expect(result.dateOnly).toBeInstanceOf(DateOnly);
352
- expect(result.time).toBeInstanceOf(Time);
353
- expect(result.uuid).toBeInstanceOf(Uuid);
354
- expect(result.set).toBeInstanceOf(Set);
355
- expect(result.map).toBeInstanceOf(Map);
356
- expect(result.bytes).toBeInstanceOf(Uint8Array);
357
- });
358
-
359
- it("Data serialized with redactBytes throws error on parse", () => {
360
- const obj = { data: new TextEncoder().encode("hello") };
361
- const str = json.stringify(obj, { redactBytes: true });
362
-
363
- // "__hidden__" is data serialized with redactBytes option, so parse throws error
364
- expect(() => json.parse<typeof obj>(str)).toThrow(
365
- "Uint8Array serialized with redactBytes option cannot be restored via parse",
366
- );
367
- });
368
-
369
- it("Invalid JSON throws error", () => {
370
- expect(() => json.parse("invalid json")).toThrow("JSON parsing error");
371
- });
372
-
373
- it("In DEV mode, full JSON included in error message", () => {
374
- const longJson = "x".repeat(2000);
375
-
376
- try {
377
- json.parse(longJson);
378
- expect.fail("Error should be thrown");
379
- } catch (err) {
380
- const message = (err as Error).message;
381
- // In DEV mode, full JSON included
382
- expect(message).toContain(longJson);
383
- }
384
- });
385
-
386
- it("Error message includes JSON content", () => {
387
- const shortJson = "invalid";
388
-
389
- try {
390
- json.parse(shortJson);
391
- expect.fail("Error should be thrown");
392
- } catch (err) {
393
- const message = (err as Error).message;
394
- expect(message).toContain("invalid");
395
- }
396
- });
397
- });
398
-
399
- //#endregion
400
- });
@@ -1,136 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { num } from "@simplysm/core-common";
3
-
4
- describe("number utils", () => {
5
- //#region parseInt
6
-
7
- describe("parseInt()", () => {
8
- it("Parses negative string", () => {
9
- expect(num.parseInt("-123")).toBe(-123);
10
- });
11
-
12
- it("Floating string returns only integer part", () => {
13
- expect(num.parseInt("123.45")).toBe(123);
14
- });
15
-
16
- it("Number type discards decimal places", () => {
17
- expect(num.parseInt(123.7)).toBe(123);
18
- expect(num.parseInt(123.3)).toBe(123);
19
- });
20
-
21
- it("Removes non-numeric characters then parses", () => {
22
- expect(num.parseInt("$1,234")).toBe(1234);
23
- expect(num.parseInt("abc123")).toBe(123);
24
- });
25
-
26
- it("Handles minus sign between characters", () => {
27
- expect(num.parseInt("abc-123def")).toBe(-123);
28
- expect(num.parseInt("abc-456def")).toBe(-456);
29
- });
30
-
31
- it("Empty string returns undefined", () => {
32
- expect(num.parseInt("")).toBe(undefined);
33
- });
34
-
35
- it("String with no digits returns undefined", () => {
36
- expect(num.parseInt("abc")).toBe(undefined);
37
- });
38
-
39
- it("Non-string type returns undefined", () => {
40
- expect(num.parseInt(null)).toBe(undefined);
41
- expect(num.parseInt(undefined)).toBe(undefined);
42
- expect(num.parseInt({})).toBe(undefined);
43
- });
44
- });
45
-
46
- //#endregion
47
-
48
- //#region parseRoundedInt
49
-
50
- describe("parseRoundedInt()", () => {
51
- it("Rounds floating string to integer", () => {
52
- expect(num.parseRoundedInt("123.5")).toBe(124);
53
- expect(num.parseRoundedInt("123.4")).toBe(123);
54
- });
55
-
56
- it("Rounds number type", () => {
57
- expect(num.parseRoundedInt(123.7)).toBe(124);
58
- });
59
-
60
- it("Returns undefined if not parseable", () => {
61
- expect(num.parseRoundedInt("abc")).toBe(undefined);
62
- });
63
- });
64
-
65
- //#endregion
66
-
67
- //#region parseFloat
68
-
69
- describe("parseFloat()", () => {
70
- it("Parses negative floating string", () => {
71
- expect(num.parseFloat("-123.45")).toBe(-123.45);
72
- });
73
-
74
- it("Number type returned as-is", () => {
75
- expect(num.parseFloat(123.45)).toBe(123.45);
76
- });
77
-
78
- it("Removes non-numeric characters then parses", () => {
79
- expect(num.parseFloat("$1,234.56")).toBe(1234.56);
80
- });
81
-
82
- it("Empty string returns undefined", () => {
83
- expect(num.parseFloat("")).toBe(undefined);
84
- });
85
-
86
- it("String with no digits returns undefined", () => {
87
- expect(num.parseFloat("abc")).toBe(undefined);
88
- });
89
-
90
- it("Non-string type returns undefined", () => {
91
- expect(num.parseFloat(null)).toBe(undefined);
92
- expect(num.parseFloat(undefined)).toBe(undefined);
93
- });
94
- });
95
-
96
- //#endregion
97
-
98
- //#region format
99
-
100
- describe("format()", () => {
101
- it("Applies thousands separator", () => {
102
- expect(num.format(1234567)).toBe("1,234,567");
103
- });
104
-
105
- it("Applies thousands separator to float", () => {
106
- const result = num.format(1234567.89);
107
- expect(result).toContain("1,234,567");
108
- });
109
-
110
- it("Specifies maximum decimal places", () => {
111
- expect(num.format(123.456, { max: 2 })).toBe("123.46");
112
- });
113
-
114
- it("Specifies minimum decimal places", () => {
115
- expect(num.format(123, { min: 2 })).toBe("123.00");
116
- });
117
-
118
- it("Specifies both max and min decimal places", () => {
119
- expect(num.format(123.4, { max: 3, min: 2 })).toBe("123.40");
120
- });
121
-
122
- it("Undefined returns undefined", () => {
123
- expect(num.format(undefined)).toBe(undefined);
124
- });
125
-
126
- it("Formats zero", () => {
127
- expect(num.format(0)).toBe("0");
128
- });
129
-
130
- it("Formats negative number", () => {
131
- expect(num.format(-1234567)).toBe("-1,234,567");
132
- });
133
- });
134
-
135
- //#endregion
136
- });