@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.
- package/dist/common.types.js +4 -4
- package/dist/errors/argument-error.js +1 -1
- package/dist/errors/not-implemented-error.js +1 -1
- package/dist/errors/timeout-error.js +1 -1
- package/dist/extensions/arr-ext.helpers.js +4 -4
- package/dist/extensions/arr-ext.js +9 -9
- package/dist/features/debounce-queue.js +2 -2
- package/dist/features/serial-queue.js +3 -3
- package/dist/index.js +30 -30
- package/dist/types/date-only.js +2 -2
- package/dist/types/date-time.js +2 -2
- package/dist/types/time.js +2 -2
- package/dist/types/uuid.js +1 -1
- package/dist/utils/bytes.js +1 -1
- package/dist/utils/json.js +8 -8
- package/dist/utils/obj.js +5 -5
- package/dist/utils/primitive.js +5 -5
- package/dist/utils/transferable.js +4 -4
- package/dist/utils/wait.js +1 -1
- package/package.json +7 -4
- package/.cache/typecheck-browser.tsbuildinfo +0 -1
- package/.cache/typecheck-node.tsbuildinfo +0 -1
- package/.cache/typecheck-tests-browser.tsbuildinfo +0 -1
- package/.cache/typecheck-tests-node.tsbuildinfo +0 -1
- package/src/common.types.ts +0 -91
- package/src/env.ts +0 -11
- package/src/errors/argument-error.ts +0 -40
- package/src/errors/not-implemented-error.ts +0 -32
- package/src/errors/sd-error.ts +0 -53
- package/src/errors/timeout-error.ts +0 -36
- package/src/extensions/arr-ext.helpers.ts +0 -53
- package/src/extensions/arr-ext.ts +0 -777
- package/src/extensions/arr-ext.types.ts +0 -258
- package/src/extensions/map-ext.ts +0 -86
- package/src/extensions/set-ext.ts +0 -68
- package/src/features/debounce-queue.ts +0 -116
- package/src/features/event-emitter.ts +0 -112
- package/src/features/serial-queue.ts +0 -94
- package/src/globals.ts +0 -12
- package/src/index.ts +0 -55
- package/src/types/date-only.ts +0 -329
- package/src/types/date-time.ts +0 -294
- package/src/types/lazy-gc-map.ts +0 -244
- package/src/types/time.ts +0 -210
- package/src/types/uuid.ts +0 -113
- package/src/utils/bytes.ts +0 -160
- package/src/utils/date-format.ts +0 -239
- package/src/utils/json.ts +0 -230
- package/src/utils/num.ts +0 -97
- package/src/utils/obj.ts +0 -956
- package/src/utils/path.ts +0 -40
- package/src/utils/primitive.ts +0 -33
- package/src/utils/str.ts +0 -252
- package/src/utils/template-strings.ts +0 -132
- package/src/utils/transferable.ts +0 -269
- package/src/utils/wait.ts +0 -40
- package/src/utils/xml.ts +0 -105
- package/src/zip/sd-zip.ts +0 -218
- package/tests/errors/errors.spec.ts +0 -196
- package/tests/extensions/array-extension.spec.ts +0 -790
- package/tests/extensions/map-extension.spec.ts +0 -147
- package/tests/extensions/set-extension.spec.ts +0 -74
- package/tests/types/date-only.spec.ts +0 -636
- package/tests/types/date-time.spec.ts +0 -391
- package/tests/types/lazy-gc-map.spec.ts +0 -692
- package/tests/types/time.spec.ts +0 -559
- package/tests/types/types.spec.ts +0 -55
- package/tests/types/uuid.spec.ts +0 -91
- package/tests/utils/bytes-utils.spec.ts +0 -230
- package/tests/utils/date-format.spec.ts +0 -371
- package/tests/utils/debounce-queue.spec.ts +0 -272
- package/tests/utils/json.spec.ts +0 -475
- package/tests/utils/number.spec.ts +0 -184
- package/tests/utils/object.spec.ts +0 -827
- package/tests/utils/path.spec.ts +0 -78
- package/tests/utils/primitive.spec.ts +0 -55
- package/tests/utils/sd-event-emitter.spec.ts +0 -216
- package/tests/utils/serial-queue.spec.ts +0 -365
- package/tests/utils/string.spec.ts +0 -294
- package/tests/utils/template-strings.spec.ts +0 -96
- package/tests/utils/transferable.spec.ts +0 -698
- package/tests/utils/wait.spec.ts +0 -145
- package/tests/utils/xml.spec.ts +0 -146
- package/tests/zip/sd-zip.spec.ts +0 -234
package/tests/utils/wait.spec.ts
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { waitTime as time, waitUntil as until, TimeoutError } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
describe("Wait", () => {
|
|
5
|
-
//#region time
|
|
6
|
-
|
|
7
|
-
describe("time()", () => {
|
|
8
|
-
it("지정된 시간만큼 대기한다", async () => {
|
|
9
|
-
const start = Date.now();
|
|
10
|
-
await time(100);
|
|
11
|
-
const elapsed = Date.now() - start;
|
|
12
|
-
|
|
13
|
-
// 100ms ± 오차 범위 - CI 환경 부하 및 타이머 정밀도 고려
|
|
14
|
-
expect(elapsed).toBeGreaterThanOrEqual(95);
|
|
15
|
-
expect(elapsed).toBeLessThan(250);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("0ms 대기도 정상 동작한다", async () => {
|
|
19
|
-
const start = Date.now();
|
|
20
|
-
await time(0);
|
|
21
|
-
const elapsed = Date.now() - start;
|
|
22
|
-
|
|
23
|
-
expect(elapsed).toBeLessThan(50);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
//#endregion
|
|
28
|
-
|
|
29
|
-
//#region until
|
|
30
|
-
|
|
31
|
-
describe("until()", () => {
|
|
32
|
-
it("조건이 참이 될 때까지 대기한다", async () => {
|
|
33
|
-
let count = 0;
|
|
34
|
-
|
|
35
|
-
await until(() => {
|
|
36
|
-
count++;
|
|
37
|
-
return count >= 3;
|
|
38
|
-
}, 10);
|
|
39
|
-
|
|
40
|
-
expect(count).toBe(3);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("비동기 조건 함수도 지원한다", async () => {
|
|
44
|
-
let count = 0;
|
|
45
|
-
|
|
46
|
-
await until(async () => {
|
|
47
|
-
await time(10);
|
|
48
|
-
count++;
|
|
49
|
-
return count >= 3;
|
|
50
|
-
}, 10);
|
|
51
|
-
|
|
52
|
-
expect(count).toBe(3);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("조건이 이미 참이면 즉시 반환한다", async () => {
|
|
56
|
-
const start = Date.now();
|
|
57
|
-
await until(() => true, 100);
|
|
58
|
-
const elapsed = Date.now() - start;
|
|
59
|
-
|
|
60
|
-
expect(elapsed).toBeLessThan(50);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("최대 시도 횟수 초과 시 TimeoutError를 던진다", async () => {
|
|
64
|
-
let count = 0;
|
|
65
|
-
|
|
66
|
-
await expect(async () => {
|
|
67
|
-
await until(
|
|
68
|
-
() => {
|
|
69
|
-
count++;
|
|
70
|
-
return false;
|
|
71
|
-
},
|
|
72
|
-
10,
|
|
73
|
-
5,
|
|
74
|
-
);
|
|
75
|
-
}).rejects.toThrow(TimeoutError);
|
|
76
|
-
|
|
77
|
-
expect(count).toBe(5);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("maxCount가 undefined면 무제한 대기한다", async () => {
|
|
81
|
-
let count = 0;
|
|
82
|
-
|
|
83
|
-
// 무제한 대기지만 조건이 참이 되면 반환
|
|
84
|
-
await until(
|
|
85
|
-
() => {
|
|
86
|
-
count++;
|
|
87
|
-
return count >= 10;
|
|
88
|
-
},
|
|
89
|
-
10,
|
|
90
|
-
undefined,
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
expect(count).toBe(10);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it("milliseconds 기본값은 100ms다", async () => {
|
|
97
|
-
let count = 0;
|
|
98
|
-
const start = Date.now();
|
|
99
|
-
|
|
100
|
-
await until(() => {
|
|
101
|
-
count++;
|
|
102
|
-
return count >= 3;
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const elapsed = Date.now() - start;
|
|
106
|
-
// 100ms * 2회 대기 = 200ms (첫 체크는 즉시), 타이머 오차 고려
|
|
107
|
-
expect(elapsed).toBeGreaterThanOrEqual(190);
|
|
108
|
-
expect(elapsed).toBeLessThan(350);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("maxCount=1이면 한 번만 시도 후 에러", async () => {
|
|
112
|
-
let count = 0;
|
|
113
|
-
|
|
114
|
-
await expect(async () => {
|
|
115
|
-
await until(
|
|
116
|
-
() => {
|
|
117
|
-
count++;
|
|
118
|
-
return false;
|
|
119
|
-
},
|
|
120
|
-
10,
|
|
121
|
-
1,
|
|
122
|
-
);
|
|
123
|
-
}).rejects.toThrow(TimeoutError);
|
|
124
|
-
|
|
125
|
-
expect(count).toBe(1);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it("조건이 maxCount 내에 참이 되면 성공", async () => {
|
|
129
|
-
let count = 0;
|
|
130
|
-
|
|
131
|
-
await until(
|
|
132
|
-
() => {
|
|
133
|
-
count++;
|
|
134
|
-
return count >= 3;
|
|
135
|
-
},
|
|
136
|
-
10,
|
|
137
|
-
5,
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
expect(count).toBe(3);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
//#endregion
|
|
145
|
-
});
|
package/tests/utils/xml.spec.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { xmlParse as parse, xmlStringify as stringify } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
describe("XmlConvert", () => {
|
|
5
|
-
//#region parse
|
|
6
|
-
|
|
7
|
-
describe("parse()", () => {
|
|
8
|
-
it("기본 XML을 파싱한다", () => {
|
|
9
|
-
const xml = "<root><child>value</child></root>";
|
|
10
|
-
const result = parse(xml) as Record<string, unknown>;
|
|
11
|
-
|
|
12
|
-
expect(result).toHaveProperty("root");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("속성을 포함한 XML을 파싱한다", () => {
|
|
16
|
-
const xml = '<root id="1"><child name="test">value</child></root>';
|
|
17
|
-
const result = parse(xml) as {
|
|
18
|
-
root: {
|
|
19
|
-
$: { id: string };
|
|
20
|
-
child: Array<{ $: { name: string }; _: string }>;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
expect(result.root.$.id).toBe("1");
|
|
25
|
-
expect(result.root.child[0].$.name).toBe("test");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("중첩된 XML을 파싱한다", () => {
|
|
29
|
-
const xml = "<root><parent><child>value</child></parent></root>";
|
|
30
|
-
const result = parse(xml) as {
|
|
31
|
-
root: { parent: Array<{ child: string[] }> };
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
expect(result.root.parent[0].child[0]).toBe("value");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("텍스트 노드를 _ 키로 파싱한다", () => {
|
|
38
|
-
const xml = '<item id="1">text content</item>';
|
|
39
|
-
const result = parse(xml) as {
|
|
40
|
-
item: { $: { id: string }; _: string };
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
expect(result.item._).toBe("text content");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("namespace prefix를 제거한다 (stripTagPrefix: true)", () => {
|
|
47
|
-
const xml = "<ns:root><ns:child>value</ns:child></ns:root>";
|
|
48
|
-
const result = parse(xml, { stripTagPrefix: true }) as {
|
|
49
|
-
root: { child: string[] };
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
expect(result).toHaveProperty("root");
|
|
53
|
-
expect(result.root).toHaveProperty("child");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("namespace prefix를 유지한다 (기본)", () => {
|
|
57
|
-
const xml = "<ns:root><ns:child>value</ns:child></ns:root>";
|
|
58
|
-
const result = parse(xml) as Record<string, unknown>;
|
|
59
|
-
|
|
60
|
-
expect(result).toHaveProperty("ns:root");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("여러 개의 같은 태그를 배열로 파싱한다", () => {
|
|
64
|
-
const xml = "<root><item>1</item><item>2</item><item>3</item></root>";
|
|
65
|
-
const result = parse(xml) as { root: { item: string[] } };
|
|
66
|
-
|
|
67
|
-
expect(result.root.item).toEqual(["1", "2", "3"]);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("속성의 namespace prefix는 제거하지 않는다", () => {
|
|
71
|
-
const xml = '<ns:root xmlns:ns="http://example.com"><ns:child>value</ns:child></ns:root>';
|
|
72
|
-
const result = parse(xml, { stripTagPrefix: true }) as {
|
|
73
|
-
root: { $: Record<string, string>; child: string[] };
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
expect(result.root.$).toHaveProperty("xmlns:ns");
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
//#endregion
|
|
81
|
-
|
|
82
|
-
//#region stringify
|
|
83
|
-
|
|
84
|
-
describe("stringify()", () => {
|
|
85
|
-
it("객체를 XML로 직렬화한다", () => {
|
|
86
|
-
const obj = { root: { child: "value" } };
|
|
87
|
-
const result = stringify(obj);
|
|
88
|
-
|
|
89
|
-
expect(result).toContain("<root>");
|
|
90
|
-
expect(result).toContain("<child>value</child>");
|
|
91
|
-
expect(result).toContain("</root>");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("속성을 포함한 객체를 직렬화한다", () => {
|
|
95
|
-
const obj = { root: { $: { id: "1" }, child: "value" } };
|
|
96
|
-
const result = stringify(obj);
|
|
97
|
-
|
|
98
|
-
expect(result).toContain('id="1"');
|
|
99
|
-
expect(result).toContain("<child>value</child>");
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("배열을 여러 태그로 직렬화한다", () => {
|
|
103
|
-
const obj = { root: { item: ["1", "2", "3"] } };
|
|
104
|
-
const result = stringify(obj);
|
|
105
|
-
|
|
106
|
-
expect(result).toContain("<item>1</item>");
|
|
107
|
-
expect(result).toContain("<item>2</item>");
|
|
108
|
-
expect(result).toContain("<item>3</item>");
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("텍스트 노드를 _ 키로 직렬화한다", () => {
|
|
112
|
-
const obj = { item: { $: { id: "1" }, _: "text content" } };
|
|
113
|
-
const result = stringify(obj);
|
|
114
|
-
|
|
115
|
-
expect(result).toContain('id="1"');
|
|
116
|
-
expect(result).toContain("text content");
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("중첩된 객체를 직렬화한다", () => {
|
|
120
|
-
const obj = { root: { parent: { child: "value" } } };
|
|
121
|
-
const result = stringify(obj);
|
|
122
|
-
|
|
123
|
-
expect(result).toContain("<parent>");
|
|
124
|
-
expect(result).toContain("<child>value</child>");
|
|
125
|
-
expect(result).toContain("</parent>");
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
//#endregion
|
|
130
|
-
|
|
131
|
-
//#region roundtrip
|
|
132
|
-
|
|
133
|
-
describe("parse/stringify roundtrip", () => {
|
|
134
|
-
it("parse 후 stringify하면 구조가 유지된다", () => {
|
|
135
|
-
const xml = "<root><child>value</child></root>";
|
|
136
|
-
const parsed = parse(xml);
|
|
137
|
-
const result = stringify(parsed);
|
|
138
|
-
|
|
139
|
-
expect(result).toContain("<root>");
|
|
140
|
-
expect(result).toContain("<child>value</child>");
|
|
141
|
-
expect(result).toContain("</root>");
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
//#endregion
|
|
146
|
-
});
|
package/tests/zip/sd-zip.spec.ts
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { ZipArchive } from "@simplysm/core-common";
|
|
3
|
-
|
|
4
|
-
const encoder = new TextEncoder();
|
|
5
|
-
const decoder = new TextDecoder();
|
|
6
|
-
|
|
7
|
-
describe("ZipArchive", () => {
|
|
8
|
-
//#region write + compress
|
|
9
|
-
|
|
10
|
-
describe("write + compress", () => {
|
|
11
|
-
it("write로 파일을 추가하고 compress로 ZIP을 생성한다", async () => {
|
|
12
|
-
const zip = new ZipArchive();
|
|
13
|
-
zip.write("file1.txt", encoder.encode("content 1"));
|
|
14
|
-
zip.write("file2.txt", encoder.encode("content 2"));
|
|
15
|
-
|
|
16
|
-
const zipBuffer = await zip.compress();
|
|
17
|
-
|
|
18
|
-
expect(zipBuffer instanceof Uint8Array).toBe(true);
|
|
19
|
-
expect(zipBuffer.length).toBeGreaterThan(0);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("특수 문자가 포함된 파일명을 처리한다", async () => {
|
|
23
|
-
const zip = new ZipArchive();
|
|
24
|
-
zip.write("파일 이름.txt", encoder.encode("한글 내용"));
|
|
25
|
-
zip.write("file (1).txt", encoder.encode("괄호 포함"));
|
|
26
|
-
zip.write("file@#$.txt", encoder.encode("특수문자"));
|
|
27
|
-
|
|
28
|
-
const zipBuffer = await zip.compress();
|
|
29
|
-
const result = new ZipArchive(zipBuffer);
|
|
30
|
-
|
|
31
|
-
const content1 = await result.get("파일 이름.txt");
|
|
32
|
-
const content2 = await result.get("file (1).txt");
|
|
33
|
-
const content3 = await result.get("file@#$.txt");
|
|
34
|
-
|
|
35
|
-
expect(content1 != null ? decoder.decode(content1) : undefined).toBe("한글 내용");
|
|
36
|
-
expect(content2 != null ? decoder.decode(content2) : undefined).toBe("괄호 포함");
|
|
37
|
-
expect(content3 != null ? decoder.decode(content3) : undefined).toBe("특수문자");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("빈 ZIP도 압축할 수 있다", async () => {
|
|
41
|
-
const zip = new ZipArchive();
|
|
42
|
-
const zipBuffer = await zip.compress();
|
|
43
|
-
|
|
44
|
-
expect(zipBuffer instanceof Uint8Array).toBe(true);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("같은 파일명으로 여러 번 write하면 덮어쓴다", async () => {
|
|
48
|
-
const zip = new ZipArchive();
|
|
49
|
-
zip.write("file.txt", encoder.encode("first"));
|
|
50
|
-
zip.write("file.txt", encoder.encode("second"));
|
|
51
|
-
|
|
52
|
-
const zipBuffer = await zip.compress();
|
|
53
|
-
const result = new ZipArchive(zipBuffer);
|
|
54
|
-
const content = await result.get("file.txt");
|
|
55
|
-
|
|
56
|
-
expect(content != null ? decoder.decode(content) : undefined).toBe("second");
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
|
-
|
|
62
|
-
//#region extractAll
|
|
63
|
-
|
|
64
|
-
describe("extractAll", () => {
|
|
65
|
-
it("압축된 모든 파일을 추출한다", async () => {
|
|
66
|
-
const zip = new ZipArchive();
|
|
67
|
-
zip.write("file1.txt", encoder.encode("content 1"));
|
|
68
|
-
zip.write("file2.txt", encoder.encode("content 2"));
|
|
69
|
-
const zipBuffer = await zip.compress();
|
|
70
|
-
|
|
71
|
-
const result = new ZipArchive(zipBuffer);
|
|
72
|
-
const files = await result.extractAll();
|
|
73
|
-
|
|
74
|
-
expect(files.size).toBe(2);
|
|
75
|
-
expect(files.get("file1.txt") != null ? decoder.decode(files.get("file1.txt")) : undefined).toBe("content 1");
|
|
76
|
-
expect(files.get("file2.txt") != null ? decoder.decode(files.get("file2.txt")) : undefined).toBe("content 2");
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("진행률 콜백을 호출한다", async () => {
|
|
80
|
-
const zip = new ZipArchive();
|
|
81
|
-
zip.write("file1.txt", encoder.encode("a".repeat(1000)));
|
|
82
|
-
zip.write("file2.txt", encoder.encode("b".repeat(1000)));
|
|
83
|
-
const zipBuffer = await zip.compress();
|
|
84
|
-
|
|
85
|
-
const result = new ZipArchive(zipBuffer);
|
|
86
|
-
const progressCalls: Array<{ fileName: string; extractedSize: number }> = [];
|
|
87
|
-
|
|
88
|
-
await result.extractAll((progress) => {
|
|
89
|
-
progressCalls.push({
|
|
90
|
-
fileName: progress.fileName,
|
|
91
|
-
extractedSize: progress.extractedSize,
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
expect(progressCalls.length).toBeGreaterThan(0);
|
|
96
|
-
expect(progressCalls.some((p) => p.fileName === "file1.txt")).toBe(true);
|
|
97
|
-
expect(progressCalls.some((p) => p.fileName === "file2.txt")).toBe(true);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("reader가 없으면 빈 캐시를 반환한다", async () => {
|
|
101
|
-
const zip = new ZipArchive();
|
|
102
|
-
const files = await zip.extractAll();
|
|
103
|
-
|
|
104
|
-
expect(files.size).toBe(0);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
//#endregion
|
|
109
|
-
|
|
110
|
-
//#region get
|
|
111
|
-
|
|
112
|
-
describe("get", () => {
|
|
113
|
-
it("특정 파일만 추출한다", async () => {
|
|
114
|
-
const zip = new ZipArchive();
|
|
115
|
-
zip.write("file1.txt", encoder.encode("content 1"));
|
|
116
|
-
zip.write("file2.txt", encoder.encode("content 2"));
|
|
117
|
-
const zipBuffer = await zip.compress();
|
|
118
|
-
|
|
119
|
-
const result = new ZipArchive(zipBuffer);
|
|
120
|
-
const content = await result.get("file1.txt");
|
|
121
|
-
|
|
122
|
-
expect(content != null ? decoder.decode(content) : undefined).toBe("content 1");
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("없는 파일은 undefined를 반환한다", async () => {
|
|
126
|
-
const zip = new ZipArchive();
|
|
127
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
128
|
-
const zipBuffer = await zip.compress();
|
|
129
|
-
|
|
130
|
-
const result = new ZipArchive(zipBuffer);
|
|
131
|
-
const content = await result.get("nonexistent.txt");
|
|
132
|
-
|
|
133
|
-
expect(content).toBe(undefined);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it("캐시된 파일은 재추출하지 않는다", async () => {
|
|
137
|
-
const zip = new ZipArchive();
|
|
138
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
139
|
-
const zipBuffer = await zip.compress();
|
|
140
|
-
|
|
141
|
-
const result = new ZipArchive(zipBuffer);
|
|
142
|
-
const content1 = await result.get("file.txt");
|
|
143
|
-
const content2 = await result.get("file.txt");
|
|
144
|
-
|
|
145
|
-
expect(content1).toBe(content2); // 같은 참조
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("reader가 없으면 undefined를 반환한다", async () => {
|
|
149
|
-
const zip = new ZipArchive();
|
|
150
|
-
const content = await zip.get("file.txt");
|
|
151
|
-
|
|
152
|
-
expect(content).toBe(undefined);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
//#endregion
|
|
157
|
-
|
|
158
|
-
//#region exists
|
|
159
|
-
|
|
160
|
-
describe("exists", () => {
|
|
161
|
-
it("파일 존재 여부를 확인한다", async () => {
|
|
162
|
-
const zip = new ZipArchive();
|
|
163
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
164
|
-
const zipBuffer = await zip.compress();
|
|
165
|
-
|
|
166
|
-
const result = new ZipArchive(zipBuffer);
|
|
167
|
-
const exists = await result.exists("file.txt");
|
|
168
|
-
const notExists = await result.exists("nonexistent.txt");
|
|
169
|
-
|
|
170
|
-
expect(exists).toBe(true);
|
|
171
|
-
expect(notExists).toBe(false);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it("캐시된 파일은 true를 반환한다", async () => {
|
|
175
|
-
const zip = new ZipArchive();
|
|
176
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
177
|
-
const zipBuffer = await zip.compress();
|
|
178
|
-
|
|
179
|
-
const result = new ZipArchive(zipBuffer);
|
|
180
|
-
await result.get("file.txt"); // 캐시에 로드
|
|
181
|
-
const exists = await result.exists("file.txt");
|
|
182
|
-
|
|
183
|
-
expect(exists).toBe(true);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it("reader가 없으면 false를 반환한다", async () => {
|
|
187
|
-
const zip = new ZipArchive();
|
|
188
|
-
const exists = await zip.exists("file.txt");
|
|
189
|
-
|
|
190
|
-
expect(exists).toBe(false);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
//#endregion
|
|
195
|
-
|
|
196
|
-
//#region close
|
|
197
|
-
|
|
198
|
-
describe("close", () => {
|
|
199
|
-
it("reader를 닫는다", async () => {
|
|
200
|
-
const zip = new ZipArchive();
|
|
201
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
202
|
-
const zipBuffer = await zip.compress();
|
|
203
|
-
|
|
204
|
-
const result = new ZipArchive(zipBuffer);
|
|
205
|
-
// extractAll 호출하여 캐시에 로드
|
|
206
|
-
await result.extractAll();
|
|
207
|
-
await result.close();
|
|
208
|
-
|
|
209
|
-
// close 이후에도 캐시된 데이터는 사용 가능
|
|
210
|
-
const content = await result.get("file.txt");
|
|
211
|
-
expect(content != null ? decoder.decode(content) : undefined).toBe("content");
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it("reader가 없어도 에러 없이 동작한다", async () => {
|
|
215
|
-
const zip = new ZipArchive();
|
|
216
|
-
await expect(zip.close()).resolves.not.toThrow();
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it("await using으로 자동 close된다", async () => {
|
|
220
|
-
const zip = new ZipArchive();
|
|
221
|
-
zip.write("file.txt", encoder.encode("content"));
|
|
222
|
-
const zipBuffer = await zip.compress();
|
|
223
|
-
|
|
224
|
-
{
|
|
225
|
-
await using result = new ZipArchive(zipBuffer);
|
|
226
|
-
await result.extractAll();
|
|
227
|
-
const content = await result.get("file.txt");
|
|
228
|
-
expect(decoder.decode(content)).toBe("content");
|
|
229
|
-
} // await using 블록 종료 시 close 자동 호출
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
//#endregion
|
|
234
|
-
});
|