@simplysm/sd-cli 14.0.42 → 14.0.44
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/angular/angular-compiler.d.ts +0 -35
- package/dist/angular/angular-compiler.d.ts.map +1 -1
- package/dist/angular/angular-compiler.js +0 -374
- package/dist/angular/angular-compiler.js.map +1 -1
- package/dist/angular/hmr-candidates.d.ts +13 -0
- package/dist/angular/hmr-candidates.d.ts.map +1 -0
- package/dist/angular/hmr-candidates.js +230 -0
- package/dist/angular/hmr-candidates.js.map +1 -0
- package/dist/angular/ngtsc-build-core.d.ts +41 -37
- package/dist/angular/ngtsc-build-core.d.ts.map +1 -1
- package/dist/angular/ngtsc-build-core.js +155 -52
- package/dist/angular/ngtsc-build-core.js.map +1 -1
- package/dist/angular/vite-angular-plugin.d.ts +1 -1
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +63 -56
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/angular/web-worker-transformer.d.ts +9 -0
- package/dist/angular/web-worker-transformer.d.ts.map +1 -0
- package/dist/angular/web-worker-transformer.js +73 -0
- package/dist/angular/web-worker-transformer.js.map +1 -0
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +6 -4
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/check.d.ts +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +15 -65
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/publish/deployment-phase.d.ts.map +1 -1
- package/dist/commands/publish/deployment-phase.js +13 -5
- package/dist/commands/publish/deployment-phase.js.map +1 -1
- package/dist/commands/publish/npm-publisher.js +1 -1
- package/dist/commands/publish/npm-publisher.js.map +1 -1
- package/dist/commands/publish/publish-command.js +1 -1
- package/dist/commands/publish/publish-command.js.map +1 -1
- package/dist/commands/publish/version-upgrade.d.ts.map +1 -1
- package/dist/commands/publish/version-upgrade.js +16 -13
- package/dist/commands/publish/version-upgrade.js.map +1 -1
- package/dist/commands/replace-deps.d.ts.map +1 -1
- package/dist/commands/replace-deps.js +2 -1
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/deps/replace-deps/collect-deps.d.ts.map +1 -1
- package/dist/deps/replace-deps/collect-deps.js +5 -2
- package/dist/deps/replace-deps/collect-deps.js.map +1 -1
- package/dist/deps/replace-deps/replace-deps-resolve.d.ts.map +1 -1
- package/dist/deps/replace-deps/replace-deps-resolve.js +6 -7
- package/dist/deps/replace-deps/replace-deps-resolve.js.map +1 -1
- package/dist/deps/replace-deps/replace-deps.d.ts +21 -3
- package/dist/deps/replace-deps/replace-deps.d.ts.map +1 -1
- package/dist/deps/replace-deps/replace-deps.js +175 -66
- package/dist/deps/replace-deps/replace-deps.js.map +1 -1
- package/dist/electron/electron.js +7 -7
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +2 -5
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
- package/dist/engines/EsbuildClientEngine.js +16 -9
- package/dist/engines/EsbuildClientEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.d.ts +4 -4
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +5 -5
- package/dist/engines/NgtscEngine.js.map +1 -1
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +0 -2
- package/dist/engines/TscEngine.js.map +1 -1
- package/dist/engines/types.d.ts +2 -0
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts +36 -0
- package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts.map +1 -0
- package/dist/esbuild/esbuild-angular-compiler-plugin.js +464 -0
- package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -0
- package/dist/esbuild/esbuild-client-config.d.ts +8 -2
- package/dist/esbuild/esbuild-client-config.d.ts.map +1 -1
- package/dist/esbuild/esbuild-client-config.js +48 -33
- package/dist/esbuild/esbuild-client-config.js.map +1 -1
- package/dist/esbuild/esbuild-postcss-plugin.d.ts.map +1 -1
- package/dist/esbuild/esbuild-postcss-plugin.js +9 -6
- package/dist/esbuild/esbuild-postcss-plugin.js.map +1 -1
- package/dist/esbuild/esbuild-tsc-plugin.d.ts +4 -1
- package/dist/esbuild/esbuild-tsc-plugin.d.ts.map +1 -1
- package/dist/esbuild/esbuild-tsc-plugin.js +27 -23
- package/dist/esbuild/esbuild-tsc-plugin.js.map +1 -1
- package/dist/esbuild/file-reference-tracker.d.ts +24 -0
- package/dist/esbuild/file-reference-tracker.d.ts.map +1 -0
- package/dist/esbuild/file-reference-tracker.js +57 -0
- package/dist/esbuild/file-reference-tracker.js.map +1 -0
- package/dist/esbuild/lmdb-cache-store.d.ts +18 -0
- package/dist/esbuild/lmdb-cache-store.d.ts.map +1 -0
- package/dist/esbuild/lmdb-cache-store.js +41 -0
- package/dist/esbuild/lmdb-cache-store.js.map +1 -0
- package/dist/esbuild/load-result-cache.d.ts +17 -0
- package/dist/esbuild/load-result-cache.d.ts.map +1 -0
- package/dist/esbuild/load-result-cache.js +61 -0
- package/dist/esbuild/load-result-cache.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lint/lint-core.js +7 -7
- package/dist/lint/lint-core.js.map +1 -1
- package/dist/orchestrators/BaseOrchestrator.js +2 -2
- package/dist/orchestrators/BaseOrchestrator.js.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +5 -19
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevOrchestrator.js +5 -5
- package/dist/orchestrators/DevOrchestrator.js.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.js +6 -6
- package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
- package/dist/runtime/ResultCollector.d.ts +1 -0
- package/dist/runtime/ResultCollector.d.ts.map +1 -1
- package/dist/runtime/ResultCollector.js.map +1 -1
- package/dist/runtime/engine-watch-events.d.ts.map +1 -1
- package/dist/runtime/engine-watch-events.js +3 -0
- package/dist/runtime/engine-watch-events.js.map +1 -1
- package/dist/runtime/rebuild-manager.js +1 -1
- package/dist/runtime/rebuild-manager.js.map +1 -1
- package/dist/runtime/worker-utils.js +1 -1
- package/dist/runtime/worker-utils.js.map +1 -1
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +4 -3
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.js +3 -3
- package/dist/sd-cli.js.map +1 -1
- package/dist/ts-compiler/SdTsCompiler.d.ts +39 -0
- package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -0
- package/dist/ts-compiler/SdTsCompiler.js +593 -0
- package/dist/ts-compiler/SdTsCompiler.js.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-options.d.ts +40 -0
- package/dist/ts-compiler/sd-ts-compiler-options.d.ts.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-options.js +2 -0
- package/dist/ts-compiler/sd-ts-compiler-options.js.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-result.d.ts +34 -0
- package/dist/ts-compiler/sd-ts-compiler-result.d.ts.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-result.js +2 -0
- package/dist/ts-compiler/sd-ts-compiler-result.js.map +1 -0
- package/dist/utils/copy-public.d.ts +6 -4
- package/dist/utils/copy-public.d.ts.map +1 -1
- package/dist/utils/copy-public.js +9 -7
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/diagnostic-utils.d.ts +2 -3
- package/dist/utils/diagnostic-utils.d.ts.map +1 -1
- package/dist/utils/diagnostic-utils.js +8 -9
- package/dist/utils/diagnostic-utils.js.map +1 -1
- package/dist/utils/output-utils.d.ts +8 -2
- package/dist/utils/output-utils.d.ts.map +1 -1
- package/dist/utils/output-utils.js +32 -8
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/workers/client.worker.d.ts +1 -1
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +115 -110
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/incremental-mtime-tracker.d.ts +13 -0
- package/dist/workers/incremental-mtime-tracker.d.ts.map +1 -0
- package/dist/workers/incremental-mtime-tracker.js +65 -0
- package/dist/workers/incremental-mtime-tracker.js.map +1 -0
- package/dist/workers/library-build.worker.d.ts +0 -2
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +169 -70
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +30 -57
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-esbuild-context.d.ts +7 -0
- package/dist/workers/server-esbuild-context.d.ts.map +1 -1
- package/dist/workers/server-esbuild-context.js +11 -2
- package/dist/workers/server-esbuild-context.js.map +1 -1
- package/package.json +5 -4
- package/src/angular/angular-compiler.ts +0 -502
- package/src/angular/hmr-candidates.ts +295 -0
- package/src/angular/ngtsc-build-core.ts +192 -91
- package/src/angular/vite-angular-plugin.ts +71 -65
- package/src/angular/web-worker-transformer.ts +117 -0
- package/src/capacitor/capacitor.ts +6 -4
- package/src/commands/check.ts +17 -76
- package/src/commands/publish/deployment-phase.ts +11 -7
- package/src/commands/publish/npm-publisher.ts +1 -1
- package/src/commands/publish/publish-command.ts +1 -1
- package/src/commands/publish/version-upgrade.ts +44 -35
- package/src/commands/replace-deps.ts +3 -1
- package/src/deps/replace-deps/collect-deps.ts +4 -2
- package/src/deps/replace-deps/replace-deps-resolve.ts +12 -7
- package/src/deps/replace-deps/replace-deps.ts +191 -69
- package/src/electron/electron.ts +7 -7
- package/src/engines/BaseEngine.ts +2 -6
- package/src/engines/EsbuildClientEngine.ts +16 -10
- package/src/engines/NgtscEngine.ts +7 -7
- package/src/engines/TscEngine.ts +0 -2
- package/src/engines/types.ts +2 -0
- package/src/esbuild/esbuild-angular-compiler-plugin.ts +647 -0
- package/src/esbuild/esbuild-client-config.ts +57 -41
- package/src/esbuild/esbuild-postcss-plugin.ts +9 -6
- package/src/esbuild/esbuild-tsc-plugin.ts +33 -23
- package/src/esbuild/file-reference-tracker.ts +61 -0
- package/src/esbuild/lmdb-cache-store.ts +46 -0
- package/src/esbuild/load-result-cache.ts +85 -0
- package/src/index.ts +5 -0
- package/src/lint/lint-core.ts +7 -7
- package/src/orchestrators/BaseOrchestrator.ts +2 -2
- package/src/orchestrators/BuildOrchestrator.ts +5 -24
- package/src/orchestrators/DevOrchestrator.ts +5 -5
- package/src/orchestrators/WatchOrchestrator.ts +6 -6
- package/src/runtime/ResultCollector.ts +1 -0
- package/src/runtime/engine-watch-events.ts +3 -0
- package/src/runtime/rebuild-manager.ts +1 -1
- package/src/runtime/worker-utils.ts +1 -1
- package/src/sd-cli-entry.ts +5 -3
- package/src/sd-cli.ts +4 -4
- package/src/ts-compiler/SdTsCompiler.ts +815 -0
- package/src/ts-compiler/sd-ts-compiler-options.ts +46 -0
- package/src/ts-compiler/sd-ts-compiler-result.ts +34 -0
- package/src/utils/copy-public.ts +9 -6
- package/src/utils/diagnostic-utils.ts +8 -9
- package/src/utils/output-utils.ts +38 -8
- package/src/workers/client.worker.ts +141 -126
- package/src/workers/incremental-mtime-tracker.ts +68 -0
- package/src/workers/library-build.worker.ts +214 -75
- package/src/workers/server-build.worker.ts +31 -61
- package/src/workers/server-esbuild-context.ts +14 -2
- package/tests/angular/fixtures/packages/basic-app/dist/styles.css +3 -0
- package/tests/angular/fixtures/packages/basic-app/scss/styles.scss +5 -0
- package/tests/angular/ngtsc-build-core.acc.spec.ts +210 -0
- package/tests/angular/ngtsc-build-core.spec.ts +52 -0
- package/tests/angular/vite-angular-plugin-sdtscompiler.verify.md +13 -0
- package/tests/angular/web-worker-transformer.spec.ts +154 -0
- package/tests/capacitor/capacitor-build.spec.ts +1 -1
- package/tests/capacitor/capacitor-icon.spec.ts +1 -1
- package/tests/capacitor/capacitor-init.spec.ts +1 -1
- package/tests/commands/check.spec.ts +90 -104
- package/tests/commands/publish.spec.ts +12 -4
- package/tests/commands/slice3-severity-cleanup.verify.md +12 -0
- package/tests/commands/version-upgrade.acc.spec.ts +210 -0
- package/tests/commands/version-upgrade.spec.ts +148 -0
- package/tests/deps/replace-deps/collect-deps.acc.spec.ts +62 -0
- package/tests/deps/replace-deps/collect-deps.spec.ts +49 -0
- package/tests/deps/replace-deps/replace-deps-filter.spec.ts +103 -0
- package/tests/deps/replace-deps/replace-deps-perf.verify.md +15 -0
- package/tests/deps/replace-deps/replace-deps-resolve.acc.spec.ts +124 -0
- package/tests/deps/replace-deps/replace-deps-setup.acc.spec.ts +156 -0
- package/tests/electron/electron.spec.ts +4 -1
- package/tests/engines/engine-adapter-isolation.spec.ts +5 -6
- package/tests/engines/engine-duplicate-output-removal.verify.md +10 -0
- package/tests/engines/esbuild-client-engine.acc.spec.ts +79 -0
- package/tests/engines/esbuild-client-engine.spec.ts +73 -3
- package/tests/esbuild/esbuild-angular-compiler-plugin-hmr.verify.md +23 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-onload.verify.md +21 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-onstart-extraction.verify.md +16 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-sdtscompiler.verify.md +15 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-stylesheet.verify.md +31 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +31 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin.spec.ts +397 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin.verify.md +21 -0
- package/tests/esbuild/esbuild-postcss-plugin-chunking.verify.md +17 -0
- package/tests/esbuild/esbuild-postcss-plugin.acc.spec.ts +152 -0
- package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +13 -0
- package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +56 -111
- package/tests/esbuild/esbuild-tsc-plugin.spec.ts +116 -52
- package/tests/esbuild/file-reference-tracker.spec.ts +99 -0
- package/tests/esbuild/lmdb-cache-store.spec.ts +58 -0
- package/tests/esbuild/load-result-cache.acc.spec.ts +55 -0
- package/tests/esbuild/load-result-cache.spec.ts +133 -0
- package/tests/orchestrators/build-orchestrator.spec.ts +4 -3
- package/tests/orchestrators/dev-orchestrator.spec.ts +5 -5
- package/tests/orchestrators/slice1-stdout-to-consola.verify.md +10 -0
- package/tests/orchestrators/typecheck-orchestrator.spec.ts +1 -1
- package/tests/orchestrators/watch-orchestrator.spec.ts +7 -7
- package/tests/runtime/result-collector.spec.ts +64 -0
- package/tests/sd-cli-entry.spec.ts +3 -4
- package/tests/sd-cli-log-tag.verify.md +11 -0
- package/tests/ts-compiler/SdTsCompiler-affected-files.verify.md +8 -0
- package/tests/ts-compiler/SdTsCompiler-diagnostics.verify.md +12 -0
- package/tests/ts-compiler/SdTsCompiler-emit.verify.md +9 -0
- package/tests/ts-compiler/SdTsCompiler.acc.spec.ts +603 -0
- package/tests/ts-compiler/SdTsCompiler.spec.ts +265 -0
- package/tests/ts-compiler/SdTsCompiler.verify.md +41 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-browser.tsbuildinfo +1 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-node.tsbuildinfo +1 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck.tsbuildinfo +1 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/src/index.ts +3 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/src/util.ts +3 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/tests/sample.test-file.ts +3 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/tsconfig.json +12 -0
- package/tests/ts-compiler/scss-lint-integration.verify.md +14 -0
- package/tests/utils/angular-build.spec.ts +1 -1
- package/tests/utils/copy-public-outdir.verify.md +8 -0
- package/tests/utils/copy-public.acc.spec.ts +52 -0
- package/tests/utils/copy-public.spec.ts +56 -0
- package/tests/utils/diagnostic-utils.spec.ts +24 -15
- package/tests/utils/engine-watch-events.acc.spec.ts +59 -0
- package/tests/utils/engine-watch-events.spec.ts +58 -0
- package/tests/utils/esbuild-client-config-integration.verify.md +9 -0
- package/tests/utils/esbuild-client-config.acc.spec.ts +45 -61
- package/tests/utils/esbuild-client-config.spec.ts +70 -52
- package/tests/utils/ngtsc-build-core-write-emit.spec.ts +136 -12
- package/tests/utils/ngtsc-build-core.spec.ts +1 -44
- package/tests/utils/output-utils.spec.ts +133 -13
- package/tests/utils/replace-deps-watch.acc.spec.ts +7 -1
- package/tests/utils/replace-deps-watch.spec.ts +57 -1
- package/tests/utils/worker-utils.spec.ts +8 -2
- package/tests/workers/client-worker-initial-build-error.verify.md +2 -3
- package/tests/workers/client-worker-initial-build-warnings.verify.md +7 -0
- package/tests/workers/client-worker-mtime-incremental.verify.md +10 -0
- package/tests/workers/client-worker-refactor.verify.md +22 -0
- package/tests/workers/client-worker-ts-cache-invalidation.verify.md +12 -0
- package/tests/workers/client-worker.acc.spec.ts +6 -3
- package/tests/workers/incremental-mtime-tracker.acc.spec.ts +144 -0
- package/tests/workers/incremental-mtime-tracker.spec.ts +102 -0
- package/tests/workers/library-build-lint.spec.ts +40 -45
- package/tests/workers/library-build-worker.spec.ts +298 -40
- package/tests/workers/server-build-lint.spec.ts +59 -45
- package/tests/workers/server-build-worker.spec.ts +63 -24
- package/tests/workers/server-esbuild-context.acc.spec.ts +2 -0
- package/tests/workers/server-esbuild-context.spec.ts +2 -0
- package/tests/workers/server-runtime-worker.spec.ts +1 -1
- package/tests/workers/shared-worker-lifecycle.acc.spec.ts +1 -1
- package/dist/angular/angular-build-pipeline.d.ts +0 -97
- package/dist/angular/angular-build-pipeline.d.ts.map +0 -1
- package/dist/angular/angular-build-pipeline.js +0 -285
- package/dist/angular/angular-build-pipeline.js.map +0 -1
- package/dist/utils/tsc-build.d.ts +0 -51
- package/dist/utils/tsc-build.d.ts.map +0 -1
- package/dist/utils/tsc-build.js +0 -156
- package/dist/utils/tsc-build.js.map +0 -1
- package/dist/workers/ngtsc-build.worker.d.ts +0 -23
- package/dist/workers/ngtsc-build.worker.d.ts.map +0 -1
- package/dist/workers/ngtsc-build.worker.js +0 -267
- package/dist/workers/ngtsc-build.worker.js.map +0 -1
- package/src/angular/angular-build-pipeline.ts +0 -406
- package/src/utils/tsc-build.ts +0 -226
- package/src/workers/ngtsc-build.worker.ts +0 -351
- package/tests/angular/angular-build-pipeline.spec.ts +0 -247
- package/tests/angular/angular-compiler-aot.acc.spec.ts +0 -68
- package/tests/angular/angular-compiler-aot.spec.ts +0 -80
- package/tests/utils/angular-compiler-emit.spec.ts +0 -666
- package/tests/utils/angular-compiler.spec.ts +0 -707
- package/tests/utils/tsc-build.spec.ts +0 -527
- package/tests/workers/ngtsc-build-lint.spec.ts +0 -141
- package/tests/workers/ngtsc-build-worker.spec.ts +0 -199
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { consola } from "consola";
|
|
3
|
+
|
|
4
|
+
const mockLogger = {
|
|
5
|
+
debug: vi.fn(),
|
|
6
|
+
info: vi.fn(),
|
|
7
|
+
warn: vi.fn(),
|
|
8
|
+
error: vi.fn(),
|
|
9
|
+
start: vi.fn(),
|
|
10
|
+
success: vi.fn(),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
vi.spyOn(consola, "withTag").mockReturnValue(mockLogger as any);
|
|
2
14
|
|
|
3
15
|
const mocks = vi.hoisted(() => ({
|
|
4
16
|
executeTypecheck: vi.fn(),
|
|
5
17
|
executeLint: vi.fn(),
|
|
6
18
|
runLintInWorker: vi.fn(),
|
|
7
|
-
execa: vi.fn(),
|
|
8
19
|
loadSdConfig: vi.fn(),
|
|
9
20
|
discoverWorkspacePackages: vi.fn(),
|
|
10
21
|
}));
|
|
@@ -25,13 +36,6 @@ vi.mock("../../src/utils/sd-config", () => ({
|
|
|
25
36
|
loadSdConfig: mocks.loadSdConfig,
|
|
26
37
|
}));
|
|
27
38
|
|
|
28
|
-
vi.mock("@simplysm/core-node", () => ({
|
|
29
|
-
cpx: {
|
|
30
|
-
spawn: mocks.execa,
|
|
31
|
-
spawnSync: vi.fn().mockReturnValue({ stdout: "", stderr: "", exitCode: 0 }),
|
|
32
|
-
},
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
39
|
vi.mock("../../src/utils/package-utils", async (importOriginal) => {
|
|
36
40
|
const actual = await importOriginal<typeof import("../../src/utils/package-utils")>();
|
|
37
41
|
return {
|
|
@@ -42,20 +46,21 @@ vi.mock("../../src/utils/package-utils", async (importOriginal) => {
|
|
|
42
46
|
|
|
43
47
|
const { runCheck } = await import("../../src/commands/check");
|
|
44
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Collects all calls to the given mock function's first argument into an array,
|
|
51
|
+
* preserving call order for sequential assertions.
|
|
52
|
+
*/
|
|
53
|
+
function collectArgs(fn: ReturnType<typeof vi.fn>): string[] {
|
|
54
|
+
return fn.mock.calls.map((call) => String(call[0]));
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
describe("runCheck", () => {
|
|
46
58
|
let savedExitCode: typeof process.exitCode;
|
|
47
|
-
let writeSpy: ReturnType<typeof vi.spyOn>;
|
|
48
|
-
let stdoutOutput: string;
|
|
49
59
|
|
|
50
60
|
beforeEach(() => {
|
|
51
61
|
vi.clearAllMocks();
|
|
52
62
|
savedExitCode = process.exitCode;
|
|
53
63
|
process.exitCode = undefined;
|
|
54
|
-
stdoutOutput = "";
|
|
55
|
-
writeSpy = vi.spyOn(process.stdout, "write").mockImplementation((chunk: unknown) => {
|
|
56
|
-
stdoutOutput += String(chunk);
|
|
57
|
-
return true;
|
|
58
|
-
});
|
|
59
64
|
|
|
60
65
|
// Default: workspace packages
|
|
61
66
|
mocks.discoverWorkspacePackages.mockReturnValue(
|
|
@@ -89,41 +94,22 @@ describe("runCheck", () => {
|
|
|
89
94
|
mocks.runLintInWorker.mockResolvedValue({
|
|
90
95
|
success: true, errorCount: 0, warningCount: 0, formattedOutput: "",
|
|
91
96
|
});
|
|
92
|
-
mocks.execa.mockResolvedValue({
|
|
93
|
-
stdout: "Tests 1 passed", stderr: "", exitCode: 0,
|
|
94
|
-
});
|
|
95
97
|
});
|
|
96
98
|
|
|
97
99
|
afterEach(() => {
|
|
98
100
|
process.exitCode = savedExitCode;
|
|
99
|
-
writeSpy.mockRestore();
|
|
100
101
|
});
|
|
101
102
|
|
|
102
|
-
it("
|
|
103
|
-
await runCheck({ targets: [], types: ["typecheck", "lint"
|
|
104
|
-
|
|
105
|
-
expect(stdoutOutput).toContain("TYPECHECK");
|
|
106
|
-
expect(stdoutOutput).toContain("TEST");
|
|
107
|
-
});
|
|
103
|
+
it("outputs success sections in TYPECHECK → LINT order via logger.success", async () => {
|
|
104
|
+
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
108
105
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const tcIdx = stdoutOutput.indexOf("TYPECHECK");
|
|
113
|
-
const lintIdx = stdoutOutput.indexOf("LINT");
|
|
114
|
-
const testIdx = stdoutOutput.indexOf("TEST");
|
|
115
|
-
const summaryIdx = stdoutOutput.indexOf("요약");
|
|
106
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
107
|
+
const tcIdx = successArgs.findIndex((a) => a.includes("TYPECHECK"));
|
|
108
|
+
const lintIdx = successArgs.findIndex((a) => a.includes("LINT"));
|
|
116
109
|
|
|
110
|
+
expect(tcIdx).toBeGreaterThanOrEqual(0);
|
|
111
|
+
expect(lintIdx).toBeGreaterThanOrEqual(0);
|
|
117
112
|
expect(tcIdx).toBeLessThan(lintIdx);
|
|
118
|
-
expect(lintIdx).toBeLessThan(testIdx);
|
|
119
|
-
expect(testIdx).toBeLessThan(summaryIdx);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it("runs only specified check types", async () => {
|
|
123
|
-
await runCheck({ targets: [], types: ["test"], fix: false });
|
|
124
|
-
|
|
125
|
-
expect(stdoutOutput).not.toContain("TYPECHECK");
|
|
126
|
-
expect(stdoutOutput).toContain("TEST");
|
|
127
113
|
});
|
|
128
114
|
|
|
129
115
|
it("sets exitCode 1 when typecheck fails", async () => {
|
|
@@ -133,35 +119,52 @@ describe("runCheck", () => {
|
|
|
133
119
|
scriptsPackagePaths: [],
|
|
134
120
|
});
|
|
135
121
|
|
|
136
|
-
await runCheck({ targets: [], types: ["typecheck", "lint"
|
|
122
|
+
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
137
123
|
|
|
138
124
|
expect(process.exitCode).toBe(1);
|
|
139
125
|
});
|
|
140
126
|
|
|
141
|
-
it("
|
|
142
|
-
mocks.
|
|
143
|
-
success: false, errorCount:
|
|
127
|
+
it("outputs failed section via logger.error with formattedOutput", async () => {
|
|
128
|
+
mocks.executeTypecheck.mockResolvedValue({
|
|
129
|
+
success: false, errorCount: 2, warningCount: 0, formattedOutput: "type errors",
|
|
130
|
+
lint: { success: true, errorCount: 0, warningCount: 0, formattedOutput: "" },
|
|
131
|
+
scriptsPackagePaths: [],
|
|
144
132
|
});
|
|
145
133
|
|
|
146
|
-
await runCheck({ targets: [], types: ["lint"], fix: false });
|
|
134
|
+
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
147
135
|
|
|
148
|
-
|
|
136
|
+
const errorArgs = collectArgs(mockLogger.error);
|
|
137
|
+
expect(errorArgs.some((a) => a.includes("TYPECHECK"))).toBe(true);
|
|
138
|
+
expect(errorArgs.some((a) => a.includes("type errors"))).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("outputs success summary via logger.success when all pass", async () => {
|
|
142
|
+
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
143
|
+
|
|
144
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
145
|
+
expect(successArgs.some((a) => a.includes("전체 통과"))).toBe(true);
|
|
149
146
|
});
|
|
150
147
|
|
|
151
|
-
it("
|
|
152
|
-
mocks.
|
|
153
|
-
|
|
148
|
+
it("outputs failure summary via logger.error when any fails", async () => {
|
|
149
|
+
mocks.executeTypecheck.mockResolvedValue({
|
|
150
|
+
success: false, errorCount: 1, warningCount: 0, formattedOutput: "err",
|
|
151
|
+
lint: { success: true, errorCount: 0, warningCount: 0, formattedOutput: "" },
|
|
152
|
+
scriptsPackagePaths: [],
|
|
154
153
|
});
|
|
155
154
|
|
|
156
|
-
await runCheck({ targets: [], types: ["
|
|
155
|
+
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
157
156
|
|
|
158
|
-
|
|
157
|
+
const errorArgs = collectArgs(mockLogger.error);
|
|
158
|
+
expect(errorArgs.some((a) => a.includes("실패"))).toBe(true);
|
|
159
|
+
expect(errorArgs.some((a) => a.includes("합계"))).toBe(true);
|
|
159
160
|
});
|
|
160
161
|
|
|
161
|
-
it("
|
|
162
|
-
mocks.
|
|
162
|
+
it("sets exitCode to 1 when lint fails", async () => {
|
|
163
|
+
mocks.executeLint.mockResolvedValue({
|
|
164
|
+
success: false, errorCount: 1, warningCount: 0, formattedOutput: "lint errors",
|
|
165
|
+
});
|
|
163
166
|
|
|
164
|
-
await runCheck({ targets: [], types: ["
|
|
167
|
+
await runCheck({ targets: [], types: ["lint"], fix: false });
|
|
165
168
|
|
|
166
169
|
expect(process.exitCode).toBe(1);
|
|
167
170
|
});
|
|
@@ -179,51 +182,45 @@ describe("runCheck", () => {
|
|
|
179
182
|
it("resolves package target to packages/ path", async () => {
|
|
180
183
|
await runCheck({ targets: ["core-node"], types: ["typecheck"], fix: false });
|
|
181
184
|
|
|
182
|
-
|
|
185
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
186
|
+
expect(successArgs.some((a) => a.includes("TYPECHECK"))).toBe(true);
|
|
183
187
|
expect(process.exitCode).toBeUndefined();
|
|
184
188
|
});
|
|
185
189
|
|
|
186
190
|
it("resolves test directory target to tests/ path", async () => {
|
|
187
191
|
await runCheck({ targets: ["orm"], types: ["typecheck"], fix: false });
|
|
188
192
|
|
|
189
|
-
|
|
193
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
194
|
+
expect(successArgs.some((a) => a.includes("TYPECHECK"))).toBe(true);
|
|
190
195
|
expect(process.exitCode).toBeUndefined();
|
|
191
196
|
});
|
|
192
197
|
|
|
193
198
|
it("resolves mixed targets to correct paths", async () => {
|
|
194
199
|
await runCheck({ targets: ["core-node", "orm"], types: ["typecheck"], fix: false });
|
|
195
200
|
|
|
196
|
-
|
|
201
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
202
|
+
expect(successArgs.some((a) => a.includes("TYPECHECK"))).toBe(true);
|
|
197
203
|
expect(process.exitCode).toBeUndefined();
|
|
198
204
|
});
|
|
199
205
|
|
|
200
206
|
it("resolves lint target to correct path", async () => {
|
|
201
207
|
await runCheck({ targets: ["orm"], types: ["lint"], fix: false });
|
|
202
208
|
|
|
203
|
-
|
|
209
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
210
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
204
211
|
expect(process.exitCode).toBeUndefined();
|
|
205
212
|
});
|
|
206
213
|
|
|
207
|
-
it("passes resolved paths to vitest", async () => {
|
|
208
|
-
await runCheck({ targets: ["orm"], types: ["test"], fix: false });
|
|
209
|
-
|
|
210
|
-
expect(mocks.execa).toHaveBeenCalledWith(
|
|
211
|
-
"pnpm",
|
|
212
|
-
["vitest", "tests/orm", "--run"],
|
|
213
|
-
expect.any(Object),
|
|
214
|
-
);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
214
|
it("passes empty targets for all when no targets specified", async () => {
|
|
218
215
|
await runCheck({ targets: [], types: ["typecheck"], fix: false });
|
|
219
216
|
|
|
220
|
-
|
|
217
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
218
|
+
expect(successArgs.some((a) => a.includes("TYPECHECK"))).toBe(true);
|
|
221
219
|
expect(process.exitCode).toBeUndefined();
|
|
222
220
|
});
|
|
223
221
|
|
|
224
222
|
describe("lint via engine integration", () => {
|
|
225
223
|
beforeEach(() => {
|
|
226
|
-
// Default: executeTypecheck returns lint result and scriptsPackagePaths
|
|
227
224
|
mocks.executeTypecheck.mockResolvedValue({
|
|
228
225
|
success: true, errorCount: 0, warningCount: 0, formattedOutput: "",
|
|
229
226
|
lint: { success: true, errorCount: 0, warningCount: 0, formattedOutput: "" },
|
|
@@ -231,15 +228,14 @@ describe("runCheck", () => {
|
|
|
231
228
|
});
|
|
232
229
|
});
|
|
233
230
|
|
|
234
|
-
// Scenario: typecheck+lint 요청 시 TYPECHECK과 LINT 섹션이 출력된다
|
|
235
231
|
it("outputs TYPECHECK and LINT sections when both are requested", async () => {
|
|
236
232
|
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
237
233
|
|
|
238
|
-
|
|
239
|
-
expect(
|
|
234
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
235
|
+
expect(successArgs.some((a) => a.includes("TYPECHECK"))).toBe(true);
|
|
236
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
240
237
|
});
|
|
241
238
|
|
|
242
|
-
// Scenario: lint 실패 시 exitCode 설정
|
|
243
239
|
it("sets exitCode 1 when engine lint fails", async () => {
|
|
244
240
|
mocks.executeTypecheck.mockResolvedValue({
|
|
245
241
|
success: true, errorCount: 0, warningCount: 0, formattedOutput: "",
|
|
@@ -252,7 +248,6 @@ describe("runCheck", () => {
|
|
|
252
248
|
expect(process.exitCode).toBe(1);
|
|
253
249
|
});
|
|
254
250
|
|
|
255
|
-
// Scenario: scripts 패키지 포함 시 lint가 성공한다
|
|
256
251
|
it("succeeds when scriptsPackagePaths is non-empty", async () => {
|
|
257
252
|
mocks.executeTypecheck.mockResolvedValue({
|
|
258
253
|
success: true, errorCount: 0, warningCount: 0, formattedOutput: "",
|
|
@@ -265,69 +260,62 @@ describe("runCheck", () => {
|
|
|
265
260
|
|
|
266
261
|
await runCheck({ targets: [], types: ["typecheck", "lint"], fix: false });
|
|
267
262
|
|
|
268
|
-
|
|
263
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
264
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
269
265
|
expect(process.exitCode).toBeUndefined();
|
|
270
266
|
});
|
|
271
267
|
});
|
|
272
268
|
|
|
273
269
|
describe("lint-only path", () => {
|
|
274
|
-
// Scenario: lint만 요청 시 LINT 섹션만 출력된다
|
|
275
270
|
it("outputs LINT section when only lint type is requested", async () => {
|
|
276
271
|
await runCheck({ targets: [], types: ["lint"], fix: false });
|
|
277
272
|
|
|
278
|
-
|
|
279
|
-
expect(
|
|
273
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
274
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
275
|
+
const allArgs = [...collectArgs(mockLogger.success), ...collectArgs(mockLogger.error)];
|
|
276
|
+
expect(allArgs.some((a) => a.includes("TYPECHECK"))).toBe(false);
|
|
280
277
|
});
|
|
281
278
|
|
|
282
|
-
// Scenario: lint,test 요청 시 LINT과 TEST 섹션 출력 (TYPECHECK 없음)
|
|
283
|
-
it("outputs LINT and TEST sections when lint,test are requested", async () => {
|
|
284
|
-
await runCheck({ targets: [], types: ["lint", "test"], fix: false });
|
|
285
|
-
|
|
286
|
-
expect(stdoutOutput).toContain("LINT");
|
|
287
|
-
expect(stdoutOutput).toContain("TEST");
|
|
288
|
-
expect(stdoutOutput).not.toContain("TYPECHECK");
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
// Scenario: scripts 패키지 포함 전체 lint
|
|
292
279
|
it("handles all packages via lint including scripts", async () => {
|
|
293
280
|
mocks.discoverWorkspacePackages.mockReturnValue(
|
|
294
281
|
new Map([
|
|
295
282
|
["core-common", "packages/core-common"],
|
|
296
|
-
["sd-claude", "packages/sd-claude"],
|
|
283
|
+
["sd-claude", "packages/sd-claude"],
|
|
297
284
|
]),
|
|
298
285
|
);
|
|
299
286
|
|
|
300
287
|
await runCheck({ targets: [], types: ["lint"], fix: false });
|
|
301
288
|
|
|
302
|
-
|
|
303
|
-
expect(
|
|
289
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
290
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
291
|
+
const allArgs = [...collectArgs(mockLogger.success), ...collectArgs(mockLogger.error)];
|
|
292
|
+
expect(allArgs.some((a) => a.includes("TYPECHECK"))).toBe(false);
|
|
304
293
|
});
|
|
305
294
|
|
|
306
|
-
// Scenario: 특정 타겟 지정 lint
|
|
307
295
|
it("succeeds with normalized target paths for lint", async () => {
|
|
308
296
|
await runCheck({ targets: ["core-common"], types: ["lint"], fix: false });
|
|
309
297
|
|
|
310
|
-
|
|
298
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
299
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
311
300
|
expect(process.exitCode).toBeUndefined();
|
|
312
301
|
});
|
|
313
302
|
|
|
314
|
-
// Scenario: --fix 옵션으로 자동 수정
|
|
315
303
|
it("succeeds when --fix is specified", async () => {
|
|
316
304
|
await runCheck({ targets: [], types: ["lint"], fix: true });
|
|
317
305
|
|
|
318
|
-
|
|
306
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
307
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
319
308
|
expect(process.exitCode).toBeUndefined();
|
|
320
309
|
});
|
|
321
310
|
|
|
322
|
-
// Scenario: --fix 없이 실행
|
|
323
311
|
it("succeeds when --fix is not specified", async () => {
|
|
324
312
|
await runCheck({ targets: [], types: ["lint"], fix: false });
|
|
325
313
|
|
|
326
|
-
|
|
314
|
+
const successArgs = collectArgs(mockLogger.success);
|
|
315
|
+
expect(successArgs.some((a) => a.includes("LINT"))).toBe(true);
|
|
327
316
|
expect(process.exitCode).toBeUndefined();
|
|
328
317
|
});
|
|
329
318
|
|
|
330
|
-
// Scenario: lint 에러 없음
|
|
331
319
|
it("does not set exitCode when lint passes", async () => {
|
|
332
320
|
mocks.executeLint.mockResolvedValue({
|
|
333
321
|
success: true, errorCount: 0, warningCount: 0, formattedOutput: "",
|
|
@@ -338,7 +326,6 @@ describe("runCheck", () => {
|
|
|
338
326
|
expect(process.exitCode).toBeUndefined();
|
|
339
327
|
});
|
|
340
328
|
|
|
341
|
-
// Scenario: lint 에러 발생
|
|
342
329
|
it("sets exitCode 1 when lint has errors", async () => {
|
|
343
330
|
mocks.executeLint.mockResolvedValue({
|
|
344
331
|
success: false, errorCount: 3, warningCount: 2, formattedOutput: "lint errors",
|
|
@@ -349,12 +336,11 @@ describe("runCheck", () => {
|
|
|
349
336
|
expect(process.exitCode).toBe(1);
|
|
350
337
|
});
|
|
351
338
|
|
|
352
|
-
// typecheck 관련 로그 메시지가 출력되지 않는다
|
|
353
339
|
it("does not output typecheck-related sections when only lint is requested", async () => {
|
|
354
340
|
await runCheck({ targets: [], types: ["lint"], fix: false });
|
|
355
341
|
|
|
356
|
-
|
|
342
|
+
const allArgs = [...collectArgs(mockLogger.success), ...collectArgs(mockLogger.error)];
|
|
343
|
+
expect(allArgs.some((a) => a.includes("TYPECHECK"))).toBe(false);
|
|
357
344
|
});
|
|
358
345
|
});
|
|
359
|
-
|
|
360
346
|
});
|
|
@@ -298,8 +298,16 @@ describe("runPublish", () => {
|
|
|
298
298
|
},
|
|
299
299
|
});
|
|
300
300
|
|
|
301
|
-
const
|
|
301
|
+
const { consola } = await import("consola");
|
|
302
|
+
const infoSpy = vi.fn();
|
|
303
|
+
const origWithTag = consola.withTag.bind(consola);
|
|
304
|
+
const withTagSpy = vi.spyOn(consola, "withTag").mockImplementation((tag: string) => {
|
|
305
|
+
const logger = origWithTag(tag);
|
|
306
|
+
logger.info = infoSpy as any;
|
|
307
|
+
return logger;
|
|
308
|
+
});
|
|
302
309
|
|
|
310
|
+
// Re-import to pick up the spy (module already loaded, but logger is created at call time)
|
|
303
311
|
await runPublish({
|
|
304
312
|
targets: [],
|
|
305
313
|
noBuild: false,
|
|
@@ -307,9 +315,9 @@ describe("runPublish", () => {
|
|
|
307
315
|
options: [],
|
|
308
316
|
});
|
|
309
317
|
|
|
310
|
-
const
|
|
311
|
-
expect(
|
|
312
|
-
|
|
318
|
+
const infoArgs = infoSpy.mock.calls.map((c: unknown[]) => String(c[0]));
|
|
319
|
+
expect(infoArgs.some((a: string) => a.includes("배포할 패키지가 없습니다"))).toBe(true);
|
|
320
|
+
withTagSpy.mockRestore();
|
|
313
321
|
});
|
|
314
322
|
});
|
|
315
323
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Slice 3: severity 정리 — LLM 검증
|
|
2
|
+
|
|
3
|
+
## 검증 항목
|
|
4
|
+
|
|
5
|
+
- [x] replace-deps.ts:5 — `const logger = consola.withTag("sd:cli:replace-deps")` 모듈-레벨 로거 추가 확인
|
|
6
|
+
- [x] replace-deps.ts:24 — `consola.warn(...)` → `logger.warn(...)` 변경 확인
|
|
7
|
+
- [x] deployment-phase.ts:66-70 — DRY-RUN 성공 메시지 `debug` → `info` 전환 확인: `dryRun ? logger.info("[DRY-RUN] ...") : logger.debug(...)`
|
|
8
|
+
- [x] deployment-phase.ts:76-80 — DRY-RUN 재시도 메시지 `debug` → `info` 전환 확인: 동일 패턴
|
|
9
|
+
- [x] deployment-phase.ts:102 — `logger.fail(...)` → `logger.error(...)` 전환 확인
|
|
10
|
+
- [x] BuildOrchestrator.ts:251 — `this._logger.success("빌드 실행 완료")` 행 제거 확인: 250행 뒤에 바로 `return` 문
|
|
11
|
+
- [x] BuildOrchestrator.ts:477 — `this._logger.info("빌드 완료")` → `this._logger.success("빌드 완료")` 전환 확인
|
|
12
|
+
- [x] BuildOrchestrator.ts:232-233 — `this._logger.start("빌드 실행 중...")` 유지 확인: start(232)/success(477) 쌍 정상화
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import os from "os";
|
|
5
|
+
import { upgradeVersion, computePublishLevels } from "../../src/commands/publish/version-upgrade";
|
|
6
|
+
|
|
7
|
+
function createTempDir(): string {
|
|
8
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "sd-cli-version-upgrade-"));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function writeJson(filePath: string, data: unknown): void {
|
|
12
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
13
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function readJson<T>(filePath: string): T {
|
|
17
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8")) as T;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe("upgradeVersion", () => {
|
|
21
|
+
let tmpDir: string;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
tmpDir = createTempDir();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("복수 패키지의 package.json을 병렬 업데이트한다", async () => {
|
|
32
|
+
// Given: allPkgPaths에 5개 패키지 경로가 있다
|
|
33
|
+
writeJson(path.join(tmpDir, "package.json"), {
|
|
34
|
+
name: "@simplysm/root",
|
|
35
|
+
version: "14.0.0",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const pkgNames = ["pkg-a", "pkg-b", "pkg-c", "pkg-d", "pkg-e"];
|
|
39
|
+
const allPkgPaths = pkgNames.map((name) => {
|
|
40
|
+
const pkgDir = path.join(tmpDir, "packages", name);
|
|
41
|
+
writeJson(path.join(pkgDir, "package.json"), {
|
|
42
|
+
name: `@simplysm/${name}`,
|
|
43
|
+
version: "14.0.0",
|
|
44
|
+
});
|
|
45
|
+
return pkgDir;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// sd-cli/templates 디렉토리 생성 (glob 대상이 없도록)
|
|
49
|
+
fs.mkdirSync(path.join(tmpDir, "packages", "sd-cli", "templates"), {
|
|
50
|
+
recursive: true,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// When
|
|
54
|
+
const result = await upgradeVersion(tmpDir, allPkgPaths, false);
|
|
55
|
+
|
|
56
|
+
// Then: 5개 패키지의 package.json이 모두 newVersion으로 업데이트된다
|
|
57
|
+
expect(result.version).toBe("14.0.1");
|
|
58
|
+
for (const pkgDir of allPkgPaths) {
|
|
59
|
+
const pkg = readJson<{ version: string }>(path.join(pkgDir, "package.json"));
|
|
60
|
+
expect(pkg.version).toBe("14.0.1");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// And: changedFiles에 5개 패키지 경로가 모두 포함된다
|
|
64
|
+
for (const pkgDir of allPkgPaths) {
|
|
65
|
+
expect(result.changedFiles).toContain(path.resolve(pkgDir, "package.json"));
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("패키지가 없으면 루트 package.json만 changedFiles에 포함된다", async () => {
|
|
70
|
+
// Given: allPkgPaths가 빈 배열이다
|
|
71
|
+
writeJson(path.join(tmpDir, "package.json"), {
|
|
72
|
+
name: "@simplysm/root",
|
|
73
|
+
version: "14.0.0",
|
|
74
|
+
});
|
|
75
|
+
fs.mkdirSync(path.join(tmpDir, "packages", "sd-cli", "templates"), {
|
|
76
|
+
recursive: true,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// When
|
|
80
|
+
const result = await upgradeVersion(tmpDir, [], false);
|
|
81
|
+
|
|
82
|
+
// Then: 루트 package.json만 changedFiles에 포함된다
|
|
83
|
+
expect(result.changedFiles).toHaveLength(1);
|
|
84
|
+
expect(result.changedFiles[0]).toBe(path.resolve(tmpDir, "package.json"));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("복수 템플릿 파일을 병렬 업데이트한다", async () => {
|
|
88
|
+
// Given: 템플릿 3개 중 2개에 @simplysm 버전이 포함되어 있다
|
|
89
|
+
writeJson(path.join(tmpDir, "package.json"), {
|
|
90
|
+
name: "@simplysm/root",
|
|
91
|
+
version: "14.0.0",
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const templatesDir = path.join(tmpDir, "packages", "sd-cli", "templates");
|
|
95
|
+
fs.mkdirSync(templatesDir, { recursive: true });
|
|
96
|
+
|
|
97
|
+
// 템플릿 1: @simplysm 버전 포함
|
|
98
|
+
fs.writeFileSync(
|
|
99
|
+
path.join(templatesDir, "a.hbs"),
|
|
100
|
+
`"@simplysm/core-common": "~14.0.0"`,
|
|
101
|
+
"utf-8",
|
|
102
|
+
);
|
|
103
|
+
// 템플릿 2: @simplysm 버전 포함
|
|
104
|
+
fs.writeFileSync(
|
|
105
|
+
path.join(templatesDir, "b.hbs"),
|
|
106
|
+
`"@simplysm/angular": "~14.0.0"`,
|
|
107
|
+
"utf-8",
|
|
108
|
+
);
|
|
109
|
+
// 템플릿 3: @simplysm 버전 미포함
|
|
110
|
+
fs.writeFileSync(path.join(templatesDir, "c.hbs"), `no version here`, "utf-8");
|
|
111
|
+
|
|
112
|
+
// When
|
|
113
|
+
const result = await upgradeVersion(tmpDir, [], false);
|
|
114
|
+
|
|
115
|
+
// Then: 2개 파일만 수정되고 changedFiles에 추가된다
|
|
116
|
+
const templateChanges = result.changedFiles.filter((f) => f.endsWith(".hbs"));
|
|
117
|
+
expect(templateChanges).toHaveLength(2);
|
|
118
|
+
|
|
119
|
+
// 수정된 파일들의 내용 확인
|
|
120
|
+
expect(fs.readFileSync(path.join(templatesDir, "a.hbs"), "utf-8")).toContain("~14.0.1");
|
|
121
|
+
expect(fs.readFileSync(path.join(templatesDir, "b.hbs"), "utf-8")).toContain("~14.0.1");
|
|
122
|
+
// 수정되지 않은 파일
|
|
123
|
+
expect(fs.readFileSync(path.join(templatesDir, "c.hbs"), "utf-8")).toBe("no version here");
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("템플릿이 없으면 템플릿 관련 쓰기 없이 완료된다", async () => {
|
|
127
|
+
// Given: glob 결과가 빈 배열이다 (templates 디렉토리에 .hbs 파일 없음)
|
|
128
|
+
writeJson(path.join(tmpDir, "package.json"), {
|
|
129
|
+
name: "@simplysm/root",
|
|
130
|
+
version: "14.0.0",
|
|
131
|
+
});
|
|
132
|
+
fs.mkdirSync(path.join(tmpDir, "packages", "sd-cli", "templates"), {
|
|
133
|
+
recursive: true,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// When
|
|
137
|
+
const result = await upgradeVersion(tmpDir, [], false);
|
|
138
|
+
|
|
139
|
+
// Then
|
|
140
|
+
const templateChanges = result.changedFiles.filter((f) => f.endsWith(".hbs"));
|
|
141
|
+
expect(templateChanges).toHaveLength(0);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("changedFiles[0]이 프로젝트 루트 package.json 경로이다", async () => {
|
|
145
|
+
// Given: allPkgPaths에 3개 패키지가 있다
|
|
146
|
+
writeJson(path.join(tmpDir, "package.json"), {
|
|
147
|
+
name: "@simplysm/root",
|
|
148
|
+
version: "14.0.0",
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const allPkgPaths = ["pkg-a", "pkg-b", "pkg-c"].map((name) => {
|
|
152
|
+
const pkgDir = path.join(tmpDir, "packages", name);
|
|
153
|
+
writeJson(path.join(pkgDir, "package.json"), {
|
|
154
|
+
name: `@simplysm/${name}`,
|
|
155
|
+
version: "14.0.0",
|
|
156
|
+
});
|
|
157
|
+
return pkgDir;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
fs.mkdirSync(path.join(tmpDir, "packages", "sd-cli", "templates"), {
|
|
161
|
+
recursive: true,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// When
|
|
165
|
+
const result = await upgradeVersion(tmpDir, allPkgPaths, false);
|
|
166
|
+
|
|
167
|
+
// Then: changedFiles[0]이 프로젝트 루트 package.json 경로이다
|
|
168
|
+
expect(result.changedFiles[0]).toBe(path.resolve(tmpDir, "package.json"));
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe("computePublishLevels", () => {
|
|
173
|
+
let tmpDir: string;
|
|
174
|
+
|
|
175
|
+
beforeEach(() => {
|
|
176
|
+
tmpDir = createTempDir();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
afterEach(() => {
|
|
180
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("의존 관계가 있는 패키지들의 레벨을 올바르게 계산한다", async () => {
|
|
184
|
+
// Given: A(의존 없음), B(A 의존), C(B 의존)
|
|
185
|
+
const pkgs = [
|
|
186
|
+
{ name: "pkg-a", deps: {} },
|
|
187
|
+
{ name: "pkg-b", deps: { "@simplysm/pkg-a": "~14.0.0" } },
|
|
188
|
+
{ name: "pkg-c", deps: { "@simplysm/pkg-b": "~14.0.0" } },
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
const publishPkgs = pkgs.map((p) => {
|
|
192
|
+
const pkgDir = path.join(tmpDir, "packages", p.name);
|
|
193
|
+
writeJson(path.join(pkgDir, "package.json"), {
|
|
194
|
+
name: `@simplysm/${p.name}`,
|
|
195
|
+
version: "14.0.0",
|
|
196
|
+
dependencies: p.deps,
|
|
197
|
+
});
|
|
198
|
+
return { name: p.name, path: pkgDir };
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// When
|
|
202
|
+
const levels = await computePublishLevels(publishPkgs);
|
|
203
|
+
|
|
204
|
+
// Then: 레벨은 [[A], [B], [C]]
|
|
205
|
+
expect(levels).toHaveLength(3);
|
|
206
|
+
expect(levels[0].map((p) => p.name)).toEqual(["pkg-a"]);
|
|
207
|
+
expect(levels[1].map((p) => p.name)).toEqual(["pkg-b"]);
|
|
208
|
+
expect(levels[2].map((p) => p.name)).toEqual(["pkg-c"]);
|
|
209
|
+
});
|
|
210
|
+
});
|