@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,692 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
- import { LazyGcMap } from "@simplysm/core-common";
3
-
4
- describe("LazyGcMap", () => {
5
- beforeEach(() => {
6
- vi.useFakeTimers();
7
- });
8
-
9
- afterEach(() => {
10
- vi.useRealTimers();
11
- });
12
-
13
- //#region 기본 Map 동작
14
-
15
- describe("기본 Map 동작", () => {
16
- it("set/get으로 값을 저장하고 가져온다", () => {
17
- const map = new LazyGcMap<string, number>({
18
- gcInterval: 1000,
19
- expireTime: 5000,
20
- });
21
-
22
- map.set("key1", 100);
23
- expect(map.get("key1")).toBe(100);
24
- });
25
-
26
- it("has로 키 존재 여부를 확인한다", () => {
27
- const map = new LazyGcMap<string, number>({
28
- gcInterval: 1000,
29
- expireTime: 5000,
30
- });
31
-
32
- map.set("key1", 100);
33
- expect(map.has("key1")).toBe(true);
34
- expect(map.has("key2")).toBe(false);
35
- });
36
-
37
- it("delete로 값을 삭제한다", () => {
38
- const map = new LazyGcMap<string, number>({
39
- gcInterval: 1000,
40
- expireTime: 5000,
41
- });
42
-
43
- map.set("key1", 100);
44
- expect(map.delete("key1")).toBe(true);
45
- expect(map.has("key1")).toBe(false);
46
- expect(map.delete("key1")).toBe(false); // 이미 삭제됨
47
- });
48
-
49
- it("dispose로 모든 값을 삭제한다", () => {
50
- const map = new LazyGcMap<string, number>({
51
- gcInterval: 1000,
52
- expireTime: 5000,
53
- });
54
-
55
- map.set("key1", 100);
56
- map.set("key2", 200);
57
- expect(map.size).toBe(2);
58
-
59
- map.dispose();
60
- expect(map.size).toBe(0);
61
- expect(map.has("key1")).toBe(false);
62
- expect(map.has("key2")).toBe(false);
63
- });
64
-
65
- it("size로 크기를 확인한다", () => {
66
- const map = new LazyGcMap<string, number>({
67
- gcInterval: 1000,
68
- expireTime: 5000,
69
- });
70
-
71
- expect(map.size).toBe(0);
72
- map.set("key1", 100);
73
- expect(map.size).toBe(1);
74
- map.set("key2", 200);
75
- expect(map.size).toBe(2);
76
- map.delete("key1");
77
- expect(map.size).toBe(1);
78
- });
79
-
80
- it("없는 키를 get하면 undefined를 반환한다", () => {
81
- const map = new LazyGcMap<string, number>({
82
- gcInterval: 1000,
83
- expireTime: 5000,
84
- });
85
-
86
- expect(map.get("nonexistent")).toBe(undefined);
87
- });
88
- });
89
-
90
- //#endregion
91
-
92
- //#region getOrCreate
93
-
94
- describe("getOrCreate()", () => {
95
- it("없는 키는 factory로 생성한다", () => {
96
- const map = new LazyGcMap<string, number>({
97
- gcInterval: 1000,
98
- expireTime: 5000,
99
- });
100
-
101
- const value = map.getOrCreate("key1", () => 100);
102
- expect(value).toBe(100);
103
- expect(map.get("key1")).toBe(100);
104
- });
105
-
106
- it("있는 키는 기존 값을 반환한다", () => {
107
- const map = new LazyGcMap<string, number>({
108
- gcInterval: 1000,
109
- expireTime: 5000,
110
- });
111
-
112
- map.set("key1", 100);
113
- const factoryCalls: number[] = [];
114
- const value = map.getOrCreate("key1", () => {
115
- factoryCalls.push(1);
116
- return 200;
117
- });
118
-
119
- expect(value).toBe(100); // 기존 값
120
- expect(factoryCalls).toHaveLength(0); // factory 호출 안 됨
121
- });
122
-
123
- it("factory는 호출될 때마다 새 값을 생성한다", () => {
124
- const map = new LazyGcMap<string, { id: number }>({
125
- gcInterval: 1000,
126
- expireTime: 5000,
127
- });
128
-
129
- const value1 = map.getOrCreate("key1", () => ({ id: 1 }));
130
- const value2 = map.getOrCreate("key2", () => ({ id: 2 }));
131
-
132
- expect(value1).toEqual({ id: 1 });
133
- expect(value2).toEqual({ id: 2 });
134
- expect(value1).not.toBe(value2);
135
- });
136
- });
137
-
138
- //#endregion
139
-
140
- //#region 자동 만료 (GC)
141
-
142
- describe("자동 만료 (GC)", () => {
143
- it("expireTime 이후 미접근 시 자동 삭제된다", async () => {
144
- const map = new LazyGcMap<string, number>({
145
- gcInterval: 100, // 100ms마다 GC
146
- expireTime: 200, // 200ms 후 만료
147
- });
148
-
149
- map.set("key1", 100);
150
- expect(map.has("key1")).toBe(true);
151
-
152
- // expireTime(200) + gcInterval(100) = 300ms 후 GC 실행됨
153
- await vi.advanceTimersByTimeAsync(350);
154
-
155
- expect(map.has("key1")).toBe(false);
156
- });
157
-
158
- it("접근하면 만료 시간이 갱신된다 (LRU)", async () => {
159
- const map = new LazyGcMap<string, number>({
160
- gcInterval: 100,
161
- expireTime: 200,
162
- });
163
-
164
- map.set("key1", 100);
165
-
166
- // 150ms마다 접근 (expireTime 200ms보다 짧음)
167
- await vi.advanceTimersByTimeAsync(150);
168
- map.get("key1"); // 접근 → 시간 갱신
169
-
170
- await vi.advanceTimersByTimeAsync(150);
171
- map.get("key1"); // 접근 → 시간 갱신
172
-
173
- await vi.advanceTimersByTimeAsync(150);
174
-
175
- // 계속 접근했으므로 만료 안 됨
176
- expect(map.has("key1")).toBe(true);
177
- });
178
-
179
- it("has()는 접근 시간을 갱신하지 않는다", async () => {
180
- const map = new LazyGcMap<string, number>({
181
- gcInterval: 100,
182
- expireTime: 200,
183
- });
184
-
185
- map.set("key1", 100);
186
-
187
- // 150ms마다 has()만 호출 (get()이 아님)
188
- await vi.advanceTimersByTimeAsync(150);
189
- map.has("key1"); // has()는 접근 시간을 갱신하지 않음
190
-
191
- await vi.advanceTimersByTimeAsync(150);
192
- map.has("key1"); // has()는 접근 시간을 갱신하지 않음
193
-
194
- await vi.advanceTimersByTimeAsync(100);
195
-
196
- // has()는 접근 시간을 갱신하지 않으므로 만료됨
197
- expect(map.has("key1")).toBe(false);
198
- });
199
-
200
- it("getOrCreate도 접근 시간을 갱신한다", async () => {
201
- const map = new LazyGcMap<string, number>({
202
- gcInterval: 100,
203
- expireTime: 200,
204
- });
205
-
206
- map.set("key1", 100);
207
-
208
- await vi.advanceTimersByTimeAsync(150);
209
- map.getOrCreate("key1", () => 200); // 접근 → 시간 갱신
210
-
211
- await vi.advanceTimersByTimeAsync(150);
212
-
213
- expect(map.has("key1")).toBe(true);
214
- });
215
-
216
- it("여러 항목 중 만료된 것만 삭제한다", async () => {
217
- const map = new LazyGcMap<string, number>({
218
- gcInterval: 100,
219
- expireTime: 200,
220
- });
221
-
222
- map.set("key1", 100);
223
- await vi.advanceTimersByTimeAsync(150);
224
- map.set("key2", 200); // key1보다 150ms 늦게 추가
225
-
226
- await vi.advanceTimersByTimeAsync(200);
227
-
228
- // key1은 만료, key2는 아직 살아있음
229
- expect(map.has("key1")).toBe(false);
230
- expect(map.has("key2")).toBe(true);
231
- });
232
-
233
- it("모든 항목이 만료되면 GC 타이머가 중지된다", async () => {
234
- const map = new LazyGcMap<string, number>({
235
- gcInterval: 100,
236
- expireTime: 200,
237
- });
238
-
239
- map.set("key1", 100);
240
-
241
- // 만료 대기
242
- await vi.advanceTimersByTimeAsync(350);
243
-
244
- expect(map.size).toBe(0);
245
- // GC 타이머 중지 확인 (더 기다려도 문제 없음)
246
- await vi.advanceTimersByTimeAsync(200);
247
- expect(map.size).toBe(0);
248
- });
249
- });
250
-
251
- //#endregion
252
-
253
- //#region onExpire 콜백
254
-
255
- describe("onExpire 콜백", () => {
256
- it("만료 시 onExpire 콜백이 호출된다", async () => {
257
- const expired: Array<[string, number]> = [];
258
- const map = new LazyGcMap<string, number>({
259
- gcInterval: 100,
260
- expireTime: 200,
261
- onExpire: (key, value) => {
262
- expired.push([key, value]);
263
- },
264
- });
265
-
266
- map.set("key1", 100);
267
- await vi.advanceTimersByTimeAsync(350);
268
-
269
- expect(expired).toEqual([["key1", 100]]);
270
- });
271
-
272
- it("비동기 onExpire 콜백도 지원한다", async () => {
273
- const expired: Array<[string, number]> = [];
274
- const map = new LazyGcMap<string, number>({
275
- gcInterval: 100,
276
- expireTime: 200,
277
- onExpire: async (key, value) => {
278
- await new Promise((r) => setTimeout(r, 10));
279
- expired.push([key, value]);
280
- },
281
- });
282
-
283
- map.set("key1", 100);
284
- // expireTime(200) + gcInterval(100) + callback(10) = 310ms
285
- await vi.advanceTimersByTimeAsync(350);
286
-
287
- expect(expired).toEqual([["key1", 100]]);
288
- });
289
-
290
- it("여러 항목 만료 시 각각 onExpire가 호출된다", async () => {
291
- const expired: Array<[string, number]> = [];
292
- const map = new LazyGcMap<string, number>({
293
- gcInterval: 100,
294
- expireTime: 200,
295
- onExpire: (key, value) => {
296
- expired.push([key, value]);
297
- },
298
- });
299
-
300
- map.set("key1", 100);
301
- map.set("key2", 200);
302
- await vi.advanceTimersByTimeAsync(350);
303
-
304
- expect(expired).toHaveLength(2);
305
- expect(expired).toContainEqual(["key1", 100]);
306
- expect(expired).toContainEqual(["key2", 200]);
307
- });
308
-
309
- it("onExpire 에러는 무시한다", async () => {
310
- const expired: Array<[string, number]> = [];
311
- const map = new LazyGcMap<string, number>({
312
- gcInterval: 100,
313
- expireTime: 200,
314
- onExpire: (key, value) => {
315
- expired.push([key, value]);
316
- throw new Error("callback error");
317
- },
318
- });
319
-
320
- map.set("key1", 100);
321
- await vi.advanceTimersByTimeAsync(350);
322
-
323
- // 에러가 발생해도 만료는 정상 처리됨
324
- expect(expired).toEqual([["key1", 100]]);
325
- expect(map.has("key1")).toBe(false);
326
- });
327
-
328
- it("onExpire 중 같은 키로 set() 호출 시 새 값이 유지된다", async () => {
329
- let map: LazyGcMap<string, number>;
330
- const expired: Array<[string, number]> = [];
331
-
332
- map = new LazyGcMap<string, number>({
333
- gcInterval: 100,
334
- expireTime: 200,
335
- onExpire: (key, value) => {
336
- expired.push([key, value]);
337
- // onExpire 콜백 중에 같은 키로 새 값 등록
338
- map.set(key, value + 1000);
339
- },
340
- });
341
-
342
- map.set("key1", 100);
343
- await vi.advanceTimersByTimeAsync(350);
344
-
345
- // onExpire는 호출되었지만, 새로 등록된 값은 삭제되지 않음
346
- expect(expired).toEqual([["key1", 100]]);
347
- expect(map.has("key1")).toBe(true);
348
- expect(map.get("key1")).toBe(1100);
349
- });
350
-
351
- it("onExpire 중 다른 키로 set() 호출은 영향 없다", async () => {
352
- let map: LazyGcMap<string, number>;
353
- const expired: Array<[string, number]> = [];
354
-
355
- map = new LazyGcMap<string, number>({
356
- gcInterval: 100,
357
- expireTime: 200,
358
- onExpire: (key, value) => {
359
- expired.push([key, value]);
360
- // onExpire 콜백 중에 다른 키로 새 값 등록 (key1 만료 시에만)
361
- if (key === "key1") {
362
- map.set("key2", 200);
363
- }
364
- },
365
- });
366
-
367
- map.set("key1", 100);
368
- // expireTime(200) + gcInterval(100) = 300ms 후 GC
369
- // key2가 등록된 후에도 아직 만료되지 않아야 함
370
- await vi.advanceTimersByTimeAsync(350);
371
-
372
- // key1은 만료 삭제됨
373
- expect(expired).toEqual([["key1", 100]]);
374
- expect(map.has("key1")).toBe(false);
375
- // key2는 새로 등록됨 (아직 만료 전)
376
- expect(map.has("key2")).toBe(true);
377
- expect(map.get("key2")).toBe(200);
378
- });
379
- });
380
-
381
- //#endregion
382
-
383
- //#region dispose (타이머 및 리소스 정리)
384
-
385
- describe("dispose() - 타이머 정리", () => {
386
- it("dispose 후 타이머가 정리되어 GC 콜백이 호출되지 않는다", async () => {
387
- const expired: Array<[string, number]> = [];
388
- const map = new LazyGcMap<string, number>({
389
- gcInterval: 100,
390
- expireTime: 200,
391
- onExpire: (key, value) => {
392
- expired.push([key, value]);
393
- },
394
- });
395
-
396
- map.set("key1", 100);
397
- expect(map.has("key1")).toBe(true);
398
-
399
- // dispose 호출로 타이머 정리
400
- map.dispose();
401
- expect(map.size).toBe(0);
402
-
403
- // expireTime + gcInterval 이상 대기
404
- await vi.advanceTimersByTimeAsync(400);
405
-
406
- // GC 콜백이 호출되지 않아야 함 (dispose로 이미 정리됨)
407
- expect(expired).toHaveLength(0);
408
- });
409
-
410
- it("dispose 후 set은 무시된다", () => {
411
- const map = new LazyGcMap<string, number>({
412
- gcInterval: 100,
413
- expireTime: 200,
414
- });
415
-
416
- map.set("key1", 100);
417
- map.dispose();
418
-
419
- // dispose 후 set은 무시됨
420
- map.set("key2", 200);
421
- expect(map.has("key2")).toBe(false);
422
- expect(map.get("key2")).toBeUndefined();
423
- expect(map.size).toBe(0);
424
- });
425
-
426
- it("dispose는 여러 번 호출해도 안전하다", () => {
427
- const map = new LazyGcMap<string, number>({
428
- gcInterval: 1000,
429
- expireTime: 5000,
430
- });
431
-
432
- map.set("key1", 100);
433
-
434
- // 여러 번 호출해도 에러 없음
435
- map.dispose();
436
- map.dispose();
437
- map.dispose();
438
-
439
- expect(map.size).toBe(0);
440
- });
441
-
442
- it("using 문으로 자동 dispose된다", async () => {
443
- const expired: Array<[string, number]> = [];
444
- {
445
- using map = new LazyGcMap<string, number>({
446
- gcInterval: 100,
447
- expireTime: 200,
448
- onExpire: (key, value) => {
449
- expired.push([key, value]);
450
- },
451
- });
452
- map.set("key1", 100);
453
- expect(map.has("key1")).toBe(true);
454
- } // using 블록 종료 시 dispose 자동 호출
455
- await vi.advanceTimersByTimeAsync(350);
456
- // dispose로 정리됨 (onExpire 미호출)
457
- expect(expired).toHaveLength(0);
458
- });
459
- });
460
-
461
- //#endregion
462
-
463
- //#region clear
464
-
465
- describe("clear()", () => {
466
- it("모든 항목을 삭제한다", () => {
467
- const map = new LazyGcMap<string, number>({
468
- gcInterval: 1000,
469
- expireTime: 5000,
470
- });
471
-
472
- map.set("key1", 100);
473
- map.set("key2", 200);
474
- expect(map.size).toBe(2);
475
-
476
- map.clear();
477
- expect(map.size).toBe(0);
478
- expect(map.has("key1")).toBe(false);
479
- expect(map.has("key2")).toBe(false);
480
- });
481
-
482
- it("clear 후 새 항목을 추가할 수 있다", () => {
483
- const map = new LazyGcMap<string, number>({
484
- gcInterval: 1000,
485
- expireTime: 5000,
486
- });
487
-
488
- map.set("key1", 100);
489
- map.clear();
490
-
491
- map.set("key2", 200);
492
- expect(map.has("key2")).toBe(true);
493
- expect(map.get("key2")).toBe(200);
494
- });
495
-
496
- it("clear는 여러 번 호출해도 안전하다", () => {
497
- const map = new LazyGcMap<string, number>({
498
- gcInterval: 1000,
499
- expireTime: 5000,
500
- });
501
-
502
- map.set("key1", 100);
503
-
504
- // 여러 번 호출해도 에러 없음
505
- map.clear();
506
- map.clear();
507
- map.clear();
508
-
509
- expect(map.size).toBe(0);
510
- });
511
-
512
- it("clear 후 GC가 정상 작동한다", async () => {
513
- const map = new LazyGcMap<string, number>({
514
- gcInterval: 100,
515
- expireTime: 200,
516
- });
517
-
518
- map.set("key1", 100);
519
- map.clear();
520
-
521
- // clear 후 새 항목 추가
522
- map.set("key2", 200);
523
-
524
- // GC가 정상 작동하는지 확인
525
- await vi.advanceTimersByTimeAsync(350);
526
- expect(map.has("key2")).toBe(false);
527
- });
528
- });
529
-
530
- //#endregion
531
-
532
- //#region SharedArrayBuffer 지원
533
-
534
- describe("SharedArrayBuffer 지원", () => {
535
- it("SharedArrayBuffer를 값으로 사용할 수 있다", () => {
536
- // SharedArrayBuffer는 일부 환경에서 보안상 비활성화될 수 있음
537
- if (typeof SharedArrayBuffer === "undefined") {
538
- expect(true).toBe(true); // 환경에서 지원하지 않으면 스킵
539
- return;
540
- }
541
-
542
- const map = new LazyGcMap<string, SharedArrayBuffer>({
543
- gcInterval: 1000,
544
- expireTime: 5000,
545
- });
546
-
547
- const buffer = new SharedArrayBuffer(16);
548
- map.set("key1", buffer);
549
-
550
- expect(map.get("key1")).toBe(buffer);
551
- expect(map.get("key1")?.byteLength).toBe(16);
552
- });
553
- });
554
-
555
- //#endregion
556
-
557
- //#region Iterator
558
-
559
- describe("Iterator", () => {
560
- it("values()로 값들을 순회한다", () => {
561
- const map = new LazyGcMap<string, number>({
562
- gcInterval: 1000,
563
- expireTime: 5000,
564
- });
565
-
566
- map.set("key1", 100);
567
- map.set("key2", 200);
568
- map.set("key3", 300);
569
-
570
- const values = Array.from(map.values());
571
- expect(values).toHaveLength(3);
572
- expect(values).toContain(100);
573
- expect(values).toContain(200);
574
- expect(values).toContain(300);
575
- });
576
-
577
- it("keys()로 키들을 순회한다", () => {
578
- const map = new LazyGcMap<string, number>({
579
- gcInterval: 1000,
580
- expireTime: 5000,
581
- });
582
-
583
- map.set("key1", 100);
584
- map.set("key2", 200);
585
-
586
- const keys = Array.from(map.keys());
587
- expect(keys).toEqual(["key1", "key2"]);
588
- });
589
-
590
- it("entries()로 엔트리를 순회한다", () => {
591
- const map = new LazyGcMap<string, number>({
592
- gcInterval: 1000,
593
- expireTime: 5000,
594
- });
595
-
596
- map.set("key1", 100);
597
- map.set("key2", 200);
598
-
599
- const entries = Array.from(map.entries());
600
- expect(entries).toEqual([
601
- ["key1", 100],
602
- ["key2", 200],
603
- ]);
604
- });
605
- });
606
-
607
- //#endregion
608
-
609
- //#region dispose 후 안전성
610
-
611
- describe("dispose 후 안전성", () => {
612
- it("dispose 후 get은 undefined를 반환한다", () => {
613
- const map = new LazyGcMap<string, number>({
614
- gcInterval: 10000,
615
- expireTime: 60000,
616
- });
617
- map.set("a", 1);
618
- map.dispose();
619
- expect(map.get("a")).toBeUndefined();
620
- });
621
-
622
- it("dispose 후 has는 false를 반환한다", () => {
623
- const map = new LazyGcMap<string, number>({
624
- gcInterval: 10000,
625
- expireTime: 60000,
626
- });
627
- map.set("a", 1);
628
- map.dispose();
629
- expect(map.has("a")).toBe(false);
630
- });
631
-
632
- it("dispose 후 delete는 false를 반환한다", () => {
633
- const map = new LazyGcMap<string, number>({
634
- gcInterval: 10000,
635
- expireTime: 60000,
636
- });
637
- map.set("a", 1);
638
- map.dispose();
639
- expect(map.delete("a")).toBe(false);
640
- });
641
-
642
- it("dispose 후 getOrCreate는 에러를 던진다", () => {
643
- const map = new LazyGcMap<string, number>({
644
- gcInterval: 10000,
645
- expireTime: 60000,
646
- });
647
- map.dispose();
648
- expect(() => map.getOrCreate("a", () => 1)).toThrow();
649
- });
650
-
651
- it("dispose 후 clear는 에러 없이 무시된다", () => {
652
- const map = new LazyGcMap<string, number>({
653
- gcInterval: 10000,
654
- expireTime: 60000,
655
- });
656
- map.dispose();
657
- expect(() => map.clear()).not.toThrow();
658
- });
659
-
660
- it("dispose 후 values는 빈 이터레이터를 반환한다", () => {
661
- const map = new LazyGcMap<string, number>({
662
- gcInterval: 10000,
663
- expireTime: 60000,
664
- });
665
- map.set("a", 1);
666
- map.dispose();
667
- expect([...map.values()]).toEqual([]);
668
- });
669
-
670
- it("dispose 후 keys는 빈 이터레이터를 반환한다", () => {
671
- const map = new LazyGcMap<string, number>({
672
- gcInterval: 10000,
673
- expireTime: 60000,
674
- });
675
- map.set("a", 1);
676
- map.dispose();
677
- expect([...map.keys()]).toEqual([]);
678
- });
679
-
680
- it("dispose 후 entries는 빈 이터레이터를 반환한다", () => {
681
- const map = new LazyGcMap<string, number>({
682
- gcInterval: 10000,
683
- expireTime: 60000,
684
- });
685
- map.set("a", 1);
686
- map.dispose();
687
- expect([...map.entries()]).toEqual([]);
688
- });
689
- });
690
-
691
- //#endregion
692
- });