@build-astron-co/nimbus 0.4.1 → 0.4.3
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/CHANGELOG.md +268 -89
- package/README.md +26 -567
- package/dist/src/agent/compaction-agent.js +24 -12
- package/dist/src/agent/context-manager.js +2 -1
- package/dist/src/agent/expand-files.js +2 -1
- package/dist/src/agent/loop.js +71 -33
- package/dist/src/agent/permissions.js +4 -2
- package/dist/src/agent/system-prompt.js +34 -17
- package/dist/src/app.js +1 -1
- package/dist/src/auth/keychain.js +8 -4
- package/dist/src/auth/store.js +70 -107
- package/dist/src/cli/init.js +35 -19
- package/dist/src/cli/run.js +18 -10
- package/dist/src/cli/serve.js +4 -2
- package/dist/src/cli.js +52 -11
- package/dist/src/commands/alias.js +5 -3
- package/dist/src/commands/audit/index.js +2 -1
- package/dist/src/commands/aws-terraform.js +36 -18
- package/dist/src/commands/completions.js +1 -1
- package/dist/src/commands/config.js +3 -2
- package/dist/src/commands/connect-github.js +92 -0
- package/dist/src/commands/cost/index.js +3 -2
- package/dist/src/commands/deploy.js +15 -10
- package/dist/src/commands/doctor.js +9 -6
- package/dist/src/commands/drift/index.js +2 -1
- package/dist/src/commands/export.js +5 -3
- package/dist/src/commands/generate-terraform.js +110 -2
- package/dist/src/commands/import.js +3 -3
- package/dist/src/commands/incident.js +10 -5
- package/dist/src/commands/login.js +8 -93
- package/dist/src/commands/logs.js +16 -8
- package/dist/src/commands/onboarding.js +6 -4
- package/dist/src/commands/pipeline.js +6 -3
- package/dist/src/commands/plugin.js +3 -2
- package/dist/src/commands/profile.js +27 -14
- package/dist/src/commands/questionnaire.js +1 -1
- package/dist/src/commands/rollback.js +3 -2
- package/dist/src/commands/rollout.js +5 -3
- package/dist/src/commands/runbook.js +17 -10
- package/dist/src/commands/schedule.js +10 -5
- package/dist/src/commands/status.js +2 -1
- package/dist/src/commands/team-context.js +12 -7
- package/dist/src/commands/template.js +1 -1
- package/dist/src/commands/tf/index.js +6 -3
- package/dist/src/commands/upgrade.js +5 -3
- package/dist/src/commands/version.js +6 -3
- package/dist/src/commands/watch.js +6 -3
- package/dist/src/compat/sqlite.js +5 -3
- package/dist/src/config/mode-store.js +2 -1
- package/dist/src/config/profiles.js +4 -2
- package/dist/src/config/types.js +2 -1
- package/dist/src/engine/executor.js +8 -4
- package/dist/src/engine/planner.js +9 -5
- package/dist/src/llm/providers/anthropic.js +6 -3
- package/dist/src/llm/providers/ollama.js +1 -1
- package/dist/src/llm/router.js +22 -7
- package/dist/src/nimbus.js +1 -0
- package/dist/src/sessions/manager.js +6 -3
- package/dist/src/sharing/viewer.js +2 -1
- package/dist/src/tools/file-ops.js +1 -2
- package/dist/src/tools/schemas/devops.js +197 -108
- package/dist/src/tools/schemas/standard.js +1 -1
- package/dist/src/ui/App.js +25 -13
- package/dist/src/ui/FileDiffModal.js +22 -11
- package/dist/src/ui/HelpModal.js +2 -1
- package/dist/src/ui/InputBox.js +6 -3
- package/dist/src/ui/MessageList.js +40 -20
- package/dist/src/ui/TerminalPane.js +2 -1
- package/dist/src/ui/ToolCallDisplay.js +12 -6
- package/dist/src/ui/TreePane.js +2 -1
- package/dist/src/ui/ink/index.js +37 -21
- package/dist/src/version.js +1 -1
- package/dist/src/watcher/index.js +8 -4
- package/package.json +3 -5
- package/src/__tests__/alias.test.ts +0 -133
- package/src/__tests__/app.test.ts +0 -76
- package/src/__tests__/audit.test.ts +0 -877
- package/src/__tests__/circuit-breaker.test.ts +0 -116
- package/src/__tests__/cli-run.test.ts +0 -351
- package/src/__tests__/compat-sqlite.test.ts +0 -68
- package/src/__tests__/context-manager.test.ts +0 -632
- package/src/__tests__/context.test.ts +0 -242
- package/src/__tests__/devops-terminal-gaps.test.ts +0 -718
- package/src/__tests__/doctor.test.ts +0 -48
- package/src/__tests__/enterprise.test.ts +0 -401
- package/src/__tests__/export.test.ts +0 -236
- package/src/__tests__/gap-11-18-20.test.ts +0 -958
- package/src/__tests__/generator.test.ts +0 -433
- package/src/__tests__/helm-streaming.test.ts +0 -127
- package/src/__tests__/hooks.test.ts +0 -582
- package/src/__tests__/incident.test.ts +0 -179
- package/src/__tests__/init.test.ts +0 -487
- package/src/__tests__/intent-parser.test.ts +0 -229
- package/src/__tests__/llm-router.test.ts +0 -209
- package/src/__tests__/logs.test.ts +0 -107
- package/src/__tests__/loop-errors.test.ts +0 -244
- package/src/__tests__/lsp.test.ts +0 -293
- package/src/__tests__/modes.test.ts +0 -336
- package/src/__tests__/perf-optimizations.test.ts +0 -847
- package/src/__tests__/permissions.test.ts +0 -338
- package/src/__tests__/pipeline.test.ts +0 -50
- package/src/__tests__/polish-phase3.test.ts +0 -340
- package/src/__tests__/profile.test.ts +0 -237
- package/src/__tests__/rollback.test.ts +0 -83
- package/src/__tests__/runbook.test.ts +0 -219
- package/src/__tests__/schedule.test.ts +0 -206
- package/src/__tests__/serve.test.ts +0 -275
- package/src/__tests__/sessions.test.ts +0 -322
- package/src/__tests__/sharing.test.ts +0 -340
- package/src/__tests__/snapshots.test.ts +0 -581
- package/src/__tests__/standalone-migration.test.ts +0 -199
- package/src/__tests__/state-db.test.ts +0 -334
- package/src/__tests__/status.test.ts +0 -158
- package/src/__tests__/stream-with-tools.test.ts +0 -778
- package/src/__tests__/subagents.test.ts +0 -176
- package/src/__tests__/system-prompt.test.ts +0 -248
- package/src/__tests__/terminal-gap-v2.test.ts +0 -395
- package/src/__tests__/terminal-parity.test.ts +0 -393
- package/src/__tests__/tf-apply.test.ts +0 -187
- package/src/__tests__/tool-converter.test.ts +0 -256
- package/src/__tests__/tool-schemas.test.ts +0 -602
- package/src/__tests__/tools.test.ts +0 -144
- package/src/__tests__/version-json.test.ts +0 -184
- package/src/__tests__/version.test.ts +0 -49
- package/src/__tests__/watch.test.ts +0 -129
- package/src/agent/compaction-agent.ts +0 -266
- package/src/agent/context-manager.ts +0 -499
- package/src/agent/context.ts +0 -427
- package/src/agent/deploy-preview.ts +0 -487
- package/src/agent/expand-files.ts +0 -108
- package/src/agent/index.ts +0 -68
- package/src/agent/loop.ts +0 -1998
- package/src/agent/modes.ts +0 -429
- package/src/agent/permissions.ts +0 -513
- package/src/agent/subagents/base.ts +0 -116
- package/src/agent/subagents/cost.ts +0 -51
- package/src/agent/subagents/explore.ts +0 -42
- package/src/agent/subagents/general.ts +0 -54
- package/src/agent/subagents/index.ts +0 -102
- package/src/agent/subagents/infra.ts +0 -59
- package/src/agent/subagents/security.ts +0 -69
- package/src/agent/system-prompt.ts +0 -990
- package/src/app.ts +0 -180
- package/src/audit/activity-log.ts +0 -290
- package/src/audit/compliance-checker.ts +0 -540
- package/src/audit/cost-tracker.ts +0 -318
- package/src/audit/index.ts +0 -23
- package/src/audit/security-scanner.ts +0 -641
- package/src/auth/guard.ts +0 -75
- package/src/auth/index.ts +0 -56
- package/src/auth/keychain.ts +0 -82
- package/src/auth/oauth.ts +0 -465
- package/src/auth/providers.ts +0 -470
- package/src/auth/sso.ts +0 -113
- package/src/auth/store.ts +0 -505
- package/src/auth/types.ts +0 -187
- package/src/build.ts +0 -141
- package/src/cli/index.ts +0 -16
- package/src/cli/init.ts +0 -1227
- package/src/cli/openapi-spec.ts +0 -356
- package/src/cli/run.ts +0 -628
- package/src/cli/serve-auth.ts +0 -80
- package/src/cli/serve.ts +0 -539
- package/src/cli/web.ts +0 -71
- package/src/cli.ts +0 -1728
- package/src/clients/core-engine-client.ts +0 -227
- package/src/clients/enterprise-client.ts +0 -334
- package/src/clients/generator-client.ts +0 -351
- package/src/clients/git-client.ts +0 -627
- package/src/clients/github-client.ts +0 -410
- package/src/clients/helm-client.ts +0 -504
- package/src/clients/index.ts +0 -80
- package/src/clients/k8s-client.ts +0 -497
- package/src/clients/llm-client.ts +0 -161
- package/src/clients/rest-client.ts +0 -130
- package/src/clients/service-discovery.ts +0 -38
- package/src/clients/terraform-client.ts +0 -482
- package/src/clients/tools-client.ts +0 -1843
- package/src/clients/ws-client.ts +0 -115
- package/src/commands/alias.ts +0 -100
- package/src/commands/analyze/index.ts +0 -352
- package/src/commands/apply/helm.ts +0 -473
- package/src/commands/apply/index.ts +0 -213
- package/src/commands/apply/k8s.ts +0 -454
- package/src/commands/apply/terraform.ts +0 -582
- package/src/commands/ask.ts +0 -167
- package/src/commands/audit/index.ts +0 -357
- package/src/commands/auth-cloud.ts +0 -407
- package/src/commands/auth-list.ts +0 -134
- package/src/commands/auth-profile.ts +0 -121
- package/src/commands/auth-refresh.ts +0 -187
- package/src/commands/auth-status.ts +0 -141
- package/src/commands/aws/ec2.ts +0 -501
- package/src/commands/aws/iam.ts +0 -397
- package/src/commands/aws/index.ts +0 -133
- package/src/commands/aws/lambda.ts +0 -396
- package/src/commands/aws/rds.ts +0 -439
- package/src/commands/aws/s3.ts +0 -439
- package/src/commands/aws/vpc.ts +0 -393
- package/src/commands/aws-discover.ts +0 -542
- package/src/commands/aws-terraform.ts +0 -755
- package/src/commands/azure/aks.ts +0 -376
- package/src/commands/azure/functions.ts +0 -253
- package/src/commands/azure/index.ts +0 -116
- package/src/commands/azure/storage.ts +0 -478
- package/src/commands/azure/vm.ts +0 -355
- package/src/commands/billing/index.ts +0 -256
- package/src/commands/chat.ts +0 -320
- package/src/commands/completions.ts +0 -268
- package/src/commands/config.ts +0 -372
- package/src/commands/cost/cloud-cost-estimator.ts +0 -266
- package/src/commands/cost/estimator.ts +0 -79
- package/src/commands/cost/index.ts +0 -810
- package/src/commands/cost/parsers/terraform.ts +0 -273
- package/src/commands/cost/parsers/types.ts +0 -25
- package/src/commands/cost/pricing/aws.ts +0 -544
- package/src/commands/cost/pricing/azure.ts +0 -499
- package/src/commands/cost/pricing/gcp.ts +0 -396
- package/src/commands/cost/pricing/index.ts +0 -40
- package/src/commands/demo.ts +0 -250
- package/src/commands/deploy.ts +0 -260
- package/src/commands/doctor.ts +0 -1386
- package/src/commands/drift/index.ts +0 -787
- package/src/commands/explain.ts +0 -277
- package/src/commands/export.ts +0 -146
- package/src/commands/feedback.ts +0 -389
- package/src/commands/fix.ts +0 -324
- package/src/commands/fs/index.ts +0 -402
- package/src/commands/gcp/compute.ts +0 -325
- package/src/commands/gcp/functions.ts +0 -271
- package/src/commands/gcp/gke.ts +0 -438
- package/src/commands/gcp/iam.ts +0 -344
- package/src/commands/gcp/index.ts +0 -129
- package/src/commands/gcp/storage.ts +0 -284
- package/src/commands/generate-helm.ts +0 -1249
- package/src/commands/generate-k8s.ts +0 -1508
- package/src/commands/generate-terraform.ts +0 -1202
- package/src/commands/gh/index.ts +0 -863
- package/src/commands/git/index.ts +0 -1343
- package/src/commands/helm/index.ts +0 -1126
- package/src/commands/help.ts +0 -715
- package/src/commands/history.ts +0 -149
- package/src/commands/import.ts +0 -868
- package/src/commands/incident.ts +0 -166
- package/src/commands/index.ts +0 -367
- package/src/commands/init.ts +0 -1051
- package/src/commands/k8s/index.ts +0 -1137
- package/src/commands/login.ts +0 -716
- package/src/commands/logout.ts +0 -83
- package/src/commands/logs.ts +0 -167
- package/src/commands/onboarding.ts +0 -405
- package/src/commands/pipeline.ts +0 -186
- package/src/commands/plan/display.ts +0 -279
- package/src/commands/plan/index.ts +0 -599
- package/src/commands/plugin.ts +0 -398
- package/src/commands/preview.ts +0 -452
- package/src/commands/profile.ts +0 -342
- package/src/commands/questionnaire.ts +0 -1172
- package/src/commands/resume.ts +0 -47
- package/src/commands/rollback.ts +0 -315
- package/src/commands/rollout.ts +0 -88
- package/src/commands/runbook.ts +0 -346
- package/src/commands/schedule.ts +0 -236
- package/src/commands/status.ts +0 -252
- package/src/commands/team/index.ts +0 -346
- package/src/commands/team-context.ts +0 -220
- package/src/commands/template.ts +0 -233
- package/src/commands/tf/index.ts +0 -1093
- package/src/commands/upgrade.ts +0 -607
- package/src/commands/usage/index.ts +0 -134
- package/src/commands/version.ts +0 -174
- package/src/commands/watch.ts +0 -153
- package/src/compat/index.ts +0 -2
- package/src/compat/runtime.ts +0 -12
- package/src/compat/sqlite.ts +0 -177
- package/src/config/index.ts +0 -17
- package/src/config/manager.ts +0 -530
- package/src/config/mode-store.ts +0 -62
- package/src/config/profiles.ts +0 -84
- package/src/config/safety-policy.ts +0 -358
- package/src/config/schema.ts +0 -125
- package/src/config/types.ts +0 -609
- package/src/config/workspace-state.ts +0 -53
- package/src/context/context-db.ts +0 -199
- package/src/demo/index.ts +0 -349
- package/src/demo/scenarios/full-journey.ts +0 -229
- package/src/demo/scenarios/getting-started.ts +0 -127
- package/src/demo/scenarios/helm-release.ts +0 -341
- package/src/demo/scenarios/k8s-deployment.ts +0 -194
- package/src/demo/scenarios/terraform-vpc.ts +0 -170
- package/src/demo/types.ts +0 -92
- package/src/engine/cost-estimator.ts +0 -480
- package/src/engine/diagram-generator.ts +0 -256
- package/src/engine/drift-detector.ts +0 -902
- package/src/engine/executor.ts +0 -1066
- package/src/engine/index.ts +0 -76
- package/src/engine/orchestrator.ts +0 -636
- package/src/engine/planner.ts +0 -787
- package/src/engine/safety.ts +0 -743
- package/src/engine/verifier.ts +0 -770
- package/src/enterprise/audit.ts +0 -348
- package/src/enterprise/auth.ts +0 -270
- package/src/enterprise/billing.ts +0 -822
- package/src/enterprise/index.ts +0 -17
- package/src/enterprise/teams.ts +0 -443
- package/src/generator/best-practices.ts +0 -1608
- package/src/generator/helm.ts +0 -630
- package/src/generator/index.ts +0 -37
- package/src/generator/intent-parser.ts +0 -514
- package/src/generator/kubernetes.ts +0 -976
- package/src/generator/terraform.ts +0 -1875
- package/src/history/index.ts +0 -8
- package/src/history/manager.ts +0 -250
- package/src/history/types.ts +0 -34
- package/src/hooks/config.ts +0 -432
- package/src/hooks/engine.ts +0 -392
- package/src/hooks/index.ts +0 -4
- package/src/llm/auth-bridge.ts +0 -198
- package/src/llm/circuit-breaker.ts +0 -140
- package/src/llm/config-loader.ts +0 -201
- package/src/llm/cost-calculator.ts +0 -171
- package/src/llm/index.ts +0 -8
- package/src/llm/model-aliases.ts +0 -115
- package/src/llm/provider-registry.ts +0 -63
- package/src/llm/providers/anthropic.ts +0 -462
- package/src/llm/providers/bedrock.ts +0 -477
- package/src/llm/providers/google.ts +0 -405
- package/src/llm/providers/ollama.ts +0 -767
- package/src/llm/providers/openai-compatible.ts +0 -340
- package/src/llm/providers/openai.ts +0 -328
- package/src/llm/providers/openrouter.ts +0 -338
- package/src/llm/router.ts +0 -1104
- package/src/llm/types.ts +0 -232
- package/src/lsp/client.ts +0 -298
- package/src/lsp/languages.ts +0 -119
- package/src/lsp/manager.ts +0 -294
- package/src/mcp/client.ts +0 -402
- package/src/mcp/index.ts +0 -5
- package/src/mcp/manager.ts +0 -133
- package/src/nimbus.ts +0 -233
- package/src/plugins/index.ts +0 -27
- package/src/plugins/loader.ts +0 -334
- package/src/plugins/manager.ts +0 -376
- package/src/plugins/types.ts +0 -284
- package/src/scanners/cicd-scanner.ts +0 -258
- package/src/scanners/cloud-scanner.ts +0 -466
- package/src/scanners/framework-scanner.ts +0 -469
- package/src/scanners/iac-scanner.ts +0 -388
- package/src/scanners/index.ts +0 -539
- package/src/scanners/language-scanner.ts +0 -276
- package/src/scanners/package-manager-scanner.ts +0 -277
- package/src/scanners/types.ts +0 -172
- package/src/sessions/manager.ts +0 -472
- package/src/sessions/types.ts +0 -44
- package/src/sharing/sync.ts +0 -300
- package/src/sharing/viewer.ts +0 -163
- package/src/snapshots/index.ts +0 -2
- package/src/snapshots/manager.ts +0 -530
- package/src/state/artifacts.ts +0 -147
- package/src/state/audit.ts +0 -137
- package/src/state/billing.ts +0 -240
- package/src/state/checkpoints.ts +0 -117
- package/src/state/config.ts +0 -67
- package/src/state/conversations.ts +0 -14
- package/src/state/credentials.ts +0 -154
- package/src/state/db.ts +0 -58
- package/src/state/index.ts +0 -26
- package/src/state/messages.ts +0 -115
- package/src/state/projects.ts +0 -123
- package/src/state/schema.ts +0 -236
- package/src/state/sessions.ts +0 -147
- package/src/state/teams.ts +0 -200
- package/src/telemetry.ts +0 -108
- package/src/tools/aws-ops.ts +0 -952
- package/src/tools/azure-ops.ts +0 -579
- package/src/tools/file-ops.ts +0 -615
- package/src/tools/gcp-ops.ts +0 -625
- package/src/tools/git-ops.ts +0 -773
- package/src/tools/github-ops.ts +0 -799
- package/src/tools/helm-ops.ts +0 -943
- package/src/tools/index.ts +0 -17
- package/src/tools/k8s-ops.ts +0 -819
- package/src/tools/schemas/converter.ts +0 -184
- package/src/tools/schemas/devops.ts +0 -3502
- package/src/tools/schemas/index.ts +0 -73
- package/src/tools/schemas/standard.ts +0 -1148
- package/src/tools/schemas/types.ts +0 -735
- package/src/tools/spawn-exec.ts +0 -148
- package/src/tools/terraform-ops.ts +0 -862
- package/src/types/ambient.d.ts +0 -193
- package/src/types/config.ts +0 -83
- package/src/types/drift.ts +0 -116
- package/src/types/enterprise.ts +0 -335
- package/src/types/index.ts +0 -20
- package/src/types/plan.ts +0 -44
- package/src/types/request.ts +0 -65
- package/src/types/response.ts +0 -54
- package/src/types/service.ts +0 -51
- package/src/ui/App.tsx +0 -2114
- package/src/ui/DeployPreview.tsx +0 -174
- package/src/ui/FileDiffModal.tsx +0 -162
- package/src/ui/Header.tsx +0 -131
- package/src/ui/HelpModal.tsx +0 -57
- package/src/ui/InputBox.tsx +0 -503
- package/src/ui/MessageList.tsx +0 -1032
- package/src/ui/PermissionPrompt.tsx +0 -163
- package/src/ui/StatusBar.tsx +0 -277
- package/src/ui/TerminalPane.tsx +0 -84
- package/src/ui/ToolCallDisplay.tsx +0 -643
- package/src/ui/TreePane.tsx +0 -132
- package/src/ui/chat-ui.ts +0 -850
- package/src/ui/index.ts +0 -33
- package/src/ui/ink/index.ts +0 -1444
- package/src/ui/streaming.ts +0 -176
- package/src/ui/theme.ts +0 -104
- package/src/ui/types.ts +0 -75
- package/src/utils/analytics.ts +0 -72
- package/src/utils/cost-warning.ts +0 -27
- package/src/utils/env.ts +0 -46
- package/src/utils/errors.ts +0 -69
- package/src/utils/event-bus.ts +0 -38
- package/src/utils/index.ts +0 -24
- package/src/utils/logger.ts +0 -171
- package/src/utils/rate-limiter.ts +0 -121
- package/src/utils/service-auth.ts +0 -49
- package/src/utils/validation.ts +0 -53
- package/src/version.ts +0 -4
- package/src/watcher/index.ts +0 -214
- package/src/wizard/approval.ts +0 -383
- package/src/wizard/index.ts +0 -25
- package/src/wizard/prompts.ts +0 -338
- package/src/wizard/types.ts +0 -172
- package/src/wizard/ui.ts +0 -556
- package/src/wizard/wizard.ts +0 -304
- package/tsconfig.json +0 -24
|
@@ -1,433 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for the generator modules:
|
|
3
|
-
* - src/generator/terraform.ts – TerraformProjectGenerator
|
|
4
|
-
* - src/generator/kubernetes.ts – KubernetesGenerator, createKubernetesGenerator
|
|
5
|
-
* - src/generator/helm.ts – HelmGenerator, createHelmGenerator
|
|
6
|
-
* - src/generator/best-practices.ts – BestPracticesEngine
|
|
7
|
-
*
|
|
8
|
-
* All generators are pure (no I/O beyond the in-process YAML serialiser), so
|
|
9
|
-
* tests run entirely in-memory and complete in milliseconds.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { describe, it, expect } from 'vitest';
|
|
13
|
-
import { TerraformProjectGenerator, type TerraformProjectConfig } from '../generator/terraform';
|
|
14
|
-
import {
|
|
15
|
-
KubernetesGenerator,
|
|
16
|
-
createKubernetesGenerator,
|
|
17
|
-
type K8sGeneratorConfig,
|
|
18
|
-
} from '../generator/kubernetes';
|
|
19
|
-
import { HelmGenerator, createHelmGenerator, type HelmChartConfig } from '../generator/helm';
|
|
20
|
-
import { BestPracticesEngine } from '../generator/best-practices';
|
|
21
|
-
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
// TerraformProjectGenerator
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
|
|
26
|
-
describe('TerraformProjectGenerator', () => {
|
|
27
|
-
const baseConfig: TerraformProjectConfig = {
|
|
28
|
-
projectName: 'test-project',
|
|
29
|
-
provider: 'aws',
|
|
30
|
-
region: 'us-east-1',
|
|
31
|
-
components: ['vpc', 's3'],
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
it('can be instantiated', () => {
|
|
35
|
-
const gen = new TerraformProjectGenerator();
|
|
36
|
-
expect(gen).toBeInstanceOf(TerraformProjectGenerator);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('generate() returns a GeneratedProject with files array', async () => {
|
|
40
|
-
const gen = new TerraformProjectGenerator();
|
|
41
|
-
const result = await gen.generate(baseConfig);
|
|
42
|
-
|
|
43
|
-
expect(result).toBeDefined();
|
|
44
|
-
expect(Array.isArray(result.files)).toBe(true);
|
|
45
|
-
expect(result.files.length).toBeGreaterThan(0);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('generates the required root .tf files', async () => {
|
|
49
|
-
const gen = new TerraformProjectGenerator();
|
|
50
|
-
const { files } = await gen.generate(baseConfig);
|
|
51
|
-
const paths = files.map(f => f.path);
|
|
52
|
-
|
|
53
|
-
expect(paths).toContain('main.tf');
|
|
54
|
-
expect(paths).toContain('variables.tf');
|
|
55
|
-
expect(paths).toContain('outputs.tf');
|
|
56
|
-
expect(paths).toContain('versions.tf');
|
|
57
|
-
expect(paths).toContain('backend.tf');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('generates environment-specific tfvars files', async () => {
|
|
61
|
-
const gen = new TerraformProjectGenerator();
|
|
62
|
-
const { files } = await gen.generate(baseConfig);
|
|
63
|
-
const paths = files.map(f => f.path);
|
|
64
|
-
|
|
65
|
-
expect(paths).toContain('environments/dev/terraform.tfvars');
|
|
66
|
-
expect(paths).toContain('environments/staging/terraform.tfvars');
|
|
67
|
-
expect(paths).toContain('environments/prod/terraform.tfvars');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('generates module files for each requested component', async () => {
|
|
71
|
-
const gen = new TerraformProjectGenerator();
|
|
72
|
-
const { files } = await gen.generate(baseConfig);
|
|
73
|
-
const paths = files.map(f => f.path);
|
|
74
|
-
|
|
75
|
-
// vpc component
|
|
76
|
-
expect(paths).toContain('modules/vpc/main.tf');
|
|
77
|
-
expect(paths).toContain('modules/vpc/variables.tf');
|
|
78
|
-
expect(paths).toContain('modules/vpc/outputs.tf');
|
|
79
|
-
|
|
80
|
-
// s3 component
|
|
81
|
-
expect(paths).toContain('modules/s3/main.tf');
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('generates a .gitignore file', async () => {
|
|
85
|
-
const gen = new TerraformProjectGenerator();
|
|
86
|
-
const { files } = await gen.generate(baseConfig);
|
|
87
|
-
const gitignore = files.find(f => f.path === '.gitignore');
|
|
88
|
-
|
|
89
|
-
expect(gitignore).toBeDefined();
|
|
90
|
-
expect(gitignore!.content).toContain('.terraform/');
|
|
91
|
-
expect(gitignore!.content).toContain('*.tfstate');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('validation report is valid when all required files are present', async () => {
|
|
95
|
-
const gen = new TerraformProjectGenerator();
|
|
96
|
-
const { validation } = await gen.generate(baseConfig);
|
|
97
|
-
|
|
98
|
-
expect(validation).toBeDefined();
|
|
99
|
-
expect(typeof validation.valid).toBe('boolean');
|
|
100
|
-
expect(typeof validation.summary.errors).toBe('number');
|
|
101
|
-
expect(typeof validation.summary.warnings).toBe('number');
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('generated main.tf contains the provider block', async () => {
|
|
105
|
-
const gen = new TerraformProjectGenerator();
|
|
106
|
-
const { files } = await gen.generate(baseConfig);
|
|
107
|
-
const mainTf = files.find(f => f.path === 'main.tf');
|
|
108
|
-
|
|
109
|
-
expect(mainTf).toBeDefined();
|
|
110
|
-
expect(mainTf!.content).toContain('provider "aws"');
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('generateGitignore() is callable as a standalone method', () => {
|
|
114
|
-
const gen = new TerraformProjectGenerator();
|
|
115
|
-
const file = gen.generateGitignore();
|
|
116
|
-
expect(file.path).toBe('.gitignore');
|
|
117
|
-
expect(file.content.length).toBeGreaterThan(0);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('validateProject() returns a ValidationReport', () => {
|
|
121
|
-
const gen = new TerraformProjectGenerator();
|
|
122
|
-
const report = gen.validateProject([
|
|
123
|
-
{ path: 'main.tf', content: 'provider "aws" {}' },
|
|
124
|
-
{ path: 'variables.tf', content: '' },
|
|
125
|
-
{ path: 'outputs.tf', content: '' },
|
|
126
|
-
{ path: 'versions.tf', content: '' },
|
|
127
|
-
{ path: 'backend.tf', content: '' },
|
|
128
|
-
]);
|
|
129
|
-
|
|
130
|
-
expect(typeof report.valid).toBe('boolean');
|
|
131
|
-
expect(Array.isArray(report.items)).toBe(true);
|
|
132
|
-
expect(typeof report.summary.errors).toBe('number');
|
|
133
|
-
expect(typeof report.summary.warnings).toBe('number');
|
|
134
|
-
expect(typeof report.summary.info).toBe('number');
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// ---------------------------------------------------------------------------
|
|
139
|
-
// KubernetesGenerator
|
|
140
|
-
// ---------------------------------------------------------------------------
|
|
141
|
-
|
|
142
|
-
describe('KubernetesGenerator', () => {
|
|
143
|
-
const baseK8sConfig: K8sGeneratorConfig = {
|
|
144
|
-
appName: 'my-app',
|
|
145
|
-
workloadType: 'deployment',
|
|
146
|
-
image: 'nginx',
|
|
147
|
-
imageTag: '1.25',
|
|
148
|
-
replicas: 2,
|
|
149
|
-
containerPort: 8080,
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
it('can be instantiated directly', () => {
|
|
153
|
-
const gen = new KubernetesGenerator(baseK8sConfig);
|
|
154
|
-
expect(gen).toBeInstanceOf(KubernetesGenerator);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('can be created via the factory function', () => {
|
|
158
|
-
const gen = createKubernetesGenerator(baseK8sConfig);
|
|
159
|
-
expect(gen).toBeInstanceOf(KubernetesGenerator);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('generate() returns an array of GeneratedManifest objects', () => {
|
|
163
|
-
const gen = new KubernetesGenerator(baseK8sConfig);
|
|
164
|
-
const manifests = gen.generate();
|
|
165
|
-
|
|
166
|
-
expect(Array.isArray(manifests)).toBe(true);
|
|
167
|
-
expect(manifests.length).toBeGreaterThan(0);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('manifests contain a Deployment', () => {
|
|
171
|
-
const gen = new KubernetesGenerator(baseK8sConfig);
|
|
172
|
-
const manifests = gen.generate();
|
|
173
|
-
const deployment = manifests.find(m => m.kind === 'Deployment');
|
|
174
|
-
|
|
175
|
-
expect(deployment).toBeDefined();
|
|
176
|
-
expect(deployment!.content).toContain('kind: Deployment');
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('manifests contain a Service when serviceType is not None', () => {
|
|
180
|
-
const gen = new KubernetesGenerator({ ...baseK8sConfig, serviceType: 'ClusterIP' });
|
|
181
|
-
const manifests = gen.generate();
|
|
182
|
-
const service = manifests.find(m => m.kind === 'Service');
|
|
183
|
-
|
|
184
|
-
expect(service).toBeDefined();
|
|
185
|
-
expect(service!.content).toContain('kind: Service');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('no Service manifest is generated when serviceType is None', () => {
|
|
189
|
-
const gen = new KubernetesGenerator({ ...baseK8sConfig, serviceType: 'None' });
|
|
190
|
-
const manifests = gen.generate();
|
|
191
|
-
const service = manifests.find(m => m.kind === 'Service');
|
|
192
|
-
expect(service).toBeUndefined();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('generateCombined() returns a YAML string with --- separators', () => {
|
|
196
|
-
const gen = new KubernetesGenerator(baseK8sConfig);
|
|
197
|
-
const combined = gen.generateCombined();
|
|
198
|
-
|
|
199
|
-
expect(typeof combined).toBe('string');
|
|
200
|
-
expect(combined.length).toBeGreaterThan(0);
|
|
201
|
-
expect(combined).toContain('---');
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it('Deployment manifest includes the correct image and replicas', () => {
|
|
205
|
-
const gen = new KubernetesGenerator(baseK8sConfig);
|
|
206
|
-
const manifests = gen.generate();
|
|
207
|
-
const deployment = manifests.find(m => m.kind === 'Deployment');
|
|
208
|
-
|
|
209
|
-
expect(deployment!.content).toContain('nginx:1.25');
|
|
210
|
-
expect(deployment!.content).toContain('replicas: 2');
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('generates Namespace manifest when namespace is not "default"', () => {
|
|
214
|
-
const gen = new KubernetesGenerator({ ...baseK8sConfig, namespace: 'production' });
|
|
215
|
-
const manifests = gen.generate();
|
|
216
|
-
const ns = manifests.find(m => m.kind === 'Namespace');
|
|
217
|
-
|
|
218
|
-
expect(ns).toBeDefined();
|
|
219
|
-
expect(ns!.content).toContain('name: production');
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
it('generates HPA manifest when hpa.enabled is true', () => {
|
|
223
|
-
const gen = new KubernetesGenerator({
|
|
224
|
-
...baseK8sConfig,
|
|
225
|
-
hpa: { enabled: true, minReplicas: 2, maxReplicas: 10 },
|
|
226
|
-
});
|
|
227
|
-
const manifests = gen.generate();
|
|
228
|
-
const hpa = manifests.find(m => m.kind === 'HorizontalPodAutoscaler');
|
|
229
|
-
|
|
230
|
-
expect(hpa).toBeDefined();
|
|
231
|
-
expect(hpa!.content).toContain('HorizontalPodAutoscaler');
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// ---------------------------------------------------------------------------
|
|
236
|
-
// HelmGenerator
|
|
237
|
-
// ---------------------------------------------------------------------------
|
|
238
|
-
|
|
239
|
-
describe('HelmGenerator', () => {
|
|
240
|
-
const baseHelmConfig: HelmChartConfig = {
|
|
241
|
-
name: 'my-chart',
|
|
242
|
-
version: '1.0.0',
|
|
243
|
-
appVersion: '2.0.0',
|
|
244
|
-
description: 'A test Helm chart',
|
|
245
|
-
values: {
|
|
246
|
-
image: {
|
|
247
|
-
repository: 'my-org/my-app',
|
|
248
|
-
tag: 'latest',
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
it('can be instantiated directly', () => {
|
|
254
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
255
|
-
expect(gen).toBeInstanceOf(HelmGenerator);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('can be created via the factory function', () => {
|
|
259
|
-
const gen = createHelmGenerator(baseHelmConfig);
|
|
260
|
-
expect(gen).toBeInstanceOf(HelmGenerator);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
it('generate() returns an array of GeneratedFile objects', () => {
|
|
264
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
265
|
-
const files = gen.generate();
|
|
266
|
-
|
|
267
|
-
expect(Array.isArray(files)).toBe(true);
|
|
268
|
-
expect(files.length).toBeGreaterThan(0);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('includes Chart.yaml in the generated files', () => {
|
|
272
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
273
|
-
const files = gen.generate();
|
|
274
|
-
const chart = files.find(f => f.path === 'Chart.yaml');
|
|
275
|
-
|
|
276
|
-
expect(chart).toBeDefined();
|
|
277
|
-
expect(chart!.content).toContain('name: my-chart');
|
|
278
|
-
expect(chart!.content).toContain('version: 1.0.0');
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
it('includes values.yaml in the generated files', () => {
|
|
282
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
283
|
-
const files = gen.generate();
|
|
284
|
-
const values = files.find(f => f.path === 'values.yaml');
|
|
285
|
-
|
|
286
|
-
expect(values).toBeDefined();
|
|
287
|
-
expect(values!.content).toContain('repository: my-org/my-app');
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it('includes a deployment template', () => {
|
|
291
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
292
|
-
const files = gen.generate();
|
|
293
|
-
const deployment = files.find(f => f.path === 'templates/deployment.yaml');
|
|
294
|
-
|
|
295
|
-
expect(deployment).toBeDefined();
|
|
296
|
-
expect(deployment!.content).toContain('kind: Deployment');
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it('includes a service template', () => {
|
|
300
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
301
|
-
const files = gen.generate();
|
|
302
|
-
const service = files.find(f => f.path === 'templates/service.yaml');
|
|
303
|
-
|
|
304
|
-
expect(service).toBeDefined();
|
|
305
|
-
expect(service!.content).toContain('kind: Service');
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
it('includes a _helpers.tpl template', () => {
|
|
309
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
310
|
-
const files = gen.generate();
|
|
311
|
-
const helpers = files.find(f => f.path === 'templates/_helpers.tpl');
|
|
312
|
-
|
|
313
|
-
expect(helpers).toBeDefined();
|
|
314
|
-
expect(helpers!.content).toContain('define "my-chart.name"');
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it('Chart.yaml contains the appVersion field', () => {
|
|
318
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
319
|
-
const files = gen.generate();
|
|
320
|
-
const chart = files.find(f => f.path === 'Chart.yaml');
|
|
321
|
-
|
|
322
|
-
expect(chart!.content).toContain('appVersion:');
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it('includes .helmignore', () => {
|
|
326
|
-
const gen = new HelmGenerator(baseHelmConfig);
|
|
327
|
-
const files = gen.generate();
|
|
328
|
-
const helmignore = files.find(f => f.path === '.helmignore');
|
|
329
|
-
|
|
330
|
-
expect(helmignore).toBeDefined();
|
|
331
|
-
expect(helmignore!.content).toContain('.git/');
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
// ---------------------------------------------------------------------------
|
|
336
|
-
// BestPracticesEngine
|
|
337
|
-
// ---------------------------------------------------------------------------
|
|
338
|
-
|
|
339
|
-
describe('BestPracticesEngine', () => {
|
|
340
|
-
it('can be instantiated with no arguments', () => {
|
|
341
|
-
const engine = new BestPracticesEngine();
|
|
342
|
-
expect(engine).toBeInstanceOf(BestPracticesEngine);
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
it('can be instantiated with custom rules', () => {
|
|
346
|
-
const customRule = {
|
|
347
|
-
id: 'custom-001',
|
|
348
|
-
category: 'security' as const,
|
|
349
|
-
severity: 'low' as const,
|
|
350
|
-
title: 'Custom Rule',
|
|
351
|
-
description: 'A test custom rule',
|
|
352
|
-
recommendation: 'Do something',
|
|
353
|
-
applies_to: ['vpc'],
|
|
354
|
-
check: (_config: Record<string, unknown>) => true,
|
|
355
|
-
};
|
|
356
|
-
const engine = new BestPracticesEngine([customRule]);
|
|
357
|
-
expect(engine).toBeInstanceOf(BestPracticesEngine);
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
it('listRules() returns an array with at least one rule', () => {
|
|
361
|
-
const engine = new BestPracticesEngine();
|
|
362
|
-
const rules = engine.listRules();
|
|
363
|
-
expect(Array.isArray(rules)).toBe(true);
|
|
364
|
-
expect(rules.length).toBeGreaterThan(0);
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
it('getRule() returns the rule for a known ID', () => {
|
|
368
|
-
const engine = new BestPracticesEngine();
|
|
369
|
-
const rule = engine.getRule('sec-001');
|
|
370
|
-
expect(rule).toBeDefined();
|
|
371
|
-
expect(rule!.id).toBe('sec-001');
|
|
372
|
-
expect(rule!.category).toBe('security');
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
it('getRule() returns undefined for an unknown rule ID', () => {
|
|
376
|
-
const engine = new BestPracticesEngine();
|
|
377
|
-
expect(engine.getRule('does-not-exist')).toBeUndefined();
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it('analyze() returns a BestPracticeReport with summary and violations', () => {
|
|
381
|
-
const engine = new BestPracticesEngine();
|
|
382
|
-
// An s3 config that deliberately violates encryption and public-access rules
|
|
383
|
-
const badConfig: Record<string, unknown> = {
|
|
384
|
-
storage_encrypted: false,
|
|
385
|
-
block_public_acls: false,
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
const report = engine.analyze('s3', badConfig);
|
|
389
|
-
|
|
390
|
-
expect(report).toBeDefined();
|
|
391
|
-
expect(typeof report.summary.total_rules_checked).toBe('number');
|
|
392
|
-
expect(typeof report.summary.violations_found).toBe('number');
|
|
393
|
-
expect(Array.isArray(report.violations)).toBe(true);
|
|
394
|
-
expect(Array.isArray(report.recommendations)).toBe(true);
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
it('analyze() with a fully compliant config produces fewer violations', () => {
|
|
398
|
-
const engine = new BestPracticesEngine();
|
|
399
|
-
|
|
400
|
-
const badReport = engine.analyze('s3', {});
|
|
401
|
-
const goodReport = engine.analyze('s3', {
|
|
402
|
-
storage_encrypted: true,
|
|
403
|
-
encryption_enabled: true,
|
|
404
|
-
block_public_acls: true,
|
|
405
|
-
block_public_policy: true,
|
|
406
|
-
ignore_public_acls: true,
|
|
407
|
-
restrict_public_buckets: true,
|
|
408
|
-
enable_versioning: true,
|
|
409
|
-
enable_lifecycle_rules: true,
|
|
410
|
-
abort_incomplete_multipart_days: 7,
|
|
411
|
-
enable_access_logging: true,
|
|
412
|
-
sse_algorithm: 'aws:kms',
|
|
413
|
-
tags: { Environment: 'dev', ManagedBy: 'Terraform', Project: 'test' },
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
expect(goodReport.summary.violations_found).toBeLessThan(badReport.summary.violations_found);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
it('getComplianceScore() returns 100 when no rules apply', () => {
|
|
420
|
-
const engine = new BestPracticesEngine();
|
|
421
|
-
const report = engine.analyze('nonexistent-component', {});
|
|
422
|
-
const score = engine.getComplianceScore(report);
|
|
423
|
-
expect(score).toBe(100);
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it('formatReportAsMarkdown() returns a markdown string', () => {
|
|
427
|
-
const engine = new BestPracticesEngine();
|
|
428
|
-
const report = engine.analyze('vpc', {});
|
|
429
|
-
const md = engine.formatReportAsMarkdown(report);
|
|
430
|
-
expect(typeof md).toBe('string');
|
|
431
|
-
expect(md).toContain('# Best Practices Report');
|
|
432
|
-
});
|
|
433
|
-
});
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Helm Streaming Tests — G10
|
|
3
|
-
*
|
|
4
|
-
* Verifies that:
|
|
5
|
-
* 1. devops.ts defines the HELM_STREAMING_ACTIONS set with the correct members
|
|
6
|
-
* 2. spawnExec is imported (not execAsync) for streaming actions
|
|
7
|
-
* 3. The helmTool.execute() calls spawnExec for upgrade/install actions
|
|
8
|
-
*
|
|
9
|
-
* The functional test mocks both spawnExec and the execAsync (helm repo update)
|
|
10
|
-
* by mocking 'node:child_process' at the top level.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
14
|
-
import { readFileSync } from 'node:fs';
|
|
15
|
-
import { join } from 'node:path';
|
|
16
|
-
|
|
17
|
-
const DEVOPS_SRC = readFileSync(join(__dirname, '..', 'tools', 'schemas', 'devops.ts'), 'utf-8');
|
|
18
|
-
|
|
19
|
-
// ---------------------------------------------------------------------------
|
|
20
|
-
// Top-level mocks — must be hoisted by vitest before imports
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
// Mock spawnExec so streaming helm actions don't attempt real shell calls
|
|
24
|
-
vi.mock('../tools/spawn-exec', () => ({
|
|
25
|
-
spawnExec: vi.fn().mockResolvedValue({ stdout: 'Release deployed successfully', stderr: '', exitCode: 0 }),
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
|
-
// Mock node:child_process exec so execAsync('helm repo update') doesn't fail
|
|
29
|
-
vi.mock('node:child_process', async () => {
|
|
30
|
-
const actual = await vi.importActual<typeof import('node:child_process')>('node:child_process');
|
|
31
|
-
return {
|
|
32
|
-
...actual,
|
|
33
|
-
exec: vi.fn((cmd: string, opts: unknown, cb?: (err: null, result: { stdout: string; stderr: string }) => void) => {
|
|
34
|
-
// Handle promisify(exec) — callback style
|
|
35
|
-
const callback = typeof opts === 'function' ? opts : cb;
|
|
36
|
-
if (typeof callback === 'function') {
|
|
37
|
-
(callback as (err: null, result: { stdout: string; stderr: string }) => void)(null, { stdout: '', stderr: '' });
|
|
38
|
-
}
|
|
39
|
-
return { on: vi.fn(), stdout: { on: vi.fn() }, stderr: { on: vi.fn() } };
|
|
40
|
-
}),
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// Source-level assertions (G10)
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
|
|
48
|
-
describe('HELM_STREAMING_ACTIONS constant in devops.ts (G10)', () => {
|
|
49
|
-
it('devops.ts defines HELM_STREAMING_ACTIONS', () => {
|
|
50
|
-
expect(DEVOPS_SRC).toContain('HELM_STREAMING_ACTIONS');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('HELM_STREAMING_ACTIONS includes install', () => {
|
|
54
|
-
const setDefMatch = DEVOPS_SRC.match(/HELM_STREAMING_ACTIONS\s*=\s*new Set\(\[([^\]]+)\]\)/);
|
|
55
|
-
expect(setDefMatch).not.toBeNull();
|
|
56
|
-
expect(setDefMatch![1]).toContain('install');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('HELM_STREAMING_ACTIONS includes upgrade', () => {
|
|
60
|
-
const setDefMatch = DEVOPS_SRC.match(/HELM_STREAMING_ACTIONS\s*=\s*new Set\(\[([^\]]+)\]\)/);
|
|
61
|
-
expect(setDefMatch).not.toBeNull();
|
|
62
|
-
expect(setDefMatch![1]).toContain('upgrade');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('HELM_STREAMING_ACTIONS includes rollback', () => {
|
|
66
|
-
const setDefMatch = DEVOPS_SRC.match(/HELM_STREAMING_ACTIONS\s*=\s*new Set\(\[([^\]]+)\]\)/);
|
|
67
|
-
expect(setDefMatch).not.toBeNull();
|
|
68
|
-
expect(setDefMatch![1]).toContain('rollback');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('HELM_STREAMING_ACTIONS includes uninstall', () => {
|
|
72
|
-
const setDefMatch = DEVOPS_SRC.match(/HELM_STREAMING_ACTIONS\s*=\s*new Set\(\[([^\]]+)\]\)/);
|
|
73
|
-
expect(setDefMatch).not.toBeNull();
|
|
74
|
-
expect(setDefMatch![1]).toContain('uninstall');
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe('spawnExec is imported in devops.ts (G10)', () => {
|
|
79
|
-
it('devops.ts imports spawnExec from spawn-exec', () => {
|
|
80
|
-
expect(DEVOPS_SRC).toContain("import { spawnExec } from '../spawn-exec'");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('devops.ts uses spawnExec for helm streaming actions (not only execAsync)', () => {
|
|
84
|
-
expect(DEVOPS_SRC).toContain('await spawnExec(command');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('helm streaming block checks HELM_STREAMING_ACTIONS.has(input.action)', () => {
|
|
88
|
-
expect(DEVOPS_SRC).toContain('HELM_STREAMING_ACTIONS.has(input.action)');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
// Functional test: spawnExec mock for streaming action
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
|
-
|
|
96
|
-
describe('helmTool routes to spawnExec for streaming actions (G10)', () => {
|
|
97
|
-
afterEach(() => {
|
|
98
|
-
vi.clearAllMocks();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('calls spawnExec for upgrade action and returns success', async () => {
|
|
102
|
-
const { spawnExec } = await import('../tools/spawn-exec');
|
|
103
|
-
const { helmTool } = await import('../tools/schemas/devops');
|
|
104
|
-
|
|
105
|
-
const result = await helmTool.execute(
|
|
106
|
-
{ action: 'upgrade', release: 'myapp', chart: 'stable/nginx', namespace: 'default' },
|
|
107
|
-
undefined,
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
expect(spawnExec).toHaveBeenCalled();
|
|
111
|
-
expect(result.isError).toBe(false);
|
|
112
|
-
expect(result.output).toContain('deployed successfully');
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('calls spawnExec for install action and returns success', async () => {
|
|
116
|
-
const { spawnExec } = await import('../tools/spawn-exec');
|
|
117
|
-
const { helmTool } = await import('../tools/schemas/devops');
|
|
118
|
-
|
|
119
|
-
const result = await helmTool.execute(
|
|
120
|
-
{ action: 'install', release: 'myapp', chart: 'bitnami/nginx' },
|
|
121
|
-
undefined,
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
expect(spawnExec).toHaveBeenCalled();
|
|
125
|
-
expect(result.isError).toBe(false);
|
|
126
|
-
});
|
|
127
|
-
});
|