|
1 | | -import { isToolAllowedForMode, FileRestrictionError, ModeConfig } from "../modes" |
| 1 | +// Mock setup must come before imports |
| 2 | +jest.mock("vscode") |
| 3 | +const mockAddCustomInstructions = jest.fn().mockResolvedValue("Combined instructions") |
| 4 | +jest.mock("../../core/prompts/sections/custom-instructions", () => ({ |
| 5 | + addCustomInstructions: mockAddCustomInstructions, |
| 6 | +})) |
| 7 | + |
| 8 | +import { isToolAllowedForMode, FileRestrictionError, ModeConfig, getFullModeDetails, modes } from "../modes" |
| 9 | +import * as vscode from "vscode" |
| 10 | +import { addCustomInstructions } from "../../core/prompts/sections/custom-instructions" |
2 | 11 |
|
3 | 12 | describe("isToolAllowedForMode", () => { |
4 | 13 | const customModes: ModeConfig[] = [ |
@@ -324,6 +333,96 @@ describe("FileRestrictionError", () => { |
324 | 333 | expect(error.name).toBe("FileRestrictionError") |
325 | 334 | }) |
326 | 335 |
|
| 336 | + describe("debug mode", () => { |
| 337 | + it("is configured correctly", () => { |
| 338 | + const debugMode = modes.find((mode) => mode.slug === "debug") |
| 339 | + expect(debugMode).toBeDefined() |
| 340 | + expect(debugMode).toMatchObject({ |
| 341 | + slug: "debug", |
| 342 | + name: "Debug", |
| 343 | + roleDefinition: |
| 344 | + "You are Roo, an expert software debugger specializing in systematic problem diagnosis and resolution.", |
| 345 | + groups: ["read", "edit", "browser", "command", "mcp"], |
| 346 | + }) |
| 347 | + expect(debugMode?.customInstructions).toContain("Reflect on 5-7 different possible sources of the problem") |
| 348 | + }) |
| 349 | + }) |
| 350 | + |
| 351 | + describe("getFullModeDetails", () => { |
| 352 | + beforeEach(() => { |
| 353 | + jest.clearAllMocks() |
| 354 | + ;(addCustomInstructions as jest.Mock).mockResolvedValue("Combined instructions") |
| 355 | + }) |
| 356 | + |
| 357 | + it("returns base mode when no overrides exist", async () => { |
| 358 | + const result = await getFullModeDetails("debug") |
| 359 | + expect(result).toMatchObject({ |
| 360 | + slug: "debug", |
| 361 | + name: "Debug", |
| 362 | + roleDefinition: |
| 363 | + "You are Roo, an expert software debugger specializing in systematic problem diagnosis and resolution.", |
| 364 | + }) |
| 365 | + }) |
| 366 | + |
| 367 | + it("applies custom mode overrides", async () => { |
| 368 | + const customModes = [ |
| 369 | + { |
| 370 | + slug: "debug", |
| 371 | + name: "Custom Debug", |
| 372 | + roleDefinition: "Custom debug role", |
| 373 | + groups: ["read"], |
| 374 | + }, |
| 375 | + ] |
| 376 | + |
| 377 | + const result = await getFullModeDetails("debug", customModes) |
| 378 | + expect(result).toMatchObject({ |
| 379 | + slug: "debug", |
| 380 | + name: "Custom Debug", |
| 381 | + roleDefinition: "Custom debug role", |
| 382 | + groups: ["read"], |
| 383 | + }) |
| 384 | + }) |
| 385 | + |
| 386 | + it("applies prompt component overrides", async () => { |
| 387 | + const customModePrompts = { |
| 388 | + debug: { |
| 389 | + roleDefinition: "Overridden role", |
| 390 | + customInstructions: "Overridden instructions", |
| 391 | + }, |
| 392 | + } |
| 393 | + |
| 394 | + const result = await getFullModeDetails("debug", undefined, customModePrompts) |
| 395 | + expect(result.roleDefinition).toBe("Overridden role") |
| 396 | + expect(result.customInstructions).toBe("Overridden instructions") |
| 397 | + }) |
| 398 | + |
| 399 | + it("combines custom instructions when cwd provided", async () => { |
| 400 | + const options = { |
| 401 | + cwd: "/test/path", |
| 402 | + globalCustomInstructions: "Global instructions", |
| 403 | + preferredLanguage: "en", |
| 404 | + } |
| 405 | + |
| 406 | + await getFullModeDetails("debug", undefined, undefined, options) |
| 407 | + |
| 408 | + expect(addCustomInstructions).toHaveBeenCalledWith( |
| 409 | + expect.any(String), |
| 410 | + "Global instructions", |
| 411 | + "/test/path", |
| 412 | + "debug", |
| 413 | + { preferredLanguage: "en" }, |
| 414 | + ) |
| 415 | + }) |
| 416 | + |
| 417 | + it("falls back to first mode for non-existent mode", async () => { |
| 418 | + const result = await getFullModeDetails("non-existent") |
| 419 | + expect(result).toMatchObject({ |
| 420 | + ...modes[0], |
| 421 | + customInstructions: "", |
| 422 | + }) |
| 423 | + }) |
| 424 | + }) |
| 425 | + |
327 | 426 | it("formats error message with description when provided", () => { |
328 | 427 | const error = new FileRestrictionError("Markdown Editor", "\\.md$", "Markdown files only", "test.js") |
329 | 428 | expect(error.message).toBe( |
|
0 commit comments