@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.
- package/build/commands/commandLibrary.d.ts +1 -0
- package/build/commands/commandLibrary.js +19 -13
- package/build/commands/localDevTestChangesCommand.d.ts +15 -0
- package/build/commands/localDevTestChangesCommand.js +201 -0
- package/build/index.js +80 -6
- package/build/prompts/code-reuse.js +3 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +1 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.js +17 -0
- package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +11 -9
- package/build/prompts/local-dev/local-dev-plan.d.ts +35 -0
- package/build/prompts/local-dev/local-dev-plan.js +429 -0
- package/build/prompts/local-dev/local-dev-prompts.d.ts +4 -0
- package/build/prompts/local-dev/local-dev-prompts.js +190 -0
- package/build/prompts/pom-aware-code-reuse.js +12 -0
- package/build/prompts/prompt-utils.d.ts +8 -0
- package/build/prompts/prompt-utils.js +33 -0
- package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +37 -14
- package/build/prompts/sut-setup/shared.js +16 -12
- package/build/prompts/test-recommendation/analysisOutputPrompt.js +21 -29
- package/build/prompts/test-recommendation/scopeAssessment.d.ts +24 -7
- package/build/prompts/test-recommendation/scopeAssessment.js +111 -12
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +41 -4
- package/build/prompts/testbot/testbot-prompts.d.ts +0 -5
- package/build/prompts/testbot/testbot-prompts.js +32 -52
- package/build/recommendation/planRanker.d.ts +15 -2
- package/build/recommendation/planRanker.js +76 -5
- package/build/resources/testbotResource.js +2 -1
- package/build/services/AnalyticsService.d.ts +1 -1
- package/build/services/TestExecutionService.d.ts +2 -1
- package/build/services/TestExecutionService.js +8 -3
- package/build/services/TestGenerationService.d.ts +2 -2
- package/build/services/TestGenerationService.js +39 -21
- package/build/services/containerEnv.js +3 -1
- package/build/tool-phases.js +6 -0
- package/build/tools/code-refactor/codeReuseTool.js +43 -4
- package/build/tools/code-refactor/enhanceAssertionsTool.js +68 -18
- package/build/tools/code-refactor/reuse-outcome.d.ts +109 -0
- package/build/tools/code-refactor/reuse-outcome.js +158 -0
- package/build/tools/code-refactor/reuse-state.d.ts +45 -0
- package/build/tools/code-refactor/reuse-state.js +140 -0
- package/build/tools/enrichTestWithMocksTool.d.ts +28 -0
- package/build/tools/enrichTestWithMocksTool.js +726 -0
- package/build/tools/executeSkyrampTestTool.d.ts +11 -0
- package/build/tools/executeSkyrampTestTool.js +62 -21
- package/build/tools/generate-tests/batchMockGenerationTool.d.ts +106 -0
- package/build/tools/generate-tests/batchMockGenerationTool.js +545 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +25 -23
- package/build/tools/generate-tests/generateContractRestTool.js +2 -2
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.js +1 -1
- package/build/tools/generate-tests/generateMockRestTool.d.ts +179 -6
- package/build/tools/generate-tests/generateMockRestTool.js +391 -22
- package/build/tools/generate-tests/loadTestSchema.d.ts +1 -1
- package/build/tools/generate-tests/planGuard.js +2 -22
- package/build/tools/generateEnrichedIntegrationTestTool.d.ts +25 -0
- package/build/tools/generateEnrichedIntegrationTestTool.js +235 -0
- package/build/tools/localDevWorkerComposeTool.d.ts +24 -0
- package/build/tools/localDevWorkerComposeTool.js +264 -0
- package/build/tools/one-click/oneClickTool.d.ts +13 -0
- package/build/tools/one-click/oneClickTool.js +195 -24
- package/build/tools/preflightMockCheckTool.d.ts +2 -0
- package/build/tools/preflightMockCheckTool.js +96 -0
- package/build/tools/queryProxyMocksTool.d.ts +70 -0
- package/build/tools/queryProxyMocksTool.js +522 -0
- package/build/tools/runExistingTestsTool.d.ts +31 -0
- package/build/tools/runExistingTestsTool.js +214 -13
- package/build/tools/submitReportTool.js +38 -3
- package/build/tools/test-management/analyzeChangesTool.d.ts +2 -1
- package/build/tools/test-management/analyzeChangesTool.js +63 -40
- package/build/tools/test-management/registerTestPlanTool.js +55 -7
- package/build/tools/trace/startTraceCollectionTool.js +3 -3
- package/build/types/FrontendIntegration.d.ts +3 -0
- package/build/types/FrontendIntegration.js +3 -0
- package/build/types/OneClickCommands.d.ts +1 -1
- package/build/types/Recommendation.d.ts +20 -0
- package/build/types/Recommendation.js +32 -6
- package/build/types/RepositoryAnalysis.d.ts +131 -14
- package/build/types/RepositoryAnalysis.js +16 -2
- package/build/types/ReuseOutcome.d.ts +63 -0
- package/build/types/ReuseOutcome.js +33 -0
- package/build/types/TestExecution.d.ts +1 -0
- package/build/types/TestTypes.d.ts +25 -7
- package/build/types/TestTypes.js +22 -6
- package/build/types/TestbotReport.d.ts +7 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +1 -0
- package/build/utils/AnalysisStateManager.d.ts +26 -0
- package/build/utils/AnalysisStateManager.js +31 -1
- package/build/utils/analyze-openapi.js +18 -1
- package/build/utils/branchDiff.d.ts +17 -1
- package/build/utils/branchDiff.js +99 -14
- package/build/utils/featureFlags.d.ts +31 -0
- package/build/utils/featureFlags.js +37 -0
- package/build/utils/frontendIntegration.js +8 -1
- package/build/utils/grpcMockValidation.d.ts +1 -0
- package/build/utils/grpcMockValidation.js +49 -0
- package/build/utils/httpMethodValidation.d.ts +4 -0
- package/build/utils/httpMethodValidation.js +15 -0
- package/build/utils/logger.js +1 -1
- package/build/utils/mockCompatibility.d.ts +49 -0
- package/build/utils/mockCompatibility.js +82 -0
- package/build/utils/pom-scope/pom-files.js +7 -0
- package/build/utils/pom-verify/bindings.js +11 -1
- package/build/utils/pom-verify/re-exports.d.ts +10 -0
- package/build/utils/pom-verify/re-exports.js +61 -0
- package/build/utils/pom-verify/resolve.d.ts +4 -1
- package/build/utils/pom-verify/resolve.js +7 -4
- package/build/utils/pom-verify/verify.d.ts +5 -0
- package/build/utils/pom-verify/verify.js +25 -3
- package/build/utils/progress.js +10 -5
- package/build/utils/proxy-terminal.js +3 -3
- package/build/utils/routeParsers.d.ts +3 -9
- package/build/utils/routeParsers.js +79 -4
- package/build/utils/utils.js +2 -2
- package/build/utils/versions.d.ts +4 -3
- package/build/utils/versions.js +3 -1
- package/build/utils/workspaceAuth.d.ts +46 -0
- package/build/utils/workspaceAuth.js +156 -1
- package/build/workspace/testSuites.d.ts +2 -1
- package/build/workspace/testSuites.js +1 -1
- package/build/workspace/workspace.d.ts +108 -32
- package/build/workspace/workspace.js +32 -4
- package/package.json +5 -2
- package/build/adapters/jestAdapter.test.d.ts +0 -1
- package/build/adapters/jestAdapter.test.js +0 -93
- package/build/adapters/mochaAdapter.test.d.ts +0 -1
- package/build/adapters/mochaAdapter.test.js +0 -63
- package/build/adapters/playwrightAdapter.test.d.ts +0 -1
- package/build/adapters/playwrightAdapter.test.js +0 -169
- package/build/adapters/pytestAdapter.test.d.ts +0 -1
- package/build/adapters/pytestAdapter.test.js +0 -90
- package/build/prompts/code-reuse.test.d.ts +0 -1
- package/build/prompts/code-reuse.test.js +0 -62
- package/build/prompts/pom-aware-code-reuse.test.d.ts +0 -1
- package/build/prompts/pom-aware-code-reuse.test.js +0 -11
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.d.ts +0 -1
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +0 -51
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +0 -1
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +0 -264
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +0 -1
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +0 -126
- package/build/prompts/test-recommendation/promptPlan.test.d.ts +0 -1
- package/build/prompts/test-recommendation/promptPlan.test.js +0 -336
- package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +0 -1
- package/build/prompts/test-recommendation/scopeAssessment.test.js +0 -371
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +0 -1
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +0 -1925
- package/build/prompts/testbot/testbot-prompts.test.d.ts +0 -1
- package/build/prompts/testbot/testbot-prompts.test.js +0 -451
- package/build/recommendation/budgeters/diversityBalancedBudgeter.test.d.ts +0 -1
- package/build/recommendation/budgeters/diversityBalancedBudgeter.test.js +0 -138
- package/build/recommendation/budgeters/fixedNBudgeter.test.d.ts +0 -1
- package/build/recommendation/budgeters/fixedNBudgeter.test.js +0 -66
- package/build/recommendation/discriminators.test.d.ts +0 -1
- package/build/recommendation/discriminators.test.js +0 -324
- package/build/recommendation/diversity.test.d.ts +0 -1
- package/build/recommendation/diversity.test.js +0 -77
- package/build/recommendation/planRanker.test.d.ts +0 -1
- package/build/recommendation/planRanker.test.js +0 -110
- package/build/resources/testbotResource.test.d.ts +0 -1
- package/build/resources/testbotResource.test.js +0 -44
- package/build/services/AnalyticsService.test.d.ts +0 -1
- package/build/services/AnalyticsService.test.js +0 -86
- package/build/services/ScenarioGenerationService.integration.test.d.ts +0 -1
- package/build/services/ScenarioGenerationService.integration.test.js +0 -162
- package/build/services/ScenarioGenerationService.test.d.ts +0 -1
- package/build/services/ScenarioGenerationService.test.js +0 -414
- package/build/services/TestDiscoveryService.test.d.ts +0 -1
- package/build/services/TestDiscoveryService.test.js +0 -983
- package/build/services/TestExecutionService.test.d.ts +0 -1
- package/build/services/TestExecutionService.test.js +0 -1032
- package/build/services/TestGenerationService.test.d.ts +0 -1
- package/build/services/TestGenerationService.test.js +0 -578
- package/build/tool-phase-coverage.test.d.ts +0 -1
- package/build/tool-phase-coverage.test.js +0 -49
- package/build/tools/code-refactor/codeReuseTool.test.d.ts +0 -1
- package/build/tools/code-refactor/codeReuseTool.test.js +0 -572
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +0 -433
- package/build/tools/generate-tests/generateContractRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateContractRestTool.test.js +0 -142
- package/build/tools/generate-tests/generateIntegrationRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateIntegrationRestTool.test.js +0 -159
- package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateLoadRestTool.test.js +0 -169
- package/build/tools/generate-tests/generateUIRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateUIRestTool.test.js +0 -32
- package/build/tools/generate-tests/planGuard.test.d.ts +0 -1
- package/build/tools/generate-tests/planGuard.test.js +0 -185
- package/build/tools/generate-tests/scenarioLint.test.d.ts +0 -1
- package/build/tools/generate-tests/scenarioLint.test.js +0 -100
- package/build/tools/runExistingTestsTool.test.d.ts +0 -1
- package/build/tools/runExistingTestsTool.test.js +0 -379
- package/build/tools/submitReportTool.test.d.ts +0 -1
- package/build/tools/submitReportTool.test.js +0 -1428
- package/build/tools/test-management/actionsTool.test.d.ts +0 -1
- package/build/tools/test-management/actionsTool.test.js +0 -436
- package/build/tools/test-management/analyzeChangesTool.test.d.ts +0 -1
- package/build/tools/test-management/analyzeChangesTool.test.js +0 -522
- package/build/tools/test-management/analyzeTestHealthTool.test.d.ts +0 -1
- package/build/tools/test-management/analyzeTestHealthTool.test.js +0 -385
- package/build/tools/test-management/registerTestPlanTool.test.d.ts +0 -1
- package/build/tools/test-management/registerTestPlanTool.test.js +0 -296
- package/build/tools/trace/resolveSaveStoragePath.test.d.ts +0 -1
- package/build/tools/trace/resolveSaveStoragePath.test.js +0 -17
- package/build/tools/trace/resolveSessionPaths.test.d.ts +0 -1
- package/build/tools/trace/resolveSessionPaths.test.js +0 -104
- package/build/tools/trace/sessionState.test.d.ts +0 -1
- package/build/tools/trace/sessionState.test.js +0 -17
- package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +0 -1
- package/build/tools/workspace/initializeWorkspaceTool.test.js +0 -139
- package/build/tools/workspace/serviceUpsert.test.d.ts +0 -1
- package/build/tools/workspace/serviceUpsert.test.js +0 -50
- package/build/utils/AnalysisStateManager.test.d.ts +0 -1
- package/build/utils/AnalysisStateManager.test.js +0 -134
- package/build/utils/dartRouteExtractor.test.d.ts +0 -1
- package/build/utils/dartRouteExtractor.test.js +0 -307
- package/build/utils/docker.test.d.ts +0 -1
- package/build/utils/docker.test.js +0 -114
- package/build/utils/featureFlags.test.d.ts +0 -1
- package/build/utils/featureFlags.test.js +0 -81
- package/build/utils/fileWalk.test.d.ts +0 -1
- package/build/utils/fileWalk.test.js +0 -252
- package/build/utils/frontendIntegration.test.d.ts +0 -1
- package/build/utils/frontendIntegration.test.js +0 -229
- package/build/utils/frontendSelectors.test.d.ts +0 -1
- package/build/utils/frontendSelectors.test.js +0 -118
- package/build/utils/gitStaging.test.d.ts +0 -1
- package/build/utils/gitStaging.test.js +0 -111
- package/build/utils/httpDefaults.test.d.ts +0 -1
- package/build/utils/httpDefaults.test.js +0 -21
- package/build/utils/importerHop.test.d.ts +0 -1
- package/build/utils/importerHop.test.js +0 -469
- package/build/utils/pathAffinityClassification.test.d.ts +0 -1
- package/build/utils/pathAffinityClassification.test.js +0 -208
- package/build/utils/planMatchKeys.test.d.ts +0 -1
- package/build/utils/planMatchKeys.test.js +0 -123
- package/build/utils/pom-scope/index.test.d.ts +0 -1
- package/build/utils/pom-scope/index.test.js +0 -278
- package/build/utils/pom-scope/pom-files.test.d.ts +0 -1
- package/build/utils/pom-scope/pom-files.test.js +0 -29
- package/build/utils/pom-scope/scoring.test.d.ts +0 -1
- package/build/utils/pom-scope/scoring.test.js +0 -39
- package/build/utils/pom-scope/selector-extractor.test.d.ts +0 -1
- package/build/utils/pom-scope/selector-extractor.test.js +0 -67
- package/build/utils/pom-verify/bindings.test.d.ts +0 -1
- package/build/utils/pom-verify/bindings.test.js +0 -164
- package/build/utils/pom-verify/calls.test.d.ts +0 -1
- package/build/utils/pom-verify/calls.test.js +0 -61
- package/build/utils/pom-verify/resolve.test.d.ts +0 -1
- package/build/utils/pom-verify/resolve.test.js +0 -114
- package/build/utils/pom-verify/verify.test.d.ts +0 -1
- package/build/utils/pom-verify/verify.test.js +0 -374
- package/build/utils/pr-comment-parser.test.d.ts +0 -1
- package/build/utils/pr-comment-parser.test.js +0 -428
- package/build/utils/progress.test.d.ts +0 -1
- package/build/utils/progress.test.js +0 -37
- package/build/utils/projectMetadata.test.d.ts +0 -1
- package/build/utils/projectMetadata.test.js +0 -172
- package/build/utils/pythonMountPrefixes.test.d.ts +0 -1
- package/build/utils/pythonMountPrefixes.test.js +0 -113
- package/build/utils/repoScanner.test.d.ts +0 -1
- package/build/utils/repoScanner.test.js +0 -190
- package/build/utils/reportVerification.test.d.ts +0 -1
- package/build/utils/reportVerification.test.js +0 -185
- package/build/utils/routeParsers.test.d.ts +0 -1
- package/build/utils/routeParsers.test.js +0 -1011
- package/build/utils/scenarioDrafting.test.d.ts +0 -1
- package/build/utils/scenarioDrafting.test.js +0 -876
- package/build/utils/sourceRouteExtractor.test.d.ts +0 -1
- package/build/utils/sourceRouteExtractor.test.js +0 -738
- package/build/utils/telemetry.test.d.ts +0 -1
- package/build/utils/telemetry.test.js +0 -70
- package/build/utils/trace-parser.test.d.ts +0 -6
- package/build/utils/trace-parser.test.js +0 -140
- package/build/utils/uiPageEnumerator.test.d.ts +0 -1
- package/build/utils/uiPageEnumerator.test.js +0 -824
- package/build/utils/utils.test.d.ts +0 -1
- package/build/utils/utils.test.js +0 -103
- package/build/utils/walkerCharacterization.test.d.ts +0 -1
- package/build/utils/walkerCharacterization.test.js +0 -233
- package/build/utils/workspaceAuth.test.d.ts +0 -1
- package/build/utils/workspaceAuth.test.js +0 -260
- package/build/workspace/testSuites.test.d.ts +0 -1
- package/build/workspace/testSuites.test.js +0 -23
- package/build/workspace/workspace.test.d.ts +0 -1
- package/build/workspace/workspace.test.js +0 -264
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
import { jest } from "@jest/globals";
|
|
2
|
-
jest.mock("@skyramp/skyramp", () => ({
|
|
3
|
-
WorkspaceConfigManager: { create: jest.fn() },
|
|
4
|
-
}));
|
|
5
|
-
import * as fs from "fs";
|
|
6
|
-
import * as path from "path";
|
|
7
|
-
import * as os from "os";
|
|
8
|
-
import { hasFlutterSdkDep, isFrontendFile, isTestFile, buildScopeAssessmentSection } from "./scopeAssessment.js";
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// isFrontendFile
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
describe("isFrontendFile", () => {
|
|
13
|
-
it("returns true for a TSX component in components/", () => {
|
|
14
|
-
expect(isFrontendFile("src/components/Button.tsx")).toBe(true);
|
|
15
|
-
});
|
|
16
|
-
it("returns true for a JSX file in pages/", () => {
|
|
17
|
-
expect(isFrontendFile("src/pages/Home.jsx")).toBe(true);
|
|
18
|
-
});
|
|
19
|
-
it("returns true for a Vue file in views/", () => {
|
|
20
|
-
expect(isFrontendFile("src/views/Dashboard.vue")).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
it("returns false for a TS route handler (API directory)", () => {
|
|
23
|
-
expect(isFrontendFile("src/routes/items.ts")).toBe(false);
|
|
24
|
-
});
|
|
25
|
-
it("returns false for a TS file in a backend service directory", () => {
|
|
26
|
-
expect(isFrontendFile("src/services/AuthService.ts")).toBe(false);
|
|
27
|
-
});
|
|
28
|
-
it("returns true for a TS file in components/ (tsx? matches .ts)", () => {
|
|
29
|
-
// FRONTEND_FILE_PATTERN uses tsx? which matches both .ts and .tsx
|
|
30
|
-
expect(isFrontendFile("src/components/utils.ts")).toBe(true);
|
|
31
|
-
});
|
|
32
|
-
it("returns false for a backend TS file in api/ even with tsx extension", () => {
|
|
33
|
-
expect(isFrontendFile("src/api/handlers/UserHandler.tsx")).toBe(false);
|
|
34
|
-
});
|
|
35
|
-
// Regression cases from three-tier logic
|
|
36
|
-
it("returns true for SvelteKit page in routes/ (svelte is always frontend)", () => {
|
|
37
|
-
expect(isFrontendFile("src/routes/+page.svelte")).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
it("returns false for Next.js API route (.tsx in pages/api/)", () => {
|
|
40
|
-
expect(isFrontendFile("pages/api/users.tsx")).toBe(false);
|
|
41
|
-
});
|
|
42
|
-
it("returns true for a standalone TSX component (no API dir)", () => {
|
|
43
|
-
expect(isFrontendFile("Button.tsx")).toBe(true);
|
|
44
|
-
});
|
|
45
|
-
it("returns true for an App.vue file", () => {
|
|
46
|
-
expect(isFrontendFile("App.vue")).toBe(true);
|
|
47
|
-
});
|
|
48
|
-
// .tsx/.jsx in non-standard dirs (lib/, shared/, helpers/) — tier 2 fires because
|
|
49
|
-
// JSX syntax is inherently frontend; no backend framework uses .tsx outside API dirs.
|
|
50
|
-
it("returns true for a TSX helper in lib/ (JSX implies frontend, no API dir)", () => {
|
|
51
|
-
expect(isFrontendFile("lib/FormHelpers.tsx")).toBe(true);
|
|
52
|
-
});
|
|
53
|
-
it("returns true for a JSX component in shared/", () => {
|
|
54
|
-
expect(isFrontendFile("shared/helpers.jsx")).toBe(true);
|
|
55
|
-
});
|
|
56
|
-
// .ts in a non-frontend dir stays false — plain TypeScript needs directory context.
|
|
57
|
-
it("returns false for a plain TS utility in lib/ (no frontend dir, tier 3 applies)", () => {
|
|
58
|
-
expect(isFrontendFile("lib/utils.ts")).toBe(false);
|
|
59
|
-
});
|
|
60
|
-
it("returns false for a plain TS API client in utils/ (no frontend dir)", () => {
|
|
61
|
-
expect(isFrontendFile("utils/apiClient.ts")).toBe(false);
|
|
62
|
-
});
|
|
63
|
-
// Flutter / Dart support — gated on hasFlutterSdkDep.
|
|
64
|
-
// Without the flag, .dart is unrecognised (legacy behaviour). With it,
|
|
65
|
-
// .dart is always-frontend (tier 2, before API_DIR_PATTERN).
|
|
66
|
-
describe(".dart files (Flutter)", () => {
|
|
67
|
-
it("returns false for .dart without hasFlutterSdkDep (default)", () => {
|
|
68
|
-
expect(isFrontendFile("lib/main.dart")).toBe(false);
|
|
69
|
-
});
|
|
70
|
-
it("returns false for .dart with hasFlutterSdkDep: false", () => {
|
|
71
|
-
expect(isFrontendFile("lib/main.dart", { hasFlutterSdkDep: false })).toBe(false);
|
|
72
|
-
});
|
|
73
|
-
it("returns true for .dart with hasFlutterSdkDep: true", () => {
|
|
74
|
-
expect(isFrontendFile("lib/main.dart", { hasFlutterSdkDep: true })).toBe(true);
|
|
75
|
-
});
|
|
76
|
-
it("returns true for nested .dart files in a Flutter project", () => {
|
|
77
|
-
expect(isFrontendFile("lib/widgets/game_board.dart", { hasFlutterSdkDep: true })).toBe(true);
|
|
78
|
-
});
|
|
79
|
-
it("returns true for .dart even in a directory that would otherwise look API-like (Flutter has no server-side Dart in scope)", () => {
|
|
80
|
-
// .dart sits in tier 2 (above API_DIR_PATTERN) so it's frontend even
|
|
81
|
-
// under api/ — there's no server-side Dart web framework that would
|
|
82
|
-
// make this ambiguous in the Flutter case.
|
|
83
|
-
expect(isFrontendFile("lib/api/client.dart", { hasFlutterSdkDep: true })).toBe(true);
|
|
84
|
-
});
|
|
85
|
-
it("returns true for game.dart at repo root in a Flutter project", () => {
|
|
86
|
-
expect(isFrontendFile("game.dart", { hasFlutterSdkDep: true })).toBe(true);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
// ---------------------------------------------------------------------------
|
|
91
|
-
// hasFlutterSdkDep
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
describe("hasFlutterSdkDep", () => {
|
|
94
|
-
let tmpDir;
|
|
95
|
-
beforeEach(() => {
|
|
96
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "flutter-pubspec-"));
|
|
97
|
-
});
|
|
98
|
-
afterEach(() => {
|
|
99
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
100
|
-
});
|
|
101
|
-
it("returns false when pubspec.yaml is absent", () => {
|
|
102
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(false);
|
|
103
|
-
});
|
|
104
|
-
it("returns true when pubspec.yaml has the canonical Flutter SDK dep", () => {
|
|
105
|
-
fs.writeFileSync(path.join(tmpDir, "pubspec.yaml"), `name: birdle
|
|
106
|
-
description: A Flutter app.
|
|
107
|
-
dependencies:
|
|
108
|
-
flutter:
|
|
109
|
-
sdk: flutter
|
|
110
|
-
cupertino_icons: ^1.0.6
|
|
111
|
-
`);
|
|
112
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(true);
|
|
113
|
-
});
|
|
114
|
-
it("returns false for a pure Dart project (no flutter SDK dep)", () => {
|
|
115
|
-
// Pure Dart server (e.g. shelf, dart_frog) has pubspec.yaml but no flutter SDK
|
|
116
|
-
fs.writeFileSync(path.join(tmpDir, "pubspec.yaml"), `name: my_dart_server
|
|
117
|
-
description: A Dart server using shelf.
|
|
118
|
-
environment:
|
|
119
|
-
sdk: ">=3.0.0 <4.0.0"
|
|
120
|
-
dependencies:
|
|
121
|
-
shelf: ^1.4.0
|
|
122
|
-
shelf_router: ^1.1.4
|
|
123
|
-
`);
|
|
124
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(false);
|
|
125
|
-
});
|
|
126
|
-
it("returns false for a Dart CLI tool (no flutter SDK dep)", () => {
|
|
127
|
-
fs.writeFileSync(path.join(tmpDir, "pubspec.yaml"), `name: my_cli
|
|
128
|
-
description: A Dart CLI.
|
|
129
|
-
environment:
|
|
130
|
-
sdk: ^3.5.0
|
|
131
|
-
dependencies:
|
|
132
|
-
args: ^2.5.0
|
|
133
|
-
`);
|
|
134
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(false);
|
|
135
|
-
});
|
|
136
|
-
it("returns false on a malformed pubspec.yaml (graceful failure)", () => {
|
|
137
|
-
fs.writeFileSync(path.join(tmpDir, "pubspec.yaml"), "::: not yaml ::: \x00");
|
|
138
|
-
// Our regex-based check still works on string content; this is more of
|
|
139
|
-
// a "doesn't throw" test. Returns false because the malformed content
|
|
140
|
-
// doesn't match the sdk: flutter pattern.
|
|
141
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(false);
|
|
142
|
-
});
|
|
143
|
-
it("returns true even with extra whitespace and comments in pubspec.yaml", () => {
|
|
144
|
-
fs.writeFileSync(path.join(tmpDir, "pubspec.yaml"), `name: birdle
|
|
145
|
-
# This is the SDK dep
|
|
146
|
-
dependencies:
|
|
147
|
-
flutter:
|
|
148
|
-
sdk: flutter
|
|
149
|
-
`);
|
|
150
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(true);
|
|
151
|
-
});
|
|
152
|
-
// Subdir search — common shapes in real Flutter repos.
|
|
153
|
-
it("returns true when pubspec.yaml lives in app/", () => {
|
|
154
|
-
fs.mkdirSync(path.join(tmpDir, "app"));
|
|
155
|
-
fs.writeFileSync(path.join(tmpDir, "app", "pubspec.yaml"), "name: app\ndependencies:\n flutter:\n sdk: flutter\n");
|
|
156
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(true);
|
|
157
|
-
});
|
|
158
|
-
it("returns true when pubspec.yaml lives in mobile/", () => {
|
|
159
|
-
fs.mkdirSync(path.join(tmpDir, "mobile"));
|
|
160
|
-
fs.writeFileSync(path.join(tmpDir, "mobile", "pubspec.yaml"), "name: app\ndependencies:\n flutter:\n sdk: flutter\n");
|
|
161
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(true);
|
|
162
|
-
});
|
|
163
|
-
it("returns true for monorepo with apps/<name>/pubspec.yaml", () => {
|
|
164
|
-
fs.mkdirSync(path.join(tmpDir, "apps", "customer-app"), { recursive: true });
|
|
165
|
-
fs.writeFileSync(path.join(tmpDir, "apps", "customer-app", "pubspec.yaml"), "name: customer_app\ndependencies:\n flutter:\n sdk: flutter\n");
|
|
166
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(true);
|
|
167
|
-
});
|
|
168
|
-
it("returns true for monorepo with packages/<name>/pubspec.yaml", () => {
|
|
169
|
-
fs.mkdirSync(path.join(tmpDir, "packages", "ui"), { recursive: true });
|
|
170
|
-
fs.writeFileSync(path.join(tmpDir, "packages", "ui", "pubspec.yaml"), "name: ui\ndependencies:\n flutter:\n sdk: flutter\n");
|
|
171
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(true);
|
|
172
|
-
});
|
|
173
|
-
it("returns false when monorepo subdirs only contain pure-Dart packages", () => {
|
|
174
|
-
// Mixed monorepo: a Dart CLI in packages/cli/, no Flutter app anywhere.
|
|
175
|
-
fs.mkdirSync(path.join(tmpDir, "packages", "cli"), { recursive: true });
|
|
176
|
-
fs.writeFileSync(path.join(tmpDir, "packages", "cli", "pubspec.yaml"), "name: cli\ndependencies:\n args: ^2.5.0\n");
|
|
177
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(false);
|
|
178
|
-
});
|
|
179
|
-
it("does not walk arbitrary subdirs (e.g. node_modules-style nested deps)", () => {
|
|
180
|
-
// A pubspec deep under an unsupported subdir should NOT be picked up.
|
|
181
|
-
// Without this guard, a transitive dependency's pubspec could falsely
|
|
182
|
-
// flag a non-Flutter repo as Flutter.
|
|
183
|
-
fs.mkdirSync(path.join(tmpDir, "vendor", "nested", "lib"), { recursive: true });
|
|
184
|
-
fs.writeFileSync(path.join(tmpDir, "vendor", "nested", "lib", "pubspec.yaml"), "name: nested\ndependencies:\n flutter:\n sdk: flutter\n");
|
|
185
|
-
expect(hasFlutterSdkDep(tmpDir)).toBe(false);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
// ---------------------------------------------------------------------------
|
|
189
|
-
// isTestFile
|
|
190
|
-
// ---------------------------------------------------------------------------
|
|
191
|
-
describe("isTestFile", () => {
|
|
192
|
-
it("matches Skyramp-generated test suffix patterns", () => {
|
|
193
|
-
expect(isTestFile("backend/tests/orders_integration_test.py")).toBe(true);
|
|
194
|
-
expect(isTestFile("frontend/tests/cart_ui_test.ts")).toBe(true);
|
|
195
|
-
expect(isTestFile("backend/tests/users_contract_test.py")).toBe(true);
|
|
196
|
-
expect(isTestFile("backend/tests/load_test.py")).toBe(true);
|
|
197
|
-
});
|
|
198
|
-
it("matches Skyramp scenario JSON files", () => {
|
|
199
|
-
expect(isTestFile("tests/scenario_orders.json")).toBe(true);
|
|
200
|
-
expect(isTestFile("scenario_checkout.json")).toBe(true);
|
|
201
|
-
});
|
|
202
|
-
it("matches conventional Vitest/Jest/Playwright spec naming", () => {
|
|
203
|
-
expect(isTestFile("frontend/tests/cart_labels_baseline.spec.ts")).toBe(true);
|
|
204
|
-
expect(isTestFile("src/components/Button.test.tsx")).toBe(true);
|
|
205
|
-
expect(isTestFile("e2e/login.spec.js")).toBe(true);
|
|
206
|
-
expect(isTestFile("packages/foo/Bar.test.jsx")).toBe(true);
|
|
207
|
-
// `.e2e.` dot form (Playwright/Cypress) — discovery's UI_TEST_EXT treats it as a UI test.
|
|
208
|
-
expect(isTestFile("e2e/login.e2e.ts")).toBe(true);
|
|
209
|
-
expect(isTestFile("packages/foo/Members.e2e.tsx")).toBe(true);
|
|
210
|
-
});
|
|
211
|
-
it("matches files under __tests__/ directories", () => {
|
|
212
|
-
expect(isTestFile("src/__tests__/utils.ts")).toBe(true);
|
|
213
|
-
expect(isTestFile("packages/foo/__tests__/Bar.tsx")).toBe(true);
|
|
214
|
-
});
|
|
215
|
-
it("returns false for ordinary source files", () => {
|
|
216
|
-
expect(isTestFile("frontend/src/pages/Cart.tsx")).toBe(false);
|
|
217
|
-
expect(isTestFile("frontend/src/components/Button.tsx")).toBe(false);
|
|
218
|
-
expect(isTestFile("backend/src/handlers/orders.py")).toBe(false);
|
|
219
|
-
});
|
|
220
|
-
it("returns false for non-spec .ts files in tests/ directories that aren't Skyramp-generated", () => {
|
|
221
|
-
// Tests/ directory alone doesn't trigger isTestFile — only the suffix matters.
|
|
222
|
-
expect(isTestFile("frontend/tests/helpers/setup.ts")).toBe(false);
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
// ---------------------------------------------------------------------------
|
|
226
|
-
// buildScopeAssessmentSection
|
|
227
|
-
// ---------------------------------------------------------------------------
|
|
228
|
-
describe("buildScopeAssessmentSection", () => {
|
|
229
|
-
it("produces a valid range in Step C for normal inputs (topN > maxGenerate)", () => {
|
|
230
|
-
const section = buildScopeAssessmentSection(10, 3);
|
|
231
|
-
// minTotal = min(3+1, 10) = 4; range should be "4–10"
|
|
232
|
-
expect(section).toContain("4–10");
|
|
233
|
-
expect(section).toContain("3 (generate) + 1 (min additional) = 4");
|
|
234
|
-
});
|
|
235
|
-
it("clamps minTotal to maxTotal when maxTotal === maxGenerate (regression: no inverted range)", () => {
|
|
236
|
-
// Edge case from review: topN=4, maxGenerate=4 → minTotal must not exceed maxTotal
|
|
237
|
-
const section = buildScopeAssessmentSection(4, 4);
|
|
238
|
-
// minTotal = min(4+1, 4) = 4; range should be "4–4", NOT "5–4"
|
|
239
|
-
expect(section).toContain("4–4");
|
|
240
|
-
// minAdditional = 4 - 4 = 0; baseline should say "0 (min additional)"
|
|
241
|
-
expect(section).toContain("4 (generate) + 0 (min additional) = 4");
|
|
242
|
-
// Must NOT contain an inverted range
|
|
243
|
-
expect(section).not.toMatch(/\b5–4\b/);
|
|
244
|
-
});
|
|
245
|
-
it("clamps minTotal to maxTotal when maxTotal < maxGenerate", () => {
|
|
246
|
-
// Defensive: maxGenerate clamped to topN upstream, but guard applies here too
|
|
247
|
-
const section = buildScopeAssessmentSection(3, 5);
|
|
248
|
-
// effectiveGenerate = min(5, 3) = 3; minTotal = min(3+1, 3) = 3; range "3–3"
|
|
249
|
-
expect(section).toContain("3–3");
|
|
250
|
-
expect(section).not.toMatch(/\b[6-9]–3\b/);
|
|
251
|
-
// Must not show original maxGenerate (5) in the formula
|
|
252
|
-
expect(section).toContain("3 (generate)");
|
|
253
|
-
expect(section).not.toContain("5 (generate)");
|
|
254
|
-
});
|
|
255
|
-
it("embeds UI/E2E confirmation step when isUIOnly=true", () => {
|
|
256
|
-
const section = buildScopeAssessmentSection(10, 3, true);
|
|
257
|
-
expect(section).toContain("frontend-only PR");
|
|
258
|
-
expect(section).toContain("100% UI/E2E");
|
|
259
|
-
expect(section).not.toContain("Step D — Determine UI vs backend split");
|
|
260
|
-
});
|
|
261
|
-
it("embeds UI vs backend split step when isUIOnly=false", () => {
|
|
262
|
-
const section = buildScopeAssessmentSection(10, 3, false);
|
|
263
|
-
expect(section).toContain("Step D — Determine UI vs backend split");
|
|
264
|
-
expect(section).not.toContain("UI/E2E confirmation");
|
|
265
|
-
});
|
|
266
|
-
it("uses defaults matching MAX_RECOMMENDATIONS and MAX_TESTS_TO_GENERATE", () => {
|
|
267
|
-
// Should not throw and should produce a non-empty string
|
|
268
|
-
const section = buildScopeAssessmentSection();
|
|
269
|
-
expect(section.length).toBeGreaterThan(0);
|
|
270
|
-
expect(section).toContain("Budget Plan");
|
|
271
|
-
});
|
|
272
|
-
// ---------------------------------------------------------------------------
|
|
273
|
-
// New branches added in PR 453 (4a) — precomputedUIPct / hasFrontendChanges
|
|
274
|
-
// ---------------------------------------------------------------------------
|
|
275
|
-
it("emits a single Budget Plan line for backend-only PR (precomputedUIPct=0)", () => {
|
|
276
|
-
// isUIOnlyPR=false, hasFrontendChanges=false → precomputedUIPct=0
|
|
277
|
-
const section = buildScopeAssessmentSection(10, 3, false, 0, false);
|
|
278
|
-
expect(section).toContain("Budget Plan: 10 total (3 generate + 7 additional), 0% UI/E2E");
|
|
279
|
-
expect(section).toContain("Use these exact numbers throughout the rest of the prompt.");
|
|
280
|
-
// Must NOT include the step-based assessment
|
|
281
|
-
expect(section).not.toContain("Step A");
|
|
282
|
-
expect(section).not.toContain("Step B");
|
|
283
|
-
expect(section).not.toContain("Step C");
|
|
284
|
-
expect(section).not.toContain("Step D");
|
|
285
|
-
});
|
|
286
|
-
// ---------------------------------------------------------------------------
|
|
287
|
-
// SKYR-3820 — zero-classified backend diff: budget defaults to 0
|
|
288
|
-
// ---------------------------------------------------------------------------
|
|
289
|
-
it("defaults the Budget Plan to 0 total when precomputedUIPct=0 and hasClassifiedApiChanges=false (SKYR-3820)", () => {
|
|
290
|
-
const section = buildScopeAssessmentSection(20, 3, false, 0, false, false);
|
|
291
|
-
expect(section).toContain("Budget Plan: 0 total");
|
|
292
|
-
// The fixed budget mandate must NOT be asserted
|
|
293
|
-
expect(section).not.toContain("Budget Plan: 20 total (3 generate + 17 additional)");
|
|
294
|
-
expect(section).not.toContain("Use these exact numbers throughout the rest of the prompt.");
|
|
295
|
-
// The conditional ceiling names the numbers the agent may claim after code review
|
|
296
|
-
expect(section).toContain("up to 20 total (3 generate + 17 additional)");
|
|
297
|
-
});
|
|
298
|
-
it("keeps the fixed budget line when hasClassifiedApiChanges is omitted (back-compat default true)", () => {
|
|
299
|
-
const withDefault = buildScopeAssessmentSection(10, 3, false, 0, false);
|
|
300
|
-
const explicitTrue = buildScopeAssessmentSection(10, 3, false, 0, false, true);
|
|
301
|
-
expect(withDefault).toBe(explicitTrue);
|
|
302
|
-
expect(withDefault).toContain("Budget Plan: 10 total (3 generate + 7 additional), 0% UI/E2E");
|
|
303
|
-
expect(withDefault).not.toContain("Budget Plan: 0 total");
|
|
304
|
-
});
|
|
305
|
-
it("does not apply the zero-classified override to UI-only PRs (precomputedUIPct=100)", () => {
|
|
306
|
-
// UI-only PRs have hasApiChanges=false by construction — the override must be
|
|
307
|
-
// gated on the backend branch (precomputedUIPct === 0) only.
|
|
308
|
-
const section = buildScopeAssessmentSection(10, 3, true, 100, false, false);
|
|
309
|
-
expect(section).toContain("Budget Plan: 10 total (3 generate + 7 additional), 100% UI/E2E");
|
|
310
|
-
expect(section).not.toContain("Budget Plan: 0 total");
|
|
311
|
-
});
|
|
312
|
-
it("does not apply the zero-classified override to the mixed-PR branch", () => {
|
|
313
|
-
const section = buildScopeAssessmentSection(10, 3, false, undefined, true, false);
|
|
314
|
-
expect(section).toContain("Budget Plan (total already determined)");
|
|
315
|
-
expect(section).toContain("Cosmetic-only override");
|
|
316
|
-
expect(section).not.toContain("Budget Plan: 0 total");
|
|
317
|
-
});
|
|
318
|
-
it("emits a single Budget Plan line for UI-only PR (precomputedUIPct=100)", () => {
|
|
319
|
-
const section = buildScopeAssessmentSection(10, 3, true, 100, false);
|
|
320
|
-
expect(section).toContain("Budget Plan: 10 total (3 generate + 7 additional), 100% UI/E2E");
|
|
321
|
-
expect(section).not.toContain("Step A");
|
|
322
|
-
expect(section).not.toContain("Step D");
|
|
323
|
-
});
|
|
324
|
-
it("emits Step D only for mixed PR (hasFrontendChanges=true, precomputedUIPct=undefined)", () => {
|
|
325
|
-
const section = buildScopeAssessmentSection(10, 3, false, undefined, true);
|
|
326
|
-
// Total is pre-determined — shows in the Budget Plan header
|
|
327
|
-
expect(section).toContain("Budget Plan (total already determined)");
|
|
328
|
-
expect(section).toContain("10 total (3 generate + 7 additional)");
|
|
329
|
-
// Step D is kept for UI/E2E split judgment
|
|
330
|
-
expect(section).toContain("Step D");
|
|
331
|
-
// The "Append your UI%" instruction must appear (comment #3222061560)
|
|
332
|
-
expect(section).toContain("Append your UI%");
|
|
333
|
-
// Steps A–C are skipped
|
|
334
|
-
expect(section).not.toContain("Step A");
|
|
335
|
-
expect(section).not.toContain("Step B");
|
|
336
|
-
expect(section).not.toContain("Step C");
|
|
337
|
-
});
|
|
338
|
-
it("offers a cosmetic-only abstention override in the mixed-PR branch", () => {
|
|
339
|
-
// Regression: a CSS-only diff classifies as frontend (hasFrontendChanges=true),
|
|
340
|
-
// which previously handed the agent a fixed total with no path to zero tests,
|
|
341
|
-
// tanking d1 coverage to 0 (eval 14-cart-css-cleanup).
|
|
342
|
-
const section = buildScopeAssessmentSection(10, 3, false, undefined, true);
|
|
343
|
-
expect(section).toContain("Cosmetic-only override");
|
|
344
|
-
expect(section).toContain("0 total");
|
|
345
|
-
// The override is self-contained: it must NOT depend on a "Task 3" that
|
|
346
|
-
// doesn't exist in standalone (non-testbot) render contexts, and it must
|
|
347
|
-
// tell the agent to skip the now-irrelevant UI% step.
|
|
348
|
-
expect(section).not.toContain("Task 3");
|
|
349
|
-
expect(section).toContain("skip Step D");
|
|
350
|
-
});
|
|
351
|
-
it("clamps additional to 0 when maxGenerate equals maxTotal (precomputed path)", () => {
|
|
352
|
-
// maxGenerate=5, maxTotal=5 → additional must be 0, not negative
|
|
353
|
-
const section = buildScopeAssessmentSection(5, 5, false, 0, false);
|
|
354
|
-
expect(section).toContain("5 generate + 0 additional");
|
|
355
|
-
expect(section).not.toMatch(/\d+ generate \+ -\d+ additional/);
|
|
356
|
-
});
|
|
357
|
-
it("clamps additional to 0 when maxGenerate exceeds maxTotal (defensive, precomputed path)", () => {
|
|
358
|
-
// Should never happen in normal usage but guard must hold
|
|
359
|
-
const section = buildScopeAssessmentSection(3, 5, false, 0, false);
|
|
360
|
-
expect(section).toContain("3 generate + 0 additional");
|
|
361
|
-
expect(section).not.toMatch(/\+ -\d+ additional/);
|
|
362
|
-
// Must not show unclamped maxGenerate
|
|
363
|
-
expect(section).not.toContain("5 generate");
|
|
364
|
-
});
|
|
365
|
-
it("clamps generate in mixed PR path when maxGenerate exceeds maxTotal", () => {
|
|
366
|
-
const section = buildScopeAssessmentSection(3, 5, false, undefined, true);
|
|
367
|
-
expect(section).toContain("3 generate + 0 additional");
|
|
368
|
-
expect(section).not.toContain("5 generate");
|
|
369
|
-
expect(section).not.toMatch(/\+ -\d+ additional/);
|
|
370
|
-
});
|
|
371
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|