@simplysm/core-node 13.0.0-beta.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 (111) hide show
  1. package/.cache/typecheck-node.tsbuildinfo +1 -0
  2. package/.cache/typecheck-tests-node.tsbuildinfo +1 -0
  3. package/README.md +375 -0
  4. package/dist/core-common/src/common.types.d.ts +74 -0
  5. package/dist/core-common/src/common.types.d.ts.map +1 -0
  6. package/dist/core-common/src/env.d.ts +6 -0
  7. package/dist/core-common/src/env.d.ts.map +1 -0
  8. package/dist/core-common/src/errors/argument-error.d.ts +25 -0
  9. package/dist/core-common/src/errors/argument-error.d.ts.map +1 -0
  10. package/dist/core-common/src/errors/not-implemented-error.d.ts +29 -0
  11. package/dist/core-common/src/errors/not-implemented-error.d.ts.map +1 -0
  12. package/dist/core-common/src/errors/sd-error.d.ts +27 -0
  13. package/dist/core-common/src/errors/sd-error.d.ts.map +1 -0
  14. package/dist/core-common/src/errors/timeout-error.d.ts +31 -0
  15. package/dist/core-common/src/errors/timeout-error.d.ts.map +1 -0
  16. package/dist/core-common/src/extensions/arr-ext.d.ts +15 -0
  17. package/dist/core-common/src/extensions/arr-ext.d.ts.map +1 -0
  18. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +19 -0
  19. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +1 -0
  20. package/dist/core-common/src/extensions/arr-ext.types.d.ts +215 -0
  21. package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +1 -0
  22. package/dist/core-common/src/extensions/map-ext.d.ts +57 -0
  23. package/dist/core-common/src/extensions/map-ext.d.ts.map +1 -0
  24. package/dist/core-common/src/extensions/set-ext.d.ts +36 -0
  25. package/dist/core-common/src/extensions/set-ext.d.ts.map +1 -0
  26. package/dist/core-common/src/features/debounce-queue.d.ts +53 -0
  27. package/dist/core-common/src/features/debounce-queue.d.ts.map +1 -0
  28. package/dist/core-common/src/features/event-emitter.d.ts +66 -0
  29. package/dist/core-common/src/features/event-emitter.d.ts.map +1 -0
  30. package/dist/core-common/src/features/serial-queue.d.ts +47 -0
  31. package/dist/core-common/src/features/serial-queue.d.ts.map +1 -0
  32. package/dist/core-common/src/index.d.ts +32 -0
  33. package/dist/core-common/src/index.d.ts.map +1 -0
  34. package/dist/core-common/src/types/date-only.d.ts +152 -0
  35. package/dist/core-common/src/types/date-only.d.ts.map +1 -0
  36. package/dist/core-common/src/types/date-time.d.ts +96 -0
  37. package/dist/core-common/src/types/date-time.d.ts.map +1 -0
  38. package/dist/core-common/src/types/lazy-gc-map.d.ts +80 -0
  39. package/dist/core-common/src/types/lazy-gc-map.d.ts.map +1 -0
  40. package/dist/core-common/src/types/time.d.ts +68 -0
  41. package/dist/core-common/src/types/time.d.ts.map +1 -0
  42. package/dist/core-common/src/types/uuid.d.ts +35 -0
  43. package/dist/core-common/src/types/uuid.d.ts.map +1 -0
  44. package/dist/core-common/src/utils/bytes.d.ts +51 -0
  45. package/dist/core-common/src/utils/bytes.d.ts.map +1 -0
  46. package/dist/core-common/src/utils/date-format.d.ts +90 -0
  47. package/dist/core-common/src/utils/date-format.d.ts.map +1 -0
  48. package/dist/core-common/src/utils/json.d.ts +34 -0
  49. package/dist/core-common/src/utils/json.d.ts.map +1 -0
  50. package/dist/core-common/src/utils/num.d.ts +60 -0
  51. package/dist/core-common/src/utils/num.d.ts.map +1 -0
  52. package/dist/core-common/src/utils/obj.d.ts +258 -0
  53. package/dist/core-common/src/utils/obj.d.ts.map +1 -0
  54. package/dist/core-common/src/utils/path.d.ts +23 -0
  55. package/dist/core-common/src/utils/path.d.ts.map +1 -0
  56. package/dist/core-common/src/utils/primitive.d.ts +18 -0
  57. package/dist/core-common/src/utils/primitive.d.ts.map +1 -0
  58. package/dist/core-common/src/utils/str.d.ts +103 -0
  59. package/dist/core-common/src/utils/str.d.ts.map +1 -0
  60. package/dist/core-common/src/utils/template-strings.d.ts +84 -0
  61. package/dist/core-common/src/utils/template-strings.d.ts.map +1 -0
  62. package/dist/core-common/src/utils/transferable.d.ts +47 -0
  63. package/dist/core-common/src/utils/transferable.d.ts.map +1 -0
  64. package/dist/core-common/src/utils/wait.d.ts +19 -0
  65. package/dist/core-common/src/utils/wait.d.ts.map +1 -0
  66. package/dist/core-common/src/utils/xml.d.ts +36 -0
  67. package/dist/core-common/src/utils/xml.d.ts.map +1 -0
  68. package/dist/core-common/src/zip/sd-zip.d.ts +80 -0
  69. package/dist/core-common/src/zip/sd-zip.d.ts.map +1 -0
  70. package/dist/core-node/src/features/fs-watcher.d.ts +70 -0
  71. package/dist/core-node/src/features/fs-watcher.d.ts.map +1 -0
  72. package/dist/core-node/src/index.d.ts +7 -0
  73. package/dist/core-node/src/index.d.ts.map +1 -0
  74. package/dist/core-node/src/utils/fs.d.ts +197 -0
  75. package/dist/core-node/src/utils/fs.d.ts.map +1 -0
  76. package/dist/core-node/src/utils/path.d.ts +75 -0
  77. package/dist/core-node/src/utils/path.d.ts.map +1 -0
  78. package/dist/core-node/src/worker/create-worker.d.ts +23 -0
  79. package/dist/core-node/src/worker/create-worker.d.ts.map +1 -0
  80. package/dist/core-node/src/worker/types.d.ts +67 -0
  81. package/dist/core-node/src/worker/types.d.ts.map +1 -0
  82. package/dist/core-node/src/worker/worker.d.ts +27 -0
  83. package/dist/core-node/src/worker/worker.d.ts.map +1 -0
  84. package/dist/features/fs-watcher.js +100 -0
  85. package/dist/features/fs-watcher.js.map +7 -0
  86. package/dist/index.js +7 -0
  87. package/dist/index.js.map +7 -0
  88. package/dist/utils/fs.js +305 -0
  89. package/dist/utils/fs.js.map +7 -0
  90. package/dist/utils/path.js +48 -0
  91. package/dist/utils/path.js.map +7 -0
  92. package/dist/worker/create-worker.js +85 -0
  93. package/dist/worker/create-worker.js.map +7 -0
  94. package/dist/worker/types.js +1 -0
  95. package/dist/worker/types.js.map +7 -0
  96. package/dist/worker/worker.js +142 -0
  97. package/dist/worker/worker.js.map +7 -0
  98. package/lib/worker-dev-proxy.js +12 -0
  99. package/package.json +23 -0
  100. package/src/features/fs-watcher.ts +176 -0
  101. package/src/index.ts +11 -0
  102. package/src/utils/fs.ts +550 -0
  103. package/src/utils/path.ts +128 -0
  104. package/src/worker/create-worker.ts +141 -0
  105. package/src/worker/types.ts +86 -0
  106. package/src/worker/worker.ts +207 -0
  107. package/tests/utils/fs-watcher.spec.ts +295 -0
  108. package/tests/utils/fs.spec.ts +754 -0
  109. package/tests/utils/path.spec.ts +192 -0
  110. package/tests/worker/fixtures/test-worker.ts +35 -0
  111. package/tests/worker/sd-worker.spec.ts +183 -0
@@ -0,0 +1,192 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import path from "path";
3
+ import {
4
+ pathPosix,
5
+ pathNorm,
6
+ pathIsChildPath,
7
+ pathChangeFileDirectory,
8
+ pathGetBasenameWithoutExt,
9
+ pathFilterByTargets,
10
+ type NormPath,
11
+ } from "../../src/utils/path";
12
+
13
+ describe("path ํ•จ์ˆ˜๋“ค", () => {
14
+ //#region posix
15
+
16
+ describe("pathPosix", () => {
17
+ it("๋‹จ์ผ ๊ฒฝ๋กœ ์ธ์ž๋ฅผ POSIX ์Šคํƒ€์ผ๋กœ ๋ณ€ํ™˜", () => {
18
+ const result = pathPosix("C:\\Users\\test\\file.txt");
19
+ expect(result).toBe("C:/Users/test/file.txt");
20
+ });
21
+
22
+ it("์—ฌ๋Ÿฌ ๊ฒฝ๋กœ ์ธ์ž๋ฅผ ์กฐํ•ฉํ•˜์—ฌ POSIX ์Šคํƒ€์ผ๋กœ ๋ณ€ํ™˜", () => {
23
+ const result = pathPosix("C:\\Users", "test", "file.txt");
24
+ expect(result).toBe("C:/Users/test/file.txt");
25
+ });
26
+
27
+ it("์ด๋ฏธ POSIX ์Šคํƒ€์ผ์ธ ๊ฒฝ๋กœ๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€", () => {
28
+ const result = pathPosix("/usr/local/bin");
29
+ expect(result).toBe("/usr/local/bin");
30
+ });
31
+
32
+ it("ํ˜ผํ•ฉ๋œ ๊ฒฝ๋กœ ๊ตฌ๋ถ„์ž ์ฒ˜๋ฆฌ", () => {
33
+ const result = pathPosix("C:/Users\\test/file.txt");
34
+ expect(result).toBe("C:/Users/test/file.txt");
35
+ });
36
+ });
37
+
38
+ //#endregion
39
+
40
+ //#region norm
41
+
42
+ describe("pathNorm", () => {
43
+ it("๊ฒฝ๋กœ๋ฅผ ์ •๊ทœํ™”ํ•˜๊ณ  NormPath ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜", () => {
44
+ const result: NormPath = pathNorm("./test/../file.txt");
45
+ expect(result).toBe(path.resolve("./test/../file.txt"));
46
+ });
47
+
48
+ it("์—ฌ๋Ÿฌ ๊ฒฝ๋กœ ์ธ์ž๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์ •๊ทœํ™”", () => {
49
+ const basePath = path.resolve("/base");
50
+ const result = pathNorm(basePath, "sub", "file.txt");
51
+ expect(result).toBe(path.resolve(basePath, "sub", "file.txt"));
52
+ });
53
+
54
+ it("์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋กœ ๋ณ€ํ™˜", () => {
55
+ const result = pathNorm("relative/path");
56
+ expect(path.isAbsolute(result)).toBe(true);
57
+ });
58
+ });
59
+
60
+ //#endregion
61
+
62
+ //#region isChildPath
63
+
64
+ describe("pathIsChildPath", () => {
65
+ it("์ž์‹ ๊ฒฝ๋กœ์ธ ๊ฒฝ์šฐ true ๋ฐ˜ํ™˜", () => {
66
+ const parent = pathNorm("/parent/dir");
67
+ const child = pathNorm("/parent/dir/child/file.txt");
68
+ expect(pathIsChildPath(child, parent)).toBe(true);
69
+ });
70
+
71
+ it("๊ฐ™์€ ๊ฒฝ๋กœ์ธ ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜", () => {
72
+ const parent = pathNorm("/parent/dir");
73
+ const child = pathNorm("/parent/dir");
74
+ expect(pathIsChildPath(child, parent)).toBe(false);
75
+ });
76
+
77
+ it("์ž์‹ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜", () => {
78
+ const parent = pathNorm("/parent/dir");
79
+ const child = pathNorm("/other/dir/file.txt");
80
+ expect(pathIsChildPath(child, parent)).toBe(false);
81
+ });
82
+
83
+ it("๋ถ€๋ชจ ๊ฒฝ๋กœ์˜ ์ผ๋ถ€ ๋ฌธ์ž์—ด๋งŒ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜", () => {
84
+ const parent = pathNorm("/parent/dir");
85
+ const child = pathNorm("/parent/directory/file.txt");
86
+ expect(pathIsChildPath(child, parent)).toBe(false);
87
+ });
88
+ });
89
+
90
+ //#endregion
91
+
92
+ //#region changeFileDirectory
93
+
94
+ describe("pathChangeFileDirectory", () => {
95
+ it("ํŒŒ์ผ์˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝ", () => {
96
+ const file = pathNorm("/source/sub/file.txt");
97
+ const from = pathNorm("/source");
98
+ const to = pathNorm("/target");
99
+
100
+ const result = pathChangeFileDirectory(file, from, to);
101
+ expect(result).toBe(pathNorm("/target/sub/file.txt"));
102
+ });
103
+
104
+ it("์ค‘์ฒฉ๋œ ๊ฒฝ๋กœ์—์„œ ๋””๋ ‰ํ† ๋ฆฌ ๋ณ€๊ฒฝ", () => {
105
+ const file = pathNorm("/a/b/c/d/file.txt");
106
+ const from = pathNorm("/a/b");
107
+ const to = pathNorm("/x/y");
108
+
109
+ const result = pathChangeFileDirectory(file, from, to);
110
+ expect(result).toBe(pathNorm("/x/y/c/d/file.txt"));
111
+ });
112
+
113
+ it("ํŒŒ์ผ์ด fromDirectory ์•ˆ์— ์—†์œผ๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ", () => {
114
+ const file = pathNorm("/other/path/file.txt");
115
+ const from = pathNorm("/source");
116
+ const to = pathNorm("/target");
117
+
118
+ expect(() => pathChangeFileDirectory(file, from, to)).toThrow();
119
+ });
120
+
121
+ it("filePath์™€ fromDirectory๊ฐ€ ๋™์ผํ•œ ๊ฒฝ์šฐ toDirectory ๋ฐ˜ํ™˜", () => {
122
+ const file = pathNorm("/source");
123
+ const from = pathNorm("/source");
124
+ const to = pathNorm("/target");
125
+
126
+ const result = pathChangeFileDirectory(file, from, to);
127
+ expect(result).toBe(to);
128
+ });
129
+ });
130
+
131
+ //#endregion
132
+
133
+ //#region getBasenameWithoutExt
134
+
135
+ describe("pathGetBasenameWithoutExt", () => {
136
+ it("๋‹จ์ผ ํ™•์žฅ์ž ์ œ๊ฑฐ (basename๋งŒ ๋ฐ˜ํ™˜)", () => {
137
+ const result = pathGetBasenameWithoutExt("/path/to/file.txt");
138
+ expect(result).toBe("file");
139
+ });
140
+
141
+ it("๋‹ค์ค‘ ํ™•์žฅ์ž์—์„œ ๋งˆ์ง€๋ง‰ ํ™•์žฅ์ž๋งŒ ์ œ๊ฑฐ", () => {
142
+ const result = pathGetBasenameWithoutExt("/path/to/file.spec.ts");
143
+ expect(result).toBe("file.spec");
144
+ });
145
+
146
+ it("ํ™•์žฅ์ž๊ฐ€ ์—†๋Š” ํŒŒ์ผ์€ basename ๋ฐ˜ํ™˜", () => {
147
+ const result = pathGetBasenameWithoutExt("/path/to/file");
148
+ expect(result).toBe("file");
149
+ });
150
+
151
+ it("์ˆจ๊น€ ํŒŒ์ผ(์ ์œผ๋กœ ์‹œ์ž‘)์€ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜", () => {
152
+ const result = pathGetBasenameWithoutExt("/path/to/.gitignore");
153
+ expect(result).toBe(".gitignore");
154
+ });
155
+ });
156
+
157
+ //#endregion
158
+
159
+ //#region filterByTargets
160
+
161
+ describe("pathFilterByTargets", () => {
162
+ const cwd = "/proj";
163
+ const files = ["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts", "/proj/lib/d.ts"];
164
+
165
+ it("๋นˆ ํƒ€๊ฒŸ ๋ฐฐ์—ด์ด๋ฉด ๋ชจ๋“  ํŒŒ์ผ ๋ฐ˜ํ™˜", () => {
166
+ const result = pathFilterByTargets(files, [], cwd);
167
+ expect(result).toEqual(files);
168
+ });
169
+
170
+ it("๋‹จ์ผ ํƒ€๊ฒŸ์œผ๋กœ ํ•„ํ„ฐ๋ง", () => {
171
+ const result = pathFilterByTargets(files, ["src"], cwd);
172
+ expect(result).toEqual(["/proj/src/a.ts", "/proj/src/b.ts"]);
173
+ });
174
+
175
+ it("๋‹ค์ค‘ ํƒ€๊ฒŸ์œผ๋กœ ํ•„ํ„ฐ๋ง", () => {
176
+ const result = pathFilterByTargets(files, ["src", "tests"], cwd);
177
+ expect(result).toEqual(["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts"]);
178
+ });
179
+
180
+ it("๋งค์นญ๋˜๋Š” ํŒŒ์ผ์ด ์—†์œผ๋ฉด ๋นˆ ๋ฐฐ์—ด ๋ฐ˜ํ™˜", () => {
181
+ const result = pathFilterByTargets(files, ["nonexistent"], cwd);
182
+ expect(result).toEqual([]);
183
+ });
184
+
185
+ it("์ •ํ™•ํ•œ ํŒŒ์ผ ๊ฒฝ๋กœ๋กœ ํ•„ํ„ฐ๋ง", () => {
186
+ const result = pathFilterByTargets(files, ["src/a.ts"], cwd);
187
+ expect(result).toEqual(["/proj/src/a.ts"]);
188
+ });
189
+ });
190
+
191
+ //#endregion
192
+ });
@@ -0,0 +1,35 @@
1
+ import { createWorker } from "../../../src";
2
+
3
+ interface TestWorkerEvents extends Record<string, unknown> {
4
+ progress: number;
5
+ }
6
+
7
+ const methods = {
8
+ add: (a: number, b: number) => {
9
+ sender.send("progress", 50);
10
+ return a + b;
11
+ },
12
+ echo: (message: string) => `Echo: ${message}`,
13
+ throwError: () => {
14
+ throw new Error("Intentional error");
15
+ },
16
+ delay: async (ms: number) => {
17
+ await new Promise((resolve) => setTimeout(resolve, ms));
18
+ return ms;
19
+ },
20
+ noReturn: () => {},
21
+ logMessage: (message: string) => {
22
+ console.log(message);
23
+ return "logged";
24
+ },
25
+ crash: () => {
26
+ // ๋™๊ธฐ์ ์œผ๋กœ ์ฆ‰์‹œ ์ข…๋ฃŒ
27
+ setImmediate(() => process.exit(1));
28
+ return "crashing...";
29
+ },
30
+ getEnv: (key: string) => process.env[key],
31
+ };
32
+
33
+ const sender = createWorker<typeof methods, TestWorkerEvents>(methods);
34
+
35
+ export default sender;
@@ -0,0 +1,183 @@
1
+ import { afterEach, describe, expect, it } from "vitest";
2
+ import path from "path";
3
+ import type { WorkerProxy } from "../../src/worker/types";
4
+ import { Worker } from "../../src/worker/worker";
5
+ import type * as TestWorkerModule from "./fixtures/test-worker";
6
+
7
+ describe("SdWorker", () => {
8
+ const workerPath = path.resolve(import.meta.dirname, "fixtures/test-worker.ts");
9
+ let worker: WorkerProxy<typeof TestWorkerModule> | undefined;
10
+
11
+ afterEach(async () => {
12
+ if (worker) {
13
+ await worker.terminate();
14
+ worker = undefined;
15
+ }
16
+ });
17
+
18
+ //#region ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
19
+
20
+ describe("๋ฉ”์„œ๋“œ ํ˜ธ์ถœ", () => {
21
+ it("์›Œ์ปค ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋ฐ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜", async () => {
22
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
23
+
24
+ const result = await worker.add(10, 20);
25
+
26
+ expect(result).toBe(30);
27
+ });
28
+
29
+ it("๋ฌธ์ž์—ด ๋ฐ˜ํ™˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ", async () => {
30
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
31
+
32
+ const result = await worker.echo("Hello");
33
+
34
+ expect(result).toBe("Echo: Hello");
35
+ });
36
+
37
+ it("์›Œ์ปค์—์„œ ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ reject", async () => {
38
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
39
+
40
+ await expect(worker.throwError()).rejects.toThrow();
41
+ });
42
+
43
+ it("์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ์—๋Ÿฌ", async () => {
44
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
45
+
46
+ // ํƒ€์ž… ์‹œ์Šคํ…œ์„ ์šฐํšŒํ•˜์—ฌ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
47
+ const unknownWorker = worker as unknown as { unknownMethod: () => Promise<void> };
48
+
49
+ await expect(unknownWorker.unknownMethod()).rejects.toThrow("์•Œ ์ˆ˜ ์—†๋Š” ๋ฉ”์„œ๋“œ: unknownMethod");
50
+ });
51
+
52
+ it("๋‹ค์ค‘ ์š”์ฒญ ๋™์‹œ ์ฒ˜๋ฆฌ", async () => {
53
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
54
+
55
+ const [result1, result2, result3] = await Promise.all([worker.add(1, 2), worker.add(3, 4), worker.add(5, 6)]);
56
+
57
+ expect(result1).toBe(3);
58
+ expect(result2).toBe(7);
59
+ expect(result3).toBe(11);
60
+ });
61
+
62
+ it("void ๋ฐ˜ํ™˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ", async () => {
63
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
64
+
65
+ const result = await worker.noReturn();
66
+
67
+ expect(result).toBeUndefined();
68
+ });
69
+ });
70
+
71
+ //#endregion
72
+
73
+ //#region ์ด๋ฒคํŠธ
74
+
75
+ describe("์ด๋ฒคํŠธ", () => {
76
+ it("์›Œ์ปค์—์„œ ์ด๋ฒคํŠธ ์ˆ˜์‹ ", async () => {
77
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
78
+
79
+ const events: number[] = [];
80
+ worker.on("progress", (value) => {
81
+ events.push(value);
82
+ });
83
+
84
+ await worker.add(1, 2);
85
+
86
+ expect(events).toContain(50);
87
+ });
88
+
89
+ it("off()๋กœ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์ œ๊ฑฐ", async () => {
90
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
91
+
92
+ const events: number[] = [];
93
+ const listener = (value: number) => {
94
+ events.push(value);
95
+ };
96
+
97
+ worker.on("progress", listener);
98
+ await worker.add(1, 2);
99
+
100
+ // ๋ฆฌ์Šค๋„ˆ ์ œ๊ฑฐ
101
+ worker.off("progress", listener);
102
+ await worker.add(3, 4);
103
+
104
+ // ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์˜ ์ด๋ฒคํŠธ๋งŒ ์ˆ˜์‹ ๋˜์–ด์•ผ ํ•จ
105
+ expect(events).toHaveLength(1);
106
+ expect(events[0]).toBe(50);
107
+ });
108
+ });
109
+
110
+ //#endregion
111
+
112
+ //#region terminate
113
+
114
+ describe("terminate", () => {
115
+ it("๋Œ€๊ธฐ ์ค‘์ธ ์š”์ฒญ์ด Worker terminated ์—๋Ÿฌ์™€ ํ•จ๊ป˜ reject", async () => {
116
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
117
+
118
+ const runPromise = worker.delay(5000);
119
+
120
+ // ์›Œ์ปค ์ข…๋ฃŒ ์ „์— ๋ฏธ๋ฆฌ ์—๋Ÿฌ๋ฅผ ์บ์น˜ํ•  ์ค€๋น„๋ฅผ ํ•œ๋‹ค
121
+ const errorPromise = runPromise.catch((err: unknown) => err);
122
+
123
+ // ์›Œ์ปค ์ข…๋ฃŒ
124
+ await worker.terminate();
125
+ worker = undefined;
126
+
127
+ const error = await errorPromise;
128
+ expect(error).toBeInstanceOf(Error);
129
+ expect((error as Error).message).toBe("์›Œ์ปค๊ฐ€ ์ข…๋ฃŒ๋จ (method: delay)");
130
+ });
131
+
132
+ it("์›Œ์ปค ๋น„์ •์ƒ ์ข…๋ฃŒ ์‹œ ๋Œ€๊ธฐ ์ค‘์ธ ์š”์ฒญ reject", async () => {
133
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
134
+
135
+ // ๊ธด delay๋ฅผ ๋จผ์ € ํ˜ธ์ถœํ•˜์—ฌ pending ์ƒํƒœ๋กœ ๋งŒ๋“ฆ
136
+ const delayPromise = worker.delay(5000).catch((err: unknown) => err);
137
+
138
+ // ์งง์€ ๋Œ€๊ธฐ ํ›„ crash ํ˜ธ์ถœ (delay๊ฐ€ pending ์ƒํƒœ์ธ ๋™์•ˆ)
139
+ await new Promise((resolve) => setTimeout(resolve, 10));
140
+ await worker.crash();
141
+
142
+ // ์›Œ์ปค๊ฐ€ ๋น„์ •์ƒ ์ข…๋ฃŒ๋˜๋ฉด pending ์ƒํƒœ์˜ delay ์š”์ฒญ์ด reject๋˜์–ด์•ผ ํ•จ
143
+ const error = await delayPromise;
144
+ expect(error).toBeInstanceOf(Error);
145
+ expect((error as Error).message).toContain("์›Œ์ปค๊ฐ€ ๋น„์ •์ƒ ์ข…๋ฃŒ๋จ");
146
+ });
147
+ });
148
+
149
+ //#endregion
150
+
151
+ //#region stdout/stderr
152
+
153
+ describe("stdout/stderr", () => {
154
+ it("์›Œ์ปค์˜ console.log ์ถœ๋ ฅ์ด ๋ฉ”์ธ ํ”„๋กœ์„ธ์Šค๋กœ ์ „๋‹ฌ", async () => {
155
+ worker = Worker.create<typeof TestWorkerModule>(workerPath);
156
+
157
+ const result = await worker.logMessage("test message");
158
+
159
+ // ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ ๋ฐ˜ํ™˜๋˜๋ฉด stdout ํŒŒ์ดํ•‘์ด ๋™์ž‘ํ•œ ๊ฒƒ
160
+ expect(result).toBe("logged");
161
+ });
162
+ });
163
+
164
+ //#endregion
165
+
166
+ //#region env ์˜ต์…˜
167
+
168
+ describe("env ์˜ต์…˜", () => {
169
+ it("env ์˜ต์…˜์ด ์›Œ์ปค์— ์ „๋‹ฌ", async () => {
170
+ worker = Worker.create<typeof TestWorkerModule>(workerPath, {
171
+ env: {
172
+ TEST_ENV_VAR: "test-value-123",
173
+ },
174
+ });
175
+
176
+ const result = await worker.getEnv("TEST_ENV_VAR");
177
+
178
+ expect(result).toBe("test-value-123");
179
+ });
180
+ });
181
+
182
+ //#endregion
183
+ });