@simplysm/sd-cli 14.0.63 → 14.0.65
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/capacitor/capacitor-android.d.ts +2 -0
- package/dist/capacitor/capacitor-android.d.ts.map +1 -1
- package/dist/capacitor/capacitor-android.js +13 -0
- package/dist/capacitor/capacitor-android.js.map +1 -1
- package/dist/capacitor/capacitor-npm-config.d.ts.map +1 -1
- package/dist/capacitor/capacitor-npm-config.js +2 -6
- package/dist/capacitor/capacitor-npm-config.js.map +1 -1
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +1 -2
- package/dist/electron/electron.js.map +1 -1
- package/package.json +8 -8
- package/src/capacitor/capacitor-android.ts +14 -0
- package/src/capacitor/capacitor-npm-config.ts +2 -6
- package/src/electron/electron.ts +1 -2
- package/tests/angular/ngtsc-build-core.acc.spec.ts +36 -94
- package/tests/capacitor/capacitor-android.spec.ts +65 -28
- package/tests/capacitor/capacitor-build.spec.ts +40 -385
- package/tests/capacitor/capacitor-config-writer.acc.spec.ts +3 -17
- package/tests/capacitor/capacitor-config-writer.spec.ts +3 -17
- package/tests/capacitor/capacitor-init.spec.ts +40 -636
- package/tests/capacitor/capacitor-npm-config.acc.spec.ts +38 -168
- package/tests/capacitor/capacitor-npm-config.spec.ts +33 -71
- package/tests/commands/check.spec.ts +25 -36
- package/tests/commands/deployment-phase.acc.spec.ts +17 -26
- package/tests/commands/git-phase.acc.spec.ts +13 -112
- package/tests/commands/lint.spec.ts +7 -24
- package/tests/commands/post-publish-phase.acc.spec.ts +5 -10
- package/tests/commands/typecheck.spec.ts +43 -65
- package/tests/electron/electron.spec.ts +22 -46
- package/tests/engines/base-engine.spec.ts +4 -13
- package/tests/engines/engine-selection.spec.ts +14 -17
- package/tests/engines/engine-typecheck-selection.acc.spec.ts +13 -16
- package/tests/engines/esbuild-client-engine.acc.spec.ts +36 -40
- package/tests/engines/esbuild-client-engine.spec.ts +4 -23
- package/tests/engines/ngtsc-engine.spec.ts +3 -10
- package/tests/engines/server-esbuild-engine.spec.ts +3 -10
- package/tests/engines/tsc-engine.spec.ts +3 -10
- package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +3 -8
- package/tests/esbuild/esbuild-tsc-plugin.spec.ts +3 -8
- package/tests/orchestrators/build-orchestrator.spec.ts +57 -102
- package/tests/orchestrators/dev-orchestrator.spec.ts +68 -109
- package/tests/orchestrators/typecheck-orchestrator.spec.ts +25 -57
- package/tests/orchestrators/watch-orchestrator.spec.ts +73 -99
- package/tests/sd-cli-entry.spec.ts +17 -20
- package/tests/utils/angular-source-file-cache.spec.ts +4 -8
- package/tests/utils/copy-src.spec.ts +9 -20
- package/tests/utils/esbuild-client-config.acc.spec.ts +9 -15
- package/tests/utils/esbuild-client-config.spec.ts +12 -24
- package/tests/utils/esbuild-config.spec.ts +51 -42
- package/tests/utils/lint-core.spec.ts +13 -19
- package/tests/utils/lint-utils.spec.ts +8 -15
- package/tests/utils/lint-with-program.spec.ts +3 -7
- package/tests/utils/ngtsc-build-core.spec.ts +2 -99
- package/tests/utils/orchestrator-utils.spec.ts +7 -20
- package/tests/utils/output-utils.spec.ts +5 -11
- package/tests/utils/sd-config.spec.ts +4 -12
- package/tests/utils/typecheck-env.spec.ts +49 -77
- package/tests/utils/typecheck-non-package.spec.ts +23 -16
- package/tests/workers/build-watch-paths.acc.spec.ts +4 -10
- package/tests/workers/build-watch-paths.spec.ts +4 -9
- package/tests/workers/client-worker.acc.spec.ts +64 -137
- package/tests/workers/client-worker.spec.ts +63 -89
- package/tests/workers/library-build-lint.spec.ts +19 -30
- package/tests/workers/library-build-worker.spec.ts +28 -55
- package/tests/workers/server-esbuild-context.acc.spec.ts +6 -15
- package/tests/workers/server-esbuild-context.spec.ts +7 -16
- package/tests/workers/server-runtime-worker.spec.ts +8 -10
- package/tests/workers/shared-worker-lifecycle.acc.spec.ts +3 -5
- package/tests/workers/shared-worker-lifecycle.spec.ts +4 -5
- package/tests/capacitor/capacitor-icon.spec.ts +0 -285
- package/tests/capacitor/capacitor-run.spec.ts +0 -256
- package/tests/capacitor/capacitor-workspace.spec.ts +0 -203
- package/tests/commands/device.spec.ts +0 -237
- package/tests/commands/publish.spec.ts +0 -1183
- package/tests/utils/external-modules.spec.ts +0 -217
- package/tests/workers/server-build-lint.spec.ts +0 -201
- package/tests/workers/server-build-worker.spec.ts +0 -765
- package/tests/workers/server-watch-manager.acc.spec.ts +0 -162
- package/tests/workers/server-watch-manager.spec.ts +0 -199
|
@@ -1,144 +1,118 @@
|
|
|
1
|
-
import { describe, it, expect,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const mockReadFileSync = vi.fn<(path: string, encoding: string) => string>();
|
|
6
|
-
vi.mock("fs", () => {
|
|
7
|
-
const fsMock = {
|
|
8
|
-
existsSync: (path: string) => mockExistsSync(path),
|
|
9
|
-
readFileSync: (path: string, encoding: string) => mockReadFileSync(path, encoding),
|
|
10
|
-
};
|
|
11
|
-
return { ...fsMock, default: fsMock };
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
vi.mock("typescript", () => ({
|
|
15
|
-
default: {
|
|
16
|
-
readConfigFile: vi.fn(),
|
|
17
|
-
sys: { readFile: vi.fn() },
|
|
18
|
-
parseJsonConfigFileContent: vi.fn(),
|
|
19
|
-
},
|
|
20
|
-
}));
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
21
5
|
|
|
22
|
-
|
|
6
|
+
import {
|
|
23
7
|
getTypesFromPackageJson,
|
|
24
8
|
getCompilerOptionsForEnv,
|
|
25
9
|
toTypecheckEnvs,
|
|
26
|
-
}
|
|
10
|
+
} from "../../src/utils/tsconfig";
|
|
11
|
+
|
|
12
|
+
let tmpRoot: string;
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
|
|
14
|
+
beforeAll(() => {
|
|
15
|
+
tmpRoot = mkdtempSync(path.join(tmpdir(), "typecheck-env-"));
|
|
30
16
|
});
|
|
31
17
|
|
|
32
|
-
|
|
18
|
+
afterAll(() => {
|
|
19
|
+
rmSync(tmpRoot, { recursive: true, force: true });
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function makePkgDir(devDependencies?: Record<string, string>): string {
|
|
23
|
+
const dir = mkdtempSync(path.join(tmpRoot, "pkg-"));
|
|
24
|
+
if (devDependencies) {
|
|
25
|
+
writeFileSync(path.join(dir, "package.json"), JSON.stringify({ devDependencies }));
|
|
26
|
+
}
|
|
27
|
+
return dir;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function makePkgDirWithJson(json: object): string {
|
|
31
|
+
const dir = mkdtempSync(path.join(tmpRoot, "pkg-"));
|
|
32
|
+
writeFileSync(path.join(dir, "package.json"), JSON.stringify(json));
|
|
33
|
+
return dir;
|
|
34
|
+
}
|
|
33
35
|
|
|
34
36
|
describe("getCompilerOptionsForEnv", () => {
|
|
35
37
|
// Scenario: node env에서 DOM 및 WebWorker lib 제거
|
|
36
38
|
it("removes DOM and WebWorker libs in node env", () => {
|
|
37
|
-
|
|
39
|
+
const pkgDir = makePkgDir(); // package.json 없음
|
|
38
40
|
const base = { lib: ["lib.esnext.d.ts", "lib.dom.d.ts", "lib.dom.iterable.d.ts", "lib.webworker.d.ts"] };
|
|
39
|
-
const result = getCompilerOptionsForEnv(base, "node",
|
|
41
|
+
const result = getCompilerOptionsForEnv(base, "node", pkgDir);
|
|
40
42
|
expect(result.lib).toEqual(["lib.esnext.d.ts"]);
|
|
41
43
|
});
|
|
42
44
|
|
|
43
45
|
// Scenario: node env에서 사용자 커스텀 lib 보존
|
|
44
46
|
it("preserves custom libs in node env", () => {
|
|
45
|
-
|
|
47
|
+
const pkgDir = makePkgDir();
|
|
46
48
|
const base = { lib: ["lib.esnext.d.ts", "lib.webworker.d.ts", "lib.scripthost.d.ts"] };
|
|
47
|
-
const result = getCompilerOptionsForEnv(base, "node",
|
|
49
|
+
const result = getCompilerOptionsForEnv(base, "node", pkgDir);
|
|
48
50
|
expect(result.lib).toEqual(["lib.esnext.d.ts", "lib.scripthost.d.ts"]);
|
|
49
51
|
});
|
|
50
52
|
|
|
51
53
|
// Scenario: browser env에서 lib 변화 없음
|
|
52
54
|
it("does not modify lib in browser env", () => {
|
|
53
|
-
|
|
55
|
+
const pkgDir = makePkgDir();
|
|
54
56
|
const base = { lib: ["lib.esnext.d.ts", "lib.webworker.d.ts"] };
|
|
55
|
-
const result = getCompilerOptionsForEnv(base, "browser",
|
|
57
|
+
const result = getCompilerOptionsForEnv(base, "browser", pkgDir);
|
|
56
58
|
expect(result.lib).toEqual(["lib.esnext.d.ts", "lib.webworker.d.ts"]);
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
// Scenario: node env에서 types 변화 없음
|
|
60
62
|
it("does not set types in node env", () => {
|
|
61
|
-
|
|
63
|
+
const pkgDir = makePkgDir();
|
|
62
64
|
const base = { lib: ["lib.esnext.d.ts"] };
|
|
63
|
-
const result = getCompilerOptionsForEnv(base, "node",
|
|
65
|
+
const result = getCompilerOptionsForEnv(base, "node", pkgDir);
|
|
64
66
|
expect(result.types).toBeUndefined();
|
|
65
67
|
});
|
|
66
68
|
|
|
67
69
|
// Scenario: browser env에서 @types/node 제거
|
|
68
70
|
it("removes @types/node in browser env via devDeps", () => {
|
|
69
|
-
|
|
70
|
-
mockReadFileSync.mockReturnValue(
|
|
71
|
-
JSON.stringify({ devDependencies: { "@types/node": "^20", "@types/ws": "^8" } }),
|
|
72
|
-
);
|
|
71
|
+
const pkgDir = makePkgDir({ "@types/node": "^20", "@types/ws": "^8" });
|
|
73
72
|
const base = { lib: ["lib.esnext.d.ts"] };
|
|
74
|
-
const result = getCompilerOptionsForEnv(base, "browser",
|
|
73
|
+
const result = getCompilerOptionsForEnv(base, "browser", pkgDir);
|
|
75
74
|
expect(result.types).toEqual(["ws"]);
|
|
76
75
|
});
|
|
77
76
|
|
|
78
77
|
// Scenario: browser env에서 @types/node만 있는 경우
|
|
79
78
|
it("returns empty types when only @types/node in browser env", () => {
|
|
80
|
-
|
|
81
|
-
mockReadFileSync.mockReturnValue(
|
|
82
|
-
JSON.stringify({ devDependencies: { "@types/node": "^20" } }),
|
|
83
|
-
);
|
|
79
|
+
const pkgDir = makePkgDir({ "@types/node": "^20" });
|
|
84
80
|
const base = { lib: ["lib.esnext.d.ts"] };
|
|
85
|
-
const result = getCompilerOptionsForEnv(base, "browser",
|
|
81
|
+
const result = getCompilerOptionsForEnv(base, "browser", pkgDir);
|
|
86
82
|
expect(result.types).toEqual([]);
|
|
87
83
|
});
|
|
88
84
|
|
|
89
85
|
// Scenario: browser env에서 @types가 없는 경우
|
|
90
86
|
it("returns empty types when no @types in browser env", () => {
|
|
91
|
-
|
|
92
|
-
mockReadFileSync.mockReturnValue(
|
|
93
|
-
JSON.stringify({ devDependencies: { vitest: "^1" } }),
|
|
94
|
-
);
|
|
87
|
+
const pkgDir = makePkgDir({ vitest: "^1" });
|
|
95
88
|
const base = { lib: ["lib.esnext.d.ts"] };
|
|
96
|
-
const result = getCompilerOptionsForEnv(base, "browser",
|
|
89
|
+
const result = getCompilerOptionsForEnv(base, "browser", pkgDir);
|
|
97
90
|
expect(result.types).toEqual([]);
|
|
98
91
|
});
|
|
99
92
|
});
|
|
100
93
|
|
|
101
|
-
//#endregion
|
|
102
|
-
|
|
103
|
-
//#region Unit Tests — getTypesFromPackageJson
|
|
104
|
-
|
|
105
94
|
describe("getTypesFromPackageJson", () => {
|
|
106
95
|
it("extracts @types packages from devDependencies", () => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
JSON.stringify({
|
|
110
|
-
devDependencies: { "@types/node": "^20", "@types/ws": "^8", "vitest": "^1" },
|
|
111
|
-
}),
|
|
112
|
-
);
|
|
113
|
-
expect(getTypesFromPackageJson("/pkg")).toEqual(["node", "ws"]);
|
|
96
|
+
const pkgDir = makePkgDir({ "@types/node": "^20", "@types/ws": "^8", "vitest": "^1" });
|
|
97
|
+
expect(getTypesFromPackageJson(pkgDir)).toEqual(["node", "ws"]);
|
|
114
98
|
});
|
|
115
99
|
|
|
116
100
|
it("returns empty array when package.json does not exist", () => {
|
|
117
|
-
|
|
118
|
-
expect(getTypesFromPackageJson(
|
|
101
|
+
const pkgDir = mkdtempSync(path.join(tmpRoot, "pkg-empty-"));
|
|
102
|
+
expect(getTypesFromPackageJson(pkgDir)).toEqual([]);
|
|
119
103
|
});
|
|
120
104
|
|
|
121
105
|
it("returns empty array when no devDependencies", () => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
expect(getTypesFromPackageJson("/pkg")).toEqual([]);
|
|
106
|
+
const pkgDir = makePkgDirWithJson({ name: "test" });
|
|
107
|
+
expect(getTypesFromPackageJson(pkgDir)).toEqual([]);
|
|
125
108
|
});
|
|
126
109
|
|
|
127
110
|
it("handles scoped @types packages", () => {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
JSON.stringify({
|
|
131
|
-
devDependencies: { "@types/ssh2-sftp-client": "^9" },
|
|
132
|
-
}),
|
|
133
|
-
);
|
|
134
|
-
expect(getTypesFromPackageJson("/pkg")).toEqual(["ssh2-sftp-client"]);
|
|
111
|
+
const pkgDir = makePkgDir({ "@types/ssh2-sftp-client": "^9" });
|
|
112
|
+
expect(getTypesFromPackageJson(pkgDir)).toEqual(["ssh2-sftp-client"]);
|
|
135
113
|
});
|
|
136
114
|
});
|
|
137
115
|
|
|
138
|
-
//#endregion
|
|
139
|
-
|
|
140
|
-
//#region Unit Tests — toTypecheckEnvs
|
|
141
|
-
|
|
142
116
|
describe("toTypecheckEnvs", () => {
|
|
143
117
|
it("returns ['node'] for node target", () => {
|
|
144
118
|
expect(toTypecheckEnvs("node")).toEqual(["node"]);
|
|
@@ -164,5 +138,3 @@ describe("toTypecheckEnvs", () => {
|
|
|
164
138
|
expect(toTypecheckEnvs(undefined)).toEqual(["node", "browser"]);
|
|
165
139
|
});
|
|
166
140
|
});
|
|
167
|
-
|
|
168
|
-
//#endregion
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
// typescript default export는 ESM에서 spyOn 불가 (Cannot redefine property) — vi.mock 유지
|
|
4
|
+
const tsMocks = vi.hoisted(() => ({
|
|
5
5
|
createIncrementalCompilerHost: vi.fn(),
|
|
6
6
|
createIncrementalProgram: vi.fn(),
|
|
7
|
-
serializeDiagnostic: vi.fn((d: any) => d),
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
vi.mock("../../src/utils/tsconfig", () => ({
|
|
11
|
-
parseTsconfig: mocks.parseTsconfig,
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
vi.mock("../../src/typecheck/typecheck-serialization", () => ({
|
|
15
|
-
serializeDiagnostic: mocks.serializeDiagnostic,
|
|
16
7
|
}));
|
|
17
8
|
|
|
18
9
|
vi.mock("typescript", async (importOriginal) => {
|
|
@@ -22,18 +13,34 @@ vi.mock("typescript", async (importOriginal) => {
|
|
|
22
13
|
...orig,
|
|
23
14
|
default: {
|
|
24
15
|
...origDefault,
|
|
25
|
-
createIncrementalCompilerHost:
|
|
26
|
-
createIncrementalProgram:
|
|
16
|
+
createIncrementalCompilerHost: tsMocks.createIncrementalCompilerHost,
|
|
17
|
+
createIncrementalProgram: tsMocks.createIncrementalProgram,
|
|
27
18
|
DiagnosticCategory: { Error: 1, Warning: 0 },
|
|
28
19
|
},
|
|
29
20
|
};
|
|
30
21
|
});
|
|
31
22
|
|
|
32
|
-
|
|
23
|
+
import * as tsconfigMod from "../../src/utils/tsconfig";
|
|
24
|
+
import * as typecheckSerializationMod from "../../src/typecheck/typecheck-serialization";
|
|
25
|
+
|
|
26
|
+
import { typecheckNonPackageFiles } from "../../src/typecheck/typecheck-non-package";
|
|
27
|
+
|
|
28
|
+
const mocks = {
|
|
29
|
+
parseTsconfig: undefined as unknown as ReturnType<typeof vi.spyOn>,
|
|
30
|
+
createIncrementalCompilerHost: tsMocks.createIncrementalCompilerHost,
|
|
31
|
+
createIncrementalProgram: tsMocks.createIncrementalProgram,
|
|
32
|
+
serializeDiagnostic: undefined as unknown as ReturnType<typeof vi.spyOn>,
|
|
33
|
+
};
|
|
33
34
|
|
|
34
35
|
describe("typecheckNonPackageFiles", () => {
|
|
35
36
|
beforeEach(() => {
|
|
36
|
-
vi.
|
|
37
|
+
vi.restoreAllMocks();
|
|
38
|
+
|
|
39
|
+
mocks.parseTsconfig = vi.spyOn(tsconfigMod, "parseTsconfig");
|
|
40
|
+
mocks.serializeDiagnostic = vi.spyOn(typecheckSerializationMod, "serializeDiagnostic")
|
|
41
|
+
.mockImplementation((d: any) => d);
|
|
42
|
+
mocks.createIncrementalCompilerHost.mockReset();
|
|
43
|
+
mocks.createIncrementalProgram.mockReset();
|
|
37
44
|
|
|
38
45
|
mocks.parseTsconfig.mockReturnValue({
|
|
39
46
|
fileNames: [
|
|
@@ -45,7 +52,7 @@ describe("typecheckNonPackageFiles", () => {
|
|
|
45
52
|
errors: [],
|
|
46
53
|
});
|
|
47
54
|
|
|
48
|
-
mocks.createIncrementalCompilerHost.mockReturnValue({});
|
|
55
|
+
mocks.createIncrementalCompilerHost.mockReturnValue({} as any);
|
|
49
56
|
|
|
50
57
|
const mockProgram = {
|
|
51
58
|
emit: vi.fn(() => ({ diagnostics: [] })),
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import * as collectDepsMod from "../../src/deps/replace-deps/collect-deps";
|
|
3
|
+
import { buildWatchPaths } from "../../src/workers/build-watch-paths";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
vi.mock("../../src/deps/replace-deps/collect-deps", () => ({
|
|
5
|
-
collectDeps: vi.fn(),
|
|
6
|
-
}));
|
|
7
|
-
|
|
8
|
-
const { collectDeps } = await import("../../src/deps/replace-deps/collect-deps");
|
|
9
|
-
const { buildWatchPaths } = await import("../../src/workers/build-watch-paths");
|
|
10
|
-
|
|
11
|
-
const mockCollectDeps = vi.mocked(collectDeps);
|
|
5
|
+
const mockCollectDeps = vi.spyOn(collectDepsMod, "collectDeps");
|
|
12
6
|
|
|
13
7
|
beforeEach(() => {
|
|
14
|
-
|
|
8
|
+
mockCollectDeps.mockReset();
|
|
15
9
|
});
|
|
16
10
|
|
|
17
11
|
describe("buildWatchPaths", () => {
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import * as collectDepsMod from "../../src/deps/replace-deps/collect-deps";
|
|
3
|
+
import { buildWatchPaths } from "../../src/workers/build-watch-paths";
|
|
2
4
|
|
|
3
|
-
vi.
|
|
4
|
-
collectDeps: vi.fn(),
|
|
5
|
-
}));
|
|
6
|
-
|
|
7
|
-
const { collectDeps } = await import("../../src/deps/replace-deps/collect-deps");
|
|
8
|
-
const { buildWatchPaths } = await import("../../src/workers/build-watch-paths");
|
|
9
|
-
|
|
10
|
-
const mockCollectDeps = vi.mocked(collectDeps);
|
|
5
|
+
const mockCollectDeps = vi.spyOn(collectDepsMod, "collectDeps");
|
|
11
6
|
|
|
12
7
|
beforeEach(() => {
|
|
13
|
-
|
|
8
|
+
mockCollectDeps.mockReset();
|
|
14
9
|
});
|
|
15
10
|
|
|
16
11
|
describe("buildWatchPaths", () => {
|
|
@@ -1,105 +1,78 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { describe, it, expect, vi, beforeAll, afterAll, beforeEach } from "vitest";
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
import * as coreNode from "@simplysm/core-node";
|
|
7
|
+
import * as sharedWorkerLifecycle from "../../src/workers/shared-worker-lifecycle";
|
|
8
|
+
import * as esbuildClientConfig from "../../src/esbuild/esbuild-client-config";
|
|
9
|
+
import * as esbuildIndexHtml from "../../src/esbuild/esbuild-index-html";
|
|
10
|
+
import * as esbuildPwa from "../../src/esbuild/esbuild-pwa";
|
|
11
|
+
import * as devHttpServer from "../../src/dev-server/dev-http-server";
|
|
12
|
+
import * as hmrService from "../../src/dev-server/hmr-service";
|
|
13
|
+
import * as hmrClientScript from "../../src/dev-server/hmr-client-script";
|
|
14
|
+
import * as copyPublic from "../../src/utils/copy-public";
|
|
15
|
+
import * as sdConfig from "../../src/utils/sd-config";
|
|
4
16
|
|
|
5
17
|
let workerFns: Record<string, (...args: any[]) => any>;
|
|
6
18
|
let mockSend: ReturnType<typeof vi.fn>;
|
|
7
19
|
|
|
8
20
|
const mockRebuild = vi.fn();
|
|
9
21
|
const mockDispose = vi.fn();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
vi.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
createPwaHtmlTransform: vi.fn(),
|
|
46
|
-
}));
|
|
47
|
-
|
|
48
|
-
vi.mock("../../src/dev-server/dev-http-server", () => ({
|
|
49
|
-
createDevHttpServer: vi.fn(),
|
|
50
|
-
}));
|
|
51
|
-
|
|
52
|
-
vi.mock("../../src/dev-server/hmr-service", () => ({
|
|
53
|
-
createHmrService: vi.fn(),
|
|
54
|
-
}));
|
|
55
|
-
|
|
56
|
-
vi.mock("../../src/dev-server/hmr-client-script", () => ({
|
|
57
|
-
createHmrPostTransform: vi.fn(),
|
|
58
|
-
}));
|
|
59
|
-
|
|
60
|
-
vi.mock("../../src/utils/copy-public", () => ({
|
|
61
|
-
copyPublicFiles: vi.fn(() => Promise.resolve()),
|
|
62
|
-
watchPublicFiles: vi.fn(),
|
|
63
|
-
}));
|
|
64
|
-
|
|
65
|
-
vi.mock("../../src/utils/sd-config", () => ({
|
|
66
|
-
loadSdConfig: vi.fn(() =>
|
|
67
|
-
Promise.resolve({
|
|
68
|
-
packages: { "my-app": { target: "client", server: "my-server" } },
|
|
69
|
-
}),
|
|
70
|
-
),
|
|
71
|
-
}));
|
|
72
|
-
|
|
73
|
-
vi.mock("node:fs", () => ({
|
|
74
|
-
default: {
|
|
75
|
-
readFileSync: (...args: any[]) => mockReadFileSync(...args),
|
|
76
|
-
writeFileSync: vi.fn(),
|
|
77
|
-
existsSync: (...args: any[]) => mockExistsSync(...args),
|
|
78
|
-
mkdirSync: vi.fn(),
|
|
79
|
-
rmSync: vi.fn(),
|
|
80
|
-
},
|
|
81
|
-
}));
|
|
82
|
-
|
|
83
|
-
//#endregion
|
|
84
|
-
|
|
85
|
-
// Import triggers createWorker, capturing the functions
|
|
22
|
+
|
|
23
|
+
vi.spyOn(coreNode, "createWorker").mockImplementation((fns: Record<string, Function>) => {
|
|
24
|
+
workerFns = fns as any;
|
|
25
|
+
mockSend = vi.fn();
|
|
26
|
+
return { send: mockSend } as any;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
vi.spyOn(sharedWorkerLifecycle, "setupWorkerLifecycle").mockImplementation(() => ({
|
|
30
|
+
logger: { debug: vi.fn(), error: vi.fn(), warn: vi.fn() },
|
|
31
|
+
guardStartWatch: vi.fn(),
|
|
32
|
+
}) as any);
|
|
33
|
+
|
|
34
|
+
vi.spyOn(esbuildClientConfig, "createClientEsbuildContext").mockResolvedValue({
|
|
35
|
+
context: { rebuild: mockRebuild, dispose: mockDispose, watch: vi.fn() },
|
|
36
|
+
sourceFileCache: {},
|
|
37
|
+
} as any);
|
|
38
|
+
|
|
39
|
+
vi.spyOn(esbuildIndexHtml, "generateIndexHtml").mockResolvedValue({
|
|
40
|
+
content: "<html></html>", errors: [], warnings: [],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
vi.spyOn(esbuildPwa, "applyPwa").mockResolvedValue(undefined);
|
|
44
|
+
vi.spyOn(esbuildPwa, "createPwaHtmlTransform").mockReturnValue(undefined as any);
|
|
45
|
+
|
|
46
|
+
vi.spyOn(devHttpServer, "createDevHttpServer").mockReturnValue(undefined as any);
|
|
47
|
+
vi.spyOn(hmrService, "createHmrService").mockReturnValue(undefined as any);
|
|
48
|
+
vi.spyOn(hmrClientScript, "createHmrPostTransform").mockReturnValue(undefined as any);
|
|
49
|
+
|
|
50
|
+
vi.spyOn(copyPublic, "copyPublicFiles").mockResolvedValue(undefined);
|
|
51
|
+
vi.spyOn(copyPublic, "watchPublicFiles").mockReturnValue(undefined as any);
|
|
52
|
+
|
|
53
|
+
vi.spyOn(sdConfig, "loadSdConfig").mockResolvedValue({
|
|
54
|
+
packages: { "my-app": { target: "client", server: "my-server" } },
|
|
55
|
+
} as any);
|
|
56
|
+
|
|
86
57
|
await import("../../src/workers/client.worker");
|
|
87
58
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
59
|
+
let tmpRoot: string;
|
|
60
|
+
let baseBuildInfo: { name: string; cwd: string; pkgDir: string };
|
|
61
|
+
|
|
62
|
+
beforeAll(() => {
|
|
63
|
+
tmpRoot = mkdtempSync(path.join(tmpdir(), "client-worker-acc-"));
|
|
64
|
+
const pkgDir = path.join(tmpRoot, "packages", "my-app");
|
|
65
|
+
mkdirSync(pkgDir, { recursive: true });
|
|
66
|
+
writeFileSync(path.join(pkgDir, "package.json"), JSON.stringify({ name: "@scope/my-app" }));
|
|
67
|
+
baseBuildInfo = { name: "my-app", cwd: tmpRoot, pkgDir };
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterAll(() => {
|
|
71
|
+
rmSync(tmpRoot, { recursive: true, force: true });
|
|
72
|
+
});
|
|
93
73
|
|
|
94
74
|
beforeEach(() => {
|
|
95
75
|
vi.clearAllMocks();
|
|
96
|
-
mockReadFileSync.mockImplementation((filePath: any) => {
|
|
97
|
-
if (String(filePath).endsWith("package.json")) {
|
|
98
|
-
return JSON.stringify({ name: "@scope/my-app" });
|
|
99
|
-
}
|
|
100
|
-
return "";
|
|
101
|
-
});
|
|
102
|
-
mockExistsSync.mockReturnValue(false);
|
|
103
76
|
mockRebuild.mockResolvedValue({
|
|
104
77
|
metafile: { outputs: {} },
|
|
105
78
|
errors: [],
|
|
@@ -140,49 +113,3 @@ describe("client.worker build() — Acceptance", () => {
|
|
|
140
113
|
expect(result.errors).toContain("Unexpected crash");
|
|
141
114
|
});
|
|
142
115
|
});
|
|
143
|
-
|
|
144
|
-
describe("client.worker build() — browserSupport 전달", () => {
|
|
145
|
-
// Scenario: browserSupport가 ClientBuildInfo를 통해 전달된다
|
|
146
|
-
it("browserSupport 설정이 createClientEsbuildContext에 legacyModule/browserslist/postcssPlugins로 전달된다", async () => {
|
|
147
|
-
const { createClientEsbuildContext } = await import(
|
|
148
|
-
"../../src/esbuild/esbuild-client-config"
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const result = await workerFns["build"]({
|
|
152
|
-
...baseBuildInfo,
|
|
153
|
-
browserSupport: {
|
|
154
|
-
legacyModule: true,
|
|
155
|
-
browserslist: "Chrome 61",
|
|
156
|
-
postCss: { plugins: [["autoprefixer"]] },
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
expect(result.success).toBe(true);
|
|
161
|
-
expect(vi.mocked(createClientEsbuildContext)).toHaveBeenCalledWith(
|
|
162
|
-
expect.objectContaining({
|
|
163
|
-
legacyModule: true,
|
|
164
|
-
browserslist: "Chrome 61",
|
|
165
|
-
postcssPlugins: [["autoprefixer"]],
|
|
166
|
-
}),
|
|
167
|
-
);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Scenario: browserSupport 미설정 시 기본값으로 동작한다
|
|
171
|
-
it("browserSupport 미설정 시 legacyModule=false, browserslist=undefined로 전달된다", async () => {
|
|
172
|
-
const { createClientEsbuildContext } = await import(
|
|
173
|
-
"../../src/esbuild/esbuild-client-config"
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const result = await workerFns["build"](baseBuildInfo);
|
|
177
|
-
|
|
178
|
-
expect(result.success).toBe(true);
|
|
179
|
-
expect(vi.mocked(createClientEsbuildContext)).toHaveBeenCalledWith(
|
|
180
|
-
expect.objectContaining({
|
|
181
|
-
legacyModule: false,
|
|
182
|
-
browserslist: undefined,
|
|
183
|
-
postcssPlugins: undefined,
|
|
184
|
-
}),
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
|