@skyramp/mcp 0.3.2-rc.pom-3 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/build/commands/commandLibrary.d.ts +1 -0
  2. package/build/commands/commandLibrary.js +19 -13
  3. package/build/commands/localDevTestChangesCommand.d.ts +15 -0
  4. package/build/commands/localDevTestChangesCommand.js +201 -0
  5. package/build/index.js +80 -6
  6. package/build/prompts/code-reuse.js +3 -0
  7. package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +1 -0
  8. package/build/prompts/enhance-assertions/sharedAssertionRules.js +17 -0
  9. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +11 -9
  10. package/build/prompts/local-dev/local-dev-plan.d.ts +35 -0
  11. package/build/prompts/local-dev/local-dev-plan.js +429 -0
  12. package/build/prompts/local-dev/local-dev-prompts.d.ts +4 -0
  13. package/build/prompts/local-dev/local-dev-prompts.js +190 -0
  14. package/build/prompts/pom-aware-code-reuse.js +12 -0
  15. package/build/prompts/prompt-utils.d.ts +8 -0
  16. package/build/prompts/prompt-utils.js +33 -0
  17. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +37 -14
  18. package/build/prompts/sut-setup/shared.js +16 -12
  19. package/build/prompts/test-recommendation/analysisOutputPrompt.js +21 -29
  20. package/build/prompts/test-recommendation/scopeAssessment.d.ts +24 -7
  21. package/build/prompts/test-recommendation/scopeAssessment.js +111 -12
  22. package/build/prompts/test-recommendation/test-recommendation-prompt.js +41 -4
  23. package/build/prompts/testbot/testbot-prompts.d.ts +0 -5
  24. package/build/prompts/testbot/testbot-prompts.js +32 -52
  25. package/build/recommendation/planRanker.d.ts +15 -2
  26. package/build/recommendation/planRanker.js +76 -5
  27. package/build/resources/testbotResource.js +2 -1
  28. package/build/services/AnalyticsService.d.ts +1 -1
  29. package/build/services/TestExecutionService.d.ts +2 -1
  30. package/build/services/TestExecutionService.js +8 -3
  31. package/build/services/TestGenerationService.d.ts +2 -2
  32. package/build/services/TestGenerationService.js +39 -21
  33. package/build/services/containerEnv.js +3 -1
  34. package/build/tool-phases.js +6 -0
  35. package/build/tools/code-refactor/codeReuseTool.js +43 -4
  36. package/build/tools/code-refactor/enhanceAssertionsTool.js +68 -18
  37. package/build/tools/code-refactor/reuse-outcome.d.ts +109 -0
  38. package/build/tools/code-refactor/reuse-outcome.js +158 -0
  39. package/build/tools/code-refactor/reuse-state.d.ts +45 -0
  40. package/build/tools/code-refactor/reuse-state.js +140 -0
  41. package/build/tools/enrichTestWithMocksTool.d.ts +28 -0
  42. package/build/tools/enrichTestWithMocksTool.js +726 -0
  43. package/build/tools/executeSkyrampTestTool.d.ts +11 -0
  44. package/build/tools/executeSkyrampTestTool.js +62 -21
  45. package/build/tools/generate-tests/batchMockGenerationTool.d.ts +106 -0
  46. package/build/tools/generate-tests/batchMockGenerationTool.js +545 -0
  47. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +25 -23
  48. package/build/tools/generate-tests/generateContractRestTool.js +2 -2
  49. package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -1
  50. package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
  51. package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -1
  52. package/build/tools/generate-tests/generateLoadRestTool.js +1 -1
  53. package/build/tools/generate-tests/generateMockRestTool.d.ts +179 -6
  54. package/build/tools/generate-tests/generateMockRestTool.js +391 -22
  55. package/build/tools/generate-tests/loadTestSchema.d.ts +1 -1
  56. package/build/tools/generate-tests/planGuard.js +2 -22
  57. package/build/tools/generateEnrichedIntegrationTestTool.d.ts +25 -0
  58. package/build/tools/generateEnrichedIntegrationTestTool.js +235 -0
  59. package/build/tools/localDevWorkerComposeTool.d.ts +24 -0
  60. package/build/tools/localDevWorkerComposeTool.js +264 -0
  61. package/build/tools/one-click/oneClickTool.d.ts +13 -0
  62. package/build/tools/one-click/oneClickTool.js +195 -24
  63. package/build/tools/preflightMockCheckTool.d.ts +2 -0
  64. package/build/tools/preflightMockCheckTool.js +96 -0
  65. package/build/tools/queryProxyMocksTool.d.ts +70 -0
  66. package/build/tools/queryProxyMocksTool.js +522 -0
  67. package/build/tools/runExistingTestsTool.d.ts +31 -0
  68. package/build/tools/runExistingTestsTool.js +214 -13
  69. package/build/tools/submitReportTool.js +38 -3
  70. package/build/tools/test-management/analyzeChangesTool.d.ts +2 -1
  71. package/build/tools/test-management/analyzeChangesTool.js +63 -40
  72. package/build/tools/test-management/registerTestPlanTool.js +55 -7
  73. package/build/tools/trace/startTraceCollectionTool.js +3 -3
  74. package/build/types/FrontendIntegration.d.ts +3 -0
  75. package/build/types/FrontendIntegration.js +3 -0
  76. package/build/types/OneClickCommands.d.ts +1 -1
  77. package/build/types/Recommendation.d.ts +20 -0
  78. package/build/types/Recommendation.js +32 -6
  79. package/build/types/RepositoryAnalysis.d.ts +131 -14
  80. package/build/types/RepositoryAnalysis.js +16 -2
  81. package/build/types/ReuseOutcome.d.ts +63 -0
  82. package/build/types/ReuseOutcome.js +33 -0
  83. package/build/types/TestExecution.d.ts +1 -0
  84. package/build/types/TestTypes.d.ts +25 -7
  85. package/build/types/TestTypes.js +22 -6
  86. package/build/types/TestbotReport.d.ts +7 -0
  87. package/build/types/index.d.ts +2 -0
  88. package/build/types/index.js +1 -0
  89. package/build/utils/AnalysisStateManager.d.ts +26 -0
  90. package/build/utils/AnalysisStateManager.js +31 -1
  91. package/build/utils/analyze-openapi.js +18 -1
  92. package/build/utils/branchDiff.d.ts +17 -1
  93. package/build/utils/branchDiff.js +99 -14
  94. package/build/utils/featureFlags.d.ts +31 -0
  95. package/build/utils/featureFlags.js +37 -0
  96. package/build/utils/frontendIntegration.js +8 -1
  97. package/build/utils/grpcMockValidation.d.ts +1 -0
  98. package/build/utils/grpcMockValidation.js +49 -0
  99. package/build/utils/httpMethodValidation.d.ts +4 -0
  100. package/build/utils/httpMethodValidation.js +15 -0
  101. package/build/utils/logger.js +1 -1
  102. package/build/utils/mockCompatibility.d.ts +49 -0
  103. package/build/utils/mockCompatibility.js +82 -0
  104. package/build/utils/pom-scope/pom-files.js +7 -0
  105. package/build/utils/pom-verify/bindings.js +11 -1
  106. package/build/utils/pom-verify/re-exports.d.ts +10 -0
  107. package/build/utils/pom-verify/re-exports.js +61 -0
  108. package/build/utils/pom-verify/resolve.d.ts +4 -1
  109. package/build/utils/pom-verify/resolve.js +7 -4
  110. package/build/utils/pom-verify/verify.d.ts +5 -0
  111. package/build/utils/pom-verify/verify.js +25 -3
  112. package/build/utils/progress.js +10 -5
  113. package/build/utils/proxy-terminal.js +3 -3
  114. package/build/utils/routeParsers.d.ts +3 -9
  115. package/build/utils/routeParsers.js +79 -4
  116. package/build/utils/utils.js +2 -2
  117. package/build/utils/versions.d.ts +4 -3
  118. package/build/utils/versions.js +3 -1
  119. package/build/utils/workspaceAuth.d.ts +46 -0
  120. package/build/utils/workspaceAuth.js +156 -1
  121. package/build/workspace/testSuites.d.ts +2 -1
  122. package/build/workspace/testSuites.js +1 -1
  123. package/build/workspace/workspace.d.ts +108 -32
  124. package/build/workspace/workspace.js +32 -4
  125. package/package.json +5 -2
  126. package/build/adapters/jestAdapter.test.d.ts +0 -1
  127. package/build/adapters/jestAdapter.test.js +0 -93
  128. package/build/adapters/mochaAdapter.test.d.ts +0 -1
  129. package/build/adapters/mochaAdapter.test.js +0 -63
  130. package/build/adapters/playwrightAdapter.test.d.ts +0 -1
  131. package/build/adapters/playwrightAdapter.test.js +0 -169
  132. package/build/adapters/pytestAdapter.test.d.ts +0 -1
  133. package/build/adapters/pytestAdapter.test.js +0 -90
  134. package/build/prompts/code-reuse.test.d.ts +0 -1
  135. package/build/prompts/code-reuse.test.js +0 -62
  136. package/build/prompts/pom-aware-code-reuse.test.d.ts +0 -1
  137. package/build/prompts/pom-aware-code-reuse.test.js +0 -11
  138. package/build/prompts/test-maintenance/drift-analysis-prompt.test.d.ts +0 -1
  139. package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +0 -51
  140. package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +0 -1
  141. package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +0 -264
  142. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +0 -1
  143. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +0 -126
  144. package/build/prompts/test-recommendation/promptPlan.test.d.ts +0 -1
  145. package/build/prompts/test-recommendation/promptPlan.test.js +0 -336
  146. package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +0 -1
  147. package/build/prompts/test-recommendation/scopeAssessment.test.js +0 -371
  148. package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +0 -1
  149. package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +0 -1925
  150. package/build/prompts/testbot/testbot-prompts.test.d.ts +0 -1
  151. package/build/prompts/testbot/testbot-prompts.test.js +0 -451
  152. package/build/recommendation/budgeters/diversityBalancedBudgeter.test.d.ts +0 -1
  153. package/build/recommendation/budgeters/diversityBalancedBudgeter.test.js +0 -138
  154. package/build/recommendation/budgeters/fixedNBudgeter.test.d.ts +0 -1
  155. package/build/recommendation/budgeters/fixedNBudgeter.test.js +0 -66
  156. package/build/recommendation/discriminators.test.d.ts +0 -1
  157. package/build/recommendation/discriminators.test.js +0 -324
  158. package/build/recommendation/diversity.test.d.ts +0 -1
  159. package/build/recommendation/diversity.test.js +0 -77
  160. package/build/recommendation/planRanker.test.d.ts +0 -1
  161. package/build/recommendation/planRanker.test.js +0 -110
  162. package/build/resources/testbotResource.test.d.ts +0 -1
  163. package/build/resources/testbotResource.test.js +0 -44
  164. package/build/services/AnalyticsService.test.d.ts +0 -1
  165. package/build/services/AnalyticsService.test.js +0 -86
  166. package/build/services/ScenarioGenerationService.integration.test.d.ts +0 -1
  167. package/build/services/ScenarioGenerationService.integration.test.js +0 -162
  168. package/build/services/ScenarioGenerationService.test.d.ts +0 -1
  169. package/build/services/ScenarioGenerationService.test.js +0 -414
  170. package/build/services/TestDiscoveryService.test.d.ts +0 -1
  171. package/build/services/TestDiscoveryService.test.js +0 -983
  172. package/build/services/TestExecutionService.test.d.ts +0 -1
  173. package/build/services/TestExecutionService.test.js +0 -1032
  174. package/build/services/TestGenerationService.test.d.ts +0 -1
  175. package/build/services/TestGenerationService.test.js +0 -578
  176. package/build/tool-phase-coverage.test.d.ts +0 -1
  177. package/build/tool-phase-coverage.test.js +0 -49
  178. package/build/tools/code-refactor/codeReuseTool.test.d.ts +0 -1
  179. package/build/tools/code-refactor/codeReuseTool.test.js +0 -572
  180. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +0 -1
  181. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +0 -433
  182. package/build/tools/generate-tests/generateContractRestTool.test.d.ts +0 -1
  183. package/build/tools/generate-tests/generateContractRestTool.test.js +0 -142
  184. package/build/tools/generate-tests/generateIntegrationRestTool.test.d.ts +0 -1
  185. package/build/tools/generate-tests/generateIntegrationRestTool.test.js +0 -159
  186. package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +0 -1
  187. package/build/tools/generate-tests/generateLoadRestTool.test.js +0 -169
  188. package/build/tools/generate-tests/generateUIRestTool.test.d.ts +0 -1
  189. package/build/tools/generate-tests/generateUIRestTool.test.js +0 -32
  190. package/build/tools/generate-tests/planGuard.test.d.ts +0 -1
  191. package/build/tools/generate-tests/planGuard.test.js +0 -185
  192. package/build/tools/generate-tests/scenarioLint.test.d.ts +0 -1
  193. package/build/tools/generate-tests/scenarioLint.test.js +0 -100
  194. package/build/tools/runExistingTestsTool.test.d.ts +0 -1
  195. package/build/tools/runExistingTestsTool.test.js +0 -379
  196. package/build/tools/submitReportTool.test.d.ts +0 -1
  197. package/build/tools/submitReportTool.test.js +0 -1428
  198. package/build/tools/test-management/actionsTool.test.d.ts +0 -1
  199. package/build/tools/test-management/actionsTool.test.js +0 -436
  200. package/build/tools/test-management/analyzeChangesTool.test.d.ts +0 -1
  201. package/build/tools/test-management/analyzeChangesTool.test.js +0 -522
  202. package/build/tools/test-management/analyzeTestHealthTool.test.d.ts +0 -1
  203. package/build/tools/test-management/analyzeTestHealthTool.test.js +0 -385
  204. package/build/tools/test-management/registerTestPlanTool.test.d.ts +0 -1
  205. package/build/tools/test-management/registerTestPlanTool.test.js +0 -296
  206. package/build/tools/trace/resolveSaveStoragePath.test.d.ts +0 -1
  207. package/build/tools/trace/resolveSaveStoragePath.test.js +0 -17
  208. package/build/tools/trace/resolveSessionPaths.test.d.ts +0 -1
  209. package/build/tools/trace/resolveSessionPaths.test.js +0 -104
  210. package/build/tools/trace/sessionState.test.d.ts +0 -1
  211. package/build/tools/trace/sessionState.test.js +0 -17
  212. package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +0 -1
  213. package/build/tools/workspace/initializeWorkspaceTool.test.js +0 -139
  214. package/build/tools/workspace/serviceUpsert.test.d.ts +0 -1
  215. package/build/tools/workspace/serviceUpsert.test.js +0 -50
  216. package/build/utils/AnalysisStateManager.test.d.ts +0 -1
  217. package/build/utils/AnalysisStateManager.test.js +0 -134
  218. package/build/utils/dartRouteExtractor.test.d.ts +0 -1
  219. package/build/utils/dartRouteExtractor.test.js +0 -307
  220. package/build/utils/docker.test.d.ts +0 -1
  221. package/build/utils/docker.test.js +0 -114
  222. package/build/utils/featureFlags.test.d.ts +0 -1
  223. package/build/utils/featureFlags.test.js +0 -81
  224. package/build/utils/fileWalk.test.d.ts +0 -1
  225. package/build/utils/fileWalk.test.js +0 -252
  226. package/build/utils/frontendIntegration.test.d.ts +0 -1
  227. package/build/utils/frontendIntegration.test.js +0 -229
  228. package/build/utils/frontendSelectors.test.d.ts +0 -1
  229. package/build/utils/frontendSelectors.test.js +0 -118
  230. package/build/utils/gitStaging.test.d.ts +0 -1
  231. package/build/utils/gitStaging.test.js +0 -111
  232. package/build/utils/httpDefaults.test.d.ts +0 -1
  233. package/build/utils/httpDefaults.test.js +0 -21
  234. package/build/utils/importerHop.test.d.ts +0 -1
  235. package/build/utils/importerHop.test.js +0 -469
  236. package/build/utils/pathAffinityClassification.test.d.ts +0 -1
  237. package/build/utils/pathAffinityClassification.test.js +0 -208
  238. package/build/utils/planMatchKeys.test.d.ts +0 -1
  239. package/build/utils/planMatchKeys.test.js +0 -123
  240. package/build/utils/pom-scope/index.test.d.ts +0 -1
  241. package/build/utils/pom-scope/index.test.js +0 -278
  242. package/build/utils/pom-scope/pom-files.test.d.ts +0 -1
  243. package/build/utils/pom-scope/pom-files.test.js +0 -29
  244. package/build/utils/pom-scope/scoring.test.d.ts +0 -1
  245. package/build/utils/pom-scope/scoring.test.js +0 -39
  246. package/build/utils/pom-scope/selector-extractor.test.d.ts +0 -1
  247. package/build/utils/pom-scope/selector-extractor.test.js +0 -67
  248. package/build/utils/pom-verify/bindings.test.d.ts +0 -1
  249. package/build/utils/pom-verify/bindings.test.js +0 -164
  250. package/build/utils/pom-verify/calls.test.d.ts +0 -1
  251. package/build/utils/pom-verify/calls.test.js +0 -61
  252. package/build/utils/pom-verify/resolve.test.d.ts +0 -1
  253. package/build/utils/pom-verify/resolve.test.js +0 -114
  254. package/build/utils/pom-verify/verify.test.d.ts +0 -1
  255. package/build/utils/pom-verify/verify.test.js +0 -374
  256. package/build/utils/pr-comment-parser.test.d.ts +0 -1
  257. package/build/utils/pr-comment-parser.test.js +0 -428
  258. package/build/utils/progress.test.d.ts +0 -1
  259. package/build/utils/progress.test.js +0 -37
  260. package/build/utils/projectMetadata.test.d.ts +0 -1
  261. package/build/utils/projectMetadata.test.js +0 -172
  262. package/build/utils/pythonMountPrefixes.test.d.ts +0 -1
  263. package/build/utils/pythonMountPrefixes.test.js +0 -113
  264. package/build/utils/repoScanner.test.d.ts +0 -1
  265. package/build/utils/repoScanner.test.js +0 -190
  266. package/build/utils/reportVerification.test.d.ts +0 -1
  267. package/build/utils/reportVerification.test.js +0 -185
  268. package/build/utils/routeParsers.test.d.ts +0 -1
  269. package/build/utils/routeParsers.test.js +0 -1011
  270. package/build/utils/scenarioDrafting.test.d.ts +0 -1
  271. package/build/utils/scenarioDrafting.test.js +0 -876
  272. package/build/utils/sourceRouteExtractor.test.d.ts +0 -1
  273. package/build/utils/sourceRouteExtractor.test.js +0 -738
  274. package/build/utils/telemetry.test.d.ts +0 -1
  275. package/build/utils/telemetry.test.js +0 -70
  276. package/build/utils/trace-parser.test.d.ts +0 -6
  277. package/build/utils/trace-parser.test.js +0 -140
  278. package/build/utils/uiPageEnumerator.test.d.ts +0 -1
  279. package/build/utils/uiPageEnumerator.test.js +0 -824
  280. package/build/utils/utils.test.d.ts +0 -1
  281. package/build/utils/utils.test.js +0 -103
  282. package/build/utils/walkerCharacterization.test.d.ts +0 -1
  283. package/build/utils/walkerCharacterization.test.js +0 -233
  284. package/build/utils/workspaceAuth.test.d.ts +0 -1
  285. package/build/utils/workspaceAuth.test.js +0 -260
  286. package/build/workspace/testSuites.test.d.ts +0 -1
  287. package/build/workspace/testSuites.test.js +0 -23
  288. package/build/workspace/workspace.test.d.ts +0 -1
  289. package/build/workspace/workspace.test.js +0 -264
@@ -1,134 +0,0 @@
1
- import * as fs from "fs";
2
- import * as os from "os";
3
- import * as path from "path";
4
- import { StateManager } from "./AnalysisStateManager.js";
5
- import { AnalysisScope } from "../types/RepositoryAnalysis.js";
6
- describe("StateManager.fromStatePath", () => {
7
- it("preserves the exact supplied path for a standard-prefixed file", () => {
8
- const stdPath = path.join(os.tmpdir(), "skyramp-analysis-some-uuid.json");
9
- const manager = StateManager.fromStatePath(stdPath);
10
- expect(manager.getStatePath()).toBe(stdPath);
11
- });
12
- it("preserves the exact supplied path for a custom filename like analyze-changes-state.json", () => {
13
- // This is the filename testbot uses — it does NOT match any STATE_FILE_PREFIXES entry.
14
- // fromStatePath must pass stateFilePath through to the constructor so the path is not rebuilt.
15
- const customPath = path.join(os.tmpdir(), "analyze-changes-state.json");
16
- const manager = StateManager.fromStatePath(customPath);
17
- expect(manager.getStatePath()).toBe(customPath);
18
- });
19
- });
20
- describe("StateManager.writeData", () => {
21
- it("creates parent directories when they do not exist", async () => {
22
- const nestedDir = path.join(os.tmpdir(), `skyramp-test-mkdir-${Date.now()}`);
23
- const nestedPath = path.join(nestedDir, "state.json");
24
- // Directory must not exist before the test
25
- expect(fs.existsSync(nestedDir)).toBe(false);
26
- const manager = new StateManager("analysis", undefined, undefined, nestedPath);
27
- await expect(manager.writeData({
28
- existingTests: [],
29
- analysisScope: AnalysisScope.CurrentBranchDiff,
30
- newEndpoints: [],
31
- })).resolves.not.toThrow();
32
- expect(fs.existsSync(nestedPath)).toBe(true);
33
- // cleanup
34
- await fs.promises.rm(nestedDir, { recursive: true, force: true });
35
- });
36
- });
37
- describe("StateManager — run-scoped per-repo sections (SKYR-3796)", () => {
38
- let stateFile;
39
- const mkState = (tag) => ({
40
- existingTests: [{ testFile: `${tag}.spec.ts` }],
41
- analysisScope: AnalysisScope.CurrentBranchDiff,
42
- newEndpoints: [],
43
- });
44
- beforeEach(() => {
45
- stateFile = path.join(os.tmpdir(), `skyramp-analysis-sections-${Date.now()}.json`);
46
- });
47
- afterEach(async () => {
48
- await fs.promises.rm(stateFile, { force: true });
49
- });
50
- it("keeps the primary at root and additional repos in relatedRepos, all in ONE file", async () => {
51
- const mgr = StateManager.fromStatePath(stateFile);
52
- // Primary (repo omitted) → root; additional repo → section.
53
- await mgr.writeRepoData(mkState("primary"), { repositoryPath: "/work/primary" });
54
- await mgr.writeRepoData(mkState("api"), {
55
- repo: "letsramp/api-insight",
56
- repositoryPath: "/work/api-insight",
57
- });
58
- // Exactly one file on disk.
59
- expect(fs.existsSync(stateFile)).toBe(true);
60
- expect(fs.existsSync(`${stateFile}.1.json`)).toBe(false);
61
- const raw = JSON.parse(await fs.promises.readFile(stateFile, "utf-8"));
62
- // Primary analysis lives at root (backward-compatible single-repo shape).
63
- expect(raw.existingTests[0].testFile).toBe("primary.spec.ts");
64
- expect(raw.metadata.repositoryPath).toBe("/work/primary");
65
- // Additional repo under relatedRepos, keyed by owner/repo.
66
- expect(raw.relatedRepos["letsramp/api-insight"].data.existingTests[0].testFile).toBe("api.spec.ts");
67
- expect(raw.relatedRepos["letsramp/api-insight"].repositoryPath).toBe("/work/api-insight");
68
- });
69
- it("reads back the correct section by repo (primary when omitted)", async () => {
70
- const mgr = StateManager.fromStatePath(stateFile);
71
- await mgr.writeRepoData(mkState("primary"), { repositoryPath: "/work/primary" });
72
- await mgr.writeRepoData(mkState("api"), { repo: "letsramp/api-insight", repositoryPath: "/work/api-insight" });
73
- expect((await mgr.readRepoData()).existingTests[0].testFile).toBe("primary.spec.ts");
74
- expect((await mgr.readRepoData("letsramp/api-insight")).existingTests[0].testFile).toBe("api.spec.ts");
75
- expect(await mgr.getRepoRepositoryPath()).toBe("/work/primary");
76
- expect(await mgr.getRepoRepositoryPath("letsramp/api-insight")).toBe("/work/api-insight");
77
- expect(await mgr.listRelatedRepos()).toEqual(["letsramp/api-insight"]);
78
- });
79
- it("preserves additional sections when the primary root is rewritten (writeData)", async () => {
80
- const mgr = StateManager.fromStatePath(stateFile);
81
- await mgr.writeRepoData(mkState("primary"), { repositoryPath: "/work/primary" });
82
- await mgr.writeRepoData(mkState("api"), { repo: "letsramp/api-insight", repositoryPath: "/work/api-insight" });
83
- // execute_test-style root rewrite must not drop the additional section.
84
- const primary = (await mgr.readRepoData());
85
- primary.existingTests[0].execution = { marker: "ran" };
86
- await mgr.writeData(primary);
87
- expect((await mgr.readRepoData("letsramp/api-insight")).existingTests[0].testFile).toBe("api.spec.ts");
88
- expect((await mgr.readRepoData()).existingTests[0].execution.marker).toBe("ran");
89
- });
90
- it("preserves an additional repo's repositoryPath when a later write omits it", async () => {
91
- const mgr = StateManager.fromStatePath(stateFile);
92
- await mgr.writeRepoData(mkState("primary"), { repositoryPath: "/work/primary" });
93
- // analyze_changes records the section WITH its checkout path.
94
- await mgr.writeRepoData(mkState("api"), {
95
- repo: "letsramp/api-insight",
96
- repositoryPath: "/work/api-insight",
97
- });
98
- // A later write to the same section (e.g. execute_test) omits repositoryPath.
99
- await mgr.writeRepoData(mkState("api-ran"), { repo: "letsramp/api-insight" });
100
- // The path must survive so getRepoRepositoryPath can still re-absolutize.
101
- expect(await mgr.getRepoRepositoryPath("letsramp/api-insight")).toBe("/work/api-insight");
102
- expect((await mgr.readRepoData("letsramp/api-insight")).existingTests[0].testFile).toBe("api-ran.spec.ts");
103
- });
104
- it("routes the primary to root and a related repo to a section when BOTH pass an explicit repo", async () => {
105
- const mgr = StateManager.fromStatePath(stateFile);
106
- // The agent now always passes an explicit owner/repo, including for the
107
- // primary. The FIRST write is the primary → root (tagged on metadata).
108
- await mgr.writeRepoData(mkState("primary"), {
109
- repo: "letsramp/primary-app",
110
- repositoryPath: "/work/primary",
111
- });
112
- await mgr.writeRepoData(mkState("api"), {
113
- repo: "letsramp/api-insight",
114
- repositoryPath: "/work/api-insight",
115
- });
116
- const raw = JSON.parse(await fs.promises.readFile(stateFile, "utf-8"));
117
- expect(raw.metadata.repository).toBe("letsramp/primary-app");
118
- expect(raw.existingTests[0].testFile).toBe("primary.spec.ts");
119
- expect(raw.relatedRepos["letsramp/api-insight"].data.existingTests[0].testFile).toBe("api.spec.ts");
120
- // The primary is reachable BOTH by its explicit repo and by omitting it.
121
- expect((await mgr.readRepoData("letsramp/primary-app")).existingTests[0].testFile).toBe("primary.spec.ts");
122
- expect((await mgr.readRepoData()).existingTests[0].testFile).toBe("primary.spec.ts");
123
- expect(await mgr.getRepoRepositoryPath("letsramp/primary-app")).toBe("/work/primary");
124
- expect(await mgr.listRelatedRepos()).toEqual(["letsramp/api-insight"]);
125
- });
126
- it("reads a legacy single-section file (no relatedRepos) as the primary", async () => {
127
- const mgr = StateManager.fromStatePath(stateFile);
128
- // Legacy write path — no repo, no sections.
129
- await mgr.writeData(mkState("legacy"), { repositoryPath: "/work/legacy" });
130
- expect((await mgr.readRepoData()).existingTests[0].testFile).toBe("legacy.spec.ts");
131
- expect(await mgr.getRepoRepositoryPath()).toBe("/work/legacy");
132
- expect(await mgr.listRelatedRepos()).toEqual([]);
133
- });
134
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,307 +0,0 @@
1
- // No external mocks needed — the extractor is pure fs + regex.
2
- import * as fs from "fs";
3
- import * as os from "os";
4
- import * as path from "path";
5
- import { extractDartRoutes } from "./dartRouteExtractor.js";
6
- function makeTmpRepo(files) {
7
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), "skyramp-dart-route-test-"));
8
- for (const f of files) {
9
- const fullPath = path.join(dir, f.path);
10
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
11
- fs.writeFileSync(fullPath, f.content);
12
- }
13
- return dir;
14
- }
15
- function cleanup(dir) {
16
- fs.rmSync(dir, { recursive: true, force: true });
17
- }
18
- describe("extractDartRoutes", () => {
19
- it("returns empty when repo has no .dart files", () => {
20
- const repo = makeTmpRepo([
21
- { path: "lib/main.dart", content: "void main() => runApp(MyApp());" },
22
- ]);
23
- expect(extractDartRoutes(repo)).toEqual([]);
24
- cleanup(repo);
25
- });
26
- it("extracts a single GoRoute with double-quoted path", () => {
27
- const repo = makeTmpRepo([
28
- {
29
- path: "lib/router.dart",
30
- content: `
31
- import 'package:go_router/go_router.dart';
32
-
33
- final router = GoRouter(routes: [
34
- GoRoute(path: "/login", builder: (ctx, st) => LoginScreen()),
35
- ]);
36
- `,
37
- },
38
- ]);
39
- const routes = extractDartRoutes(repo);
40
- expect(routes).toHaveLength(1);
41
- expect(routes[0].path).toBe("/login");
42
- expect(routes[0].declaredIn).toMatch(/router\.dart$/);
43
- cleanup(repo);
44
- });
45
- it("extracts a single GoRoute with single-quoted path", () => {
46
- const repo = makeTmpRepo([
47
- {
48
- path: "lib/app.dart",
49
- content: `GoRoute(path: '/home', builder: (c, s) => Home())`,
50
- },
51
- ]);
52
- const routes = extractDartRoutes(repo);
53
- expect(routes).toHaveLength(1);
54
- expect(routes[0].path).toBe("/home");
55
- cleanup(repo);
56
- });
57
- it("extracts multiple GoRoutes from one file", () => {
58
- const repo = makeTmpRepo([
59
- {
60
- path: "lib/router.dart",
61
- content: `
62
- final router = GoRouter(routes: [
63
- GoRoute(path: '/login', builder: (c, s) => LoginScreen()),
64
- GoRoute(path: '/dashboard', builder: (c, s) => DashboardScreen()),
65
- GoRoute(path: '/profile/:id', builder: (c, s) => ProfileScreen()),
66
- ]);
67
- `,
68
- },
69
- ]);
70
- const routes = extractDartRoutes(repo);
71
- expect(routes.map((r) => r.path).sort()).toEqual([
72
- "/dashboard",
73
- "/login",
74
- "/profile/:id",
75
- ]);
76
- cleanup(repo);
77
- });
78
- it("extracts nested GoRoutes (sub-routes inside parent)", () => {
79
- const repo = makeTmpRepo([
80
- {
81
- path: "lib/router.dart",
82
- content: `
83
- GoRoute(
84
- path: '/settings',
85
- builder: (c, s) => SettingsScreen(),
86
- routes: [
87
- GoRoute(path: 'account', builder: (c, s) => AccountScreen()),
88
- GoRoute(path: 'privacy', builder: (c, s) => PrivacyScreen()),
89
- ],
90
- );
91
- `,
92
- },
93
- ]);
94
- const routes = extractDartRoutes(repo);
95
- expect(routes.map((r) => r.path).sort()).toEqual([
96
- "/settings",
97
- "account",
98
- "privacy",
99
- ]);
100
- cleanup(repo);
101
- });
102
- it("walks lib/ and skips build, .dart_tool, ios, android, macos, web", () => {
103
- const repo = makeTmpRepo([
104
- {
105
- path: "lib/router.dart",
106
- content: `GoRoute(path: '/real', builder: (c, s) => X())`,
107
- },
108
- {
109
- path: "build/app/intermediates/router.dart",
110
- content: `GoRoute(path: '/build-fake', builder: (c, s) => X())`,
111
- },
112
- {
113
- path: ".dart_tool/something.dart",
114
- content: `GoRoute(path: '/tool-fake', builder: (c, s) => X())`,
115
- },
116
- {
117
- path: "ios/Generated.dart",
118
- content: `GoRoute(path: '/ios-fake', builder: (c, s) => X())`,
119
- },
120
- ]);
121
- const routes = extractDartRoutes(repo);
122
- expect(routes.map((r) => r.path)).toEqual(["/real"]);
123
- cleanup(repo);
124
- });
125
- it("ignores GoRoute calls without a string-literal path (constants, expressions)", () => {
126
- const repo = makeTmpRepo([
127
- {
128
- path: "lib/router.dart",
129
- content: `
130
- const _kHome = '/home';
131
- final router = GoRouter(routes: [
132
- GoRoute(path: _kHome, builder: (c, s) => H()),
133
- GoRoute(path: '/login', builder: (c, s) => L()),
134
- ]);
135
- `,
136
- },
137
- ]);
138
- const routes = extractDartRoutes(repo);
139
- expect(routes.map((r) => r.path)).toEqual(["/login"]);
140
- cleanup(repo);
141
- });
142
- it("returns empty for non-Flutter Dart files (no GoRoute calls)", () => {
143
- const repo = makeTmpRepo([
144
- {
145
- path: "bin/server.dart",
146
- content: `
147
- void main() async {
148
- final server = await HttpServer.bind('localhost', 8080);
149
- await for (final req in server) { /* ... */ }
150
- }
151
- `,
152
- },
153
- ]);
154
- expect(extractDartRoutes(repo)).toEqual([]);
155
- cleanup(repo);
156
- });
157
- it("deduplicates identical GoRoute paths declared multiple times", () => {
158
- const repo = makeTmpRepo([
159
- {
160
- path: "lib/a.dart",
161
- content: `GoRoute(path: '/login', builder: (c, s) => A())`,
162
- },
163
- {
164
- path: "lib/b.dart",
165
- content: `GoRoute(path: '/login', builder: (c, s) => B())`,
166
- },
167
- ]);
168
- const routes = extractDartRoutes(repo);
169
- expect(routes).toHaveLength(1);
170
- expect(routes[0].path).toBe("/login");
171
- cleanup(repo);
172
- });
173
- // Real-world: extract all routes from the books example we built locally.
174
- // This guards the regex against the actual customer-style GoRouter shape
175
- // — multi-line declarations with redirect+pageBuilder mixed in.
176
- it("extracts the books example's six routes", () => {
177
- const repo = makeTmpRepo([
178
- {
179
- path: "lib/main.dart",
180
- content: `
181
- import 'package:go_router/go_router.dart';
182
-
183
- late final GoRouter _router = GoRouter(
184
- routes: <GoRoute>[
185
- GoRoute(path: '/', redirect: (_, _) => '/books'),
186
- GoRoute(
187
- path: '/signin',
188
- pageBuilder: (BuildContext context, GoRouterState state) => SignIn(),
189
- ),
190
- GoRoute(path: '/books', redirect: (_, _) => '/books/popular'),
191
- GoRoute(
192
- path: '/book/:bookId',
193
- redirect: (BuildContext context, GoRouterState state) =>
194
- '/books/all/' + state.pathParameters['bookId']!,
195
- ),
196
- GoRoute(
197
- path: '/books/:kind(new|all|popular)',
198
- pageBuilder: (BuildContext context, GoRouterState state) => Books(),
199
- routes: <GoRoute>[
200
- GoRoute(
201
- path: ':bookId',
202
- builder: (BuildContext context, GoRouterState state) => BookDetails(),
203
- ),
204
- ],
205
- ),
206
- GoRoute(
207
- path: '/author/:authorId',
208
- redirect: (BuildContext context, GoRouterState state) =>
209
- '/authors/' + state.pathParameters['authorId']!,
210
- ),
211
- GoRoute(
212
- path: '/authors',
213
- pageBuilder: (BuildContext context, GoRouterState state) => Authors(),
214
- routes: <GoRoute>[
215
- GoRoute(
216
- path: ':authorId',
217
- builder: (BuildContext context, GoRouterState state) => AuthorDetails(),
218
- ),
219
- ],
220
- ),
221
- GoRoute(
222
- path: '/settings',
223
- pageBuilder: (BuildContext context, GoRouterState state) => Settings(),
224
- ),
225
- ],
226
- );
227
- `,
228
- },
229
- ]);
230
- const routes = extractDartRoutes(repo);
231
- const paths = routes.map((r) => r.path).sort();
232
- // Top-level absolute paths.
233
- expect(paths).toEqual([
234
- "/",
235
- "/author/:authorId",
236
- "/authors",
237
- "/book/:bookId",
238
- "/books",
239
- "/books/:kind(new|all|popular)",
240
- "/settings",
241
- "/signin",
242
- ":authorId",
243
- ":bookId",
244
- ].sort());
245
- cleanup(repo);
246
- });
247
- // ── New shape: screenWidgets, screenFiles, isRedirectOnly ─────────────────
248
- it("flags redirect-only routes (no builder/pageBuilder)", () => {
249
- const repo = makeTmpRepo([
250
- {
251
- path: "lib/router.dart",
252
- content: `
253
- GoRoute(path: '/', redirect: (_, _) => '/home'),
254
- GoRoute(path: '/home', builder: (c, s) => Home()),
255
- `,
256
- },
257
- ]);
258
- const routes = extractDartRoutes(repo);
259
- const root = routes.find((r) => r.path === "/");
260
- const home = routes.find((r) => r.path === "/home");
261
- expect(root?.isRedirectOnly).toBe(true);
262
- expect(home?.isRedirectOnly).toBe(false);
263
- cleanup(repo);
264
- });
265
- it("captures screen widget identifiers from builder/pageBuilder", () => {
266
- const repo = makeTmpRepo([
267
- {
268
- path: "lib/router.dart",
269
- content: `
270
- GoRoute(path: '/login', builder: (c, s) => LoginScreen()),
271
- GoRoute(path: '/profile', pageBuilder: (c, s) => MaterialPage(child: ProfileScreen())),
272
- `,
273
- },
274
- ]);
275
- const routes = extractDartRoutes(repo);
276
- const login = routes.find((r) => r.path === "/login");
277
- const profile = routes.find((r) => r.path === "/profile");
278
- expect(login?.screenWidgets).toContain("LoginScreen");
279
- expect(profile?.screenWidgets).toContain("ProfileScreen");
280
- // Ignored framework identifiers should NOT appear.
281
- expect(login?.screenWidgets).not.toContain("BuildContext");
282
- expect(profile?.screenWidgets).not.toContain("MaterialPage");
283
- cleanup(repo);
284
- });
285
- it("resolves screenWidgets to imported file paths via filename heuristic", () => {
286
- const repo = makeTmpRepo([
287
- {
288
- path: "lib/main.dart",
289
- content: `
290
- import 'src/screens/authors.dart';
291
- import 'src/screens/settings.dart';
292
-
293
- GoRoute(path: '/authors', builder: (c, s) => AuthorsScreen()),
294
- GoRoute(path: '/settings', builder: (c, s) => SettingsScreen()),
295
- `,
296
- },
297
- { path: "lib/src/screens/authors.dart", content: "// AuthorsScreen widget" },
298
- { path: "lib/src/screens/settings.dart", content: "// SettingsScreen widget" },
299
- ]);
300
- const routes = extractDartRoutes(repo);
301
- const authors = routes.find((r) => r.path === "/authors");
302
- const settings = routes.find((r) => r.path === "/settings");
303
- expect(authors?.screenFiles[0]).toMatch(/lib\/src\/screens\/authors\.dart$/);
304
- expect(settings?.screenFiles[0]).toMatch(/lib\/src\/screens\/settings\.dart$/);
305
- cleanup(repo);
306
- });
307
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,114 +0,0 @@
1
- // @ts-nocheck - Jest ESM type inference issues
2
- import { jest } from "@jest/globals";
3
- // Mock logger before importing docker module
4
- const mockInspect = jest.fn();
5
- const mockGetImage = jest.fn(() => ({ inspect: mockInspect }));
6
- const mockFollowProgress = jest.fn();
7
- const mockPull = jest.fn();
8
- const mockModem = { followProgress: mockFollowProgress };
9
- jest.unstable_mockModule("./logger.js", () => ({
10
- logger: {
11
- debug: jest.fn(),
12
- info: jest.fn(),
13
- error: jest.fn(),
14
- warning: jest.fn(),
15
- },
16
- }));
17
- jest.mock("dockerode", () => jest.fn().mockImplementation(() => ({
18
- getImage: mockGetImage,
19
- pull: mockPull,
20
- modem: mockModem,
21
- })));
22
- const { dockerImageExistsLocally, pullDockerImage } = await import("./docker.js");
23
- // Helper: make docker.pull succeed (stream ends without error)
24
- function mockPullSuccess() {
25
- const fakeStream = {};
26
- mockPull.mockImplementation((_image, _opts, cb) => {
27
- cb(null, fakeStream);
28
- });
29
- mockFollowProgress.mockImplementation((_stream, onFinished) => {
30
- onFinished(null);
31
- });
32
- }
33
- // Helper: make docker.pull fail with the given error
34
- function mockPullError(err) {
35
- mockPull.mockImplementation((_image, _opts, cb) => {
36
- cb(err);
37
- });
38
- }
39
- describe("dockerImageExistsLocally", () => {
40
- beforeEach(() => jest.clearAllMocks());
41
- it("returns true when inspect succeeds", async () => {
42
- mockInspect.mockResolvedValue({});
43
- await expect(dockerImageExistsLocally("img:tag")).resolves.toBe(true);
44
- });
45
- it("returns false on 404 (image not present locally)", async () => {
46
- mockInspect.mockRejectedValue({ statusCode: 404 });
47
- await expect(dockerImageExistsLocally("img:tag")).resolves.toBe(false);
48
- });
49
- it("throws and logs a warning when Docker daemon is unreachable", async () => {
50
- const { logger } = await import("./logger.js");
51
- const daemonErr = new Error("connect ECONNREFUSED /var/run/docker.sock");
52
- mockInspect.mockRejectedValue(daemonErr);
53
- await expect(dockerImageExistsLocally("img:tag")).rejects.toThrow(daemonErr);
54
- expect(logger.warning).toHaveBeenCalledWith("Could not check Docker image locally", expect.objectContaining({ image: "img:tag" }));
55
- });
56
- });
57
- describe("pullDockerImage", () => {
58
- const IMAGE = "skyramp/executor:v1.3.36";
59
- beforeEach(() => jest.clearAllMocks());
60
- describe("on amd64 host", () => {
61
- const originalArch = process.arch;
62
- beforeAll(() => Object.defineProperty(process, "arch", { value: "x64", configurable: true }));
63
- afterAll(() => Object.defineProperty(process, "arch", { value: originalArch, configurable: true }));
64
- it("pulls with linux/amd64 and succeeds", async () => {
65
- mockPullSuccess();
66
- await expect(pullDockerImage(IMAGE)).resolves.toBeUndefined();
67
- expect(mockPull).toHaveBeenCalledTimes(1);
68
- expect(mockPull).toHaveBeenCalledWith(IMAGE, { platform: "linux/amd64" }, expect.any(Function));
69
- });
70
- it("rethrows any pull error without fallback", async () => {
71
- const err = new Error("unauthorized: access denied");
72
- mockPullError(err);
73
- await expect(pullDockerImage(IMAGE)).rejects.toThrow(err);
74
- expect(mockPull).toHaveBeenCalledTimes(1);
75
- });
76
- });
77
- describe("on arm64 host", () => {
78
- const originalArch = process.arch;
79
- beforeAll(() => Object.defineProperty(process, "arch", { value: "arm64", configurable: true }));
80
- afterAll(() => Object.defineProperty(process, "arch", { value: originalArch, configurable: true }));
81
- it("pulls with linux/arm64 and succeeds without fallback when image lands locally", async () => {
82
- mockPullSuccess();
83
- mockInspect.mockResolvedValue({}); // post-pull verify: image found
84
- await expect(pullDockerImage(IMAGE)).resolves.toBeUndefined();
85
- expect(mockPull).toHaveBeenCalledTimes(1);
86
- expect(mockPull).toHaveBeenCalledWith(IMAGE, { platform: "linux/arm64" }, expect.any(Function));
87
- });
88
- it("falls back to linux/amd64 on manifest-mismatch error", async () => {
89
- const manifestErr = new Error("no matching manifest for linux/arm64 in the manifest list entries");
90
- const fakeStream = {};
91
- mockPull
92
- .mockImplementationOnce((_image, _opts, cb) => cb(manifestErr))
93
- .mockImplementationOnce((_image, _opts, cb) => cb(null, fakeStream));
94
- mockFollowProgress.mockImplementation((_stream, onFinished) => onFinished(null));
95
- await expect(pullDockerImage(IMAGE)).resolves.toBeUndefined();
96
- expect(mockPull).toHaveBeenCalledTimes(2);
97
- expect(mockPull).toHaveBeenNthCalledWith(1, IMAGE, { platform: "linux/arm64" }, expect.any(Function));
98
- expect(mockPull).toHaveBeenNthCalledWith(2, IMAGE, { platform: "linux/amd64" }, expect.any(Function));
99
- });
100
- it("rethrows non-manifest errors (auth/network) without falling back", async () => {
101
- const authErr = new Error("unauthorized: access denied");
102
- mockPullError(authErr);
103
- await expect(pullDockerImage(IMAGE)).rejects.toThrow(authErr);
104
- expect(mockPull).toHaveBeenCalledTimes(1);
105
- });
106
- it("falls back to linux/amd64 when arm64 pull succeeds silently but image is not stored locally", async () => {
107
- mockPullSuccess();
108
- mockInspect.mockRejectedValueOnce({ statusCode: 404 }); // post-pull verify: not found
109
- await expect(pullDockerImage(IMAGE)).resolves.toBeUndefined();
110
- expect(mockPull).toHaveBeenCalledTimes(2);
111
- expect(mockPull).toHaveBeenNthCalledWith(2, IMAGE, { platform: "linux/amd64" }, expect.any(Function));
112
- });
113
- });
114
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,81 +0,0 @@
1
- import { resolveServiceDetailsRef } from "./utils.js";
2
- import { isTestbotEnabled } from "./featureFlags.js";
3
- // Capture and restore the original env var so these tests don't pollute other
4
- // test suites or a developer's shell environment where the var may already be set.
5
- let originalTestbotEnv;
6
- beforeAll(() => { originalTestbotEnv = process.env.SKYRAMP_FEATURE_TESTBOT; });
7
- afterAll(() => {
8
- if (originalTestbotEnv === undefined) {
9
- delete process.env.SKYRAMP_FEATURE_TESTBOT;
10
- }
11
- else {
12
- process.env.SKYRAMP_FEATURE_TESTBOT = originalTestbotEnv;
13
- }
14
- });
15
- describe("isTestbotEnabled", () => {
16
- afterEach(() => {
17
- delete process.env.SKYRAMP_FEATURE_TESTBOT;
18
- });
19
- it('returns true when SKYRAMP_FEATURE_TESTBOT is "1"', () => {
20
- process.env.SKYRAMP_FEATURE_TESTBOT = "1";
21
- expect(isTestbotEnabled()).toBe(true);
22
- });
23
- it("returns false when SKYRAMP_FEATURE_TESTBOT is unset", () => {
24
- expect(isTestbotEnabled()).toBe(false);
25
- });
26
- it('returns false when SKYRAMP_FEATURE_TESTBOT is "0"', () => {
27
- process.env.SKYRAMP_FEATURE_TESTBOT = "0";
28
- expect(isTestbotEnabled()).toBe(false);
29
- });
30
- it('returns false when SKYRAMP_FEATURE_TESTBOT is "true"', () => {
31
- process.env.SKYRAMP_FEATURE_TESTBOT = "true";
32
- expect(isTestbotEnabled()).toBe(false);
33
- });
34
- });
35
- describe("resolveServiceDetailsRef", () => {
36
- afterEach(() => {
37
- delete process.env.SKYRAMP_FEATURE_TESTBOT;
38
- });
39
- describe("testbot mode (SKYRAMP_FEATURE_TESTBOT=1)", () => {
40
- beforeEach(() => {
41
- process.env.SKYRAMP_FEATURE_TESTBOT = "1";
42
- });
43
- it("returns <services> block reference for testDirRef", () => {
44
- expect(resolveServiceDetailsRef().testDirRef).toContain("<test_directory>");
45
- expect(resolveServiceDetailsRef().testDirRef).toContain("<services>");
46
- });
47
- it("returns <services> block reference for frontendTestDirRef", () => {
48
- expect(resolveServiceDetailsRef().frontendTestDirRef).toContain("<test_directory>");
49
- expect(resolveServiceDetailsRef().frontendTestDirRef).toContain("<services>");
50
- });
51
- it("returns <services> block reference for authSourceRef", () => {
52
- expect(resolveServiceDetailsRef().authSourceRef).toContain("<services>");
53
- });
54
- it("returns <services> block reference for baseUrlRef", () => {
55
- expect(resolveServiceDetailsRef().baseUrlRef).toContain("<base_url>");
56
- });
57
- it("does NOT reference workspace.yml in any field", () => {
58
- const refs = resolveServiceDetailsRef();
59
- for (const val of Object.values(refs)) {
60
- expect(val).not.toContain("workspace.yml");
61
- }
62
- });
63
- });
64
- describe("MCP mode (SKYRAMP_FEATURE_TESTBOT unset)", () => {
65
- it("returns workspace.yml reference for testDirRef", () => {
66
- expect(resolveServiceDetailsRef().testDirRef).toContain("workspace.yml");
67
- });
68
- it("returns workspace.yml reference for frontendTestDirRef", () => {
69
- expect(resolveServiceDetailsRef().frontendTestDirRef).toContain("workspace.yml");
70
- });
71
- it("returns workspace.yml reference for authSourceRef", () => {
72
- expect(resolveServiceDetailsRef().authSourceRef).toContain("workspace.yml");
73
- });
74
- it("does NOT reference <services> in any field", () => {
75
- const refs = resolveServiceDetailsRef();
76
- for (const val of Object.values(refs)) {
77
- expect(val).not.toContain("<services>");
78
- }
79
- });
80
- });
81
- });
@@ -1 +0,0 @@
1
- export {};