Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/web-evals/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
globals: true,
watch: false,
},
})
1 change: 1 addition & 0 deletions packages/build/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export default defineConfig({
test: {
globals: true,
environment: "node",
watch: false,
},
})
1 change: 1 addition & 0 deletions packages/cloud/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default defineConfig({
test: {
globals: true,
environment: "node",
watch: false,
},
resolve: {
alias: {
Expand Down
1 change: 1 addition & 0 deletions packages/evals/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export default defineConfig({
globals: true,
environment: "node",
globalSetup: "./vitest-global-setup.ts",
watch: false,
},
})
1 change: 1 addition & 0 deletions packages/telemetry/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export default defineConfig({
test: {
globals: true,
environment: "node",
watch: false,
},
})
1 change: 1 addition & 0 deletions packages/types/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
globals: true,
watch: false,
},
})
137 changes: 137 additions & 0 deletions src/__mocks__/vitest-vscode-mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Mock VSCode API for Vitest tests
const mockEventEmitter = () => ({
event: () => () => {},
fire: () => {},
dispose: () => {},
})

const mockDisposable = {
dispose: () => {},
}

const mockUri = {
file: (path) => ({ fsPath: path, path, scheme: "file" }),
parse: (path) => ({ fsPath: path, path, scheme: "file" }),
}

const mockRange = class {
constructor(start, end) {
this.start = start
this.end = end
}
}

const mockPosition = class {
constructor(line, character) {
this.line = line
this.character = character
}
}

const mockSelection = class extends mockRange {
constructor(start, end) {
super(start, end)
this.anchor = start
this.active = end
}
}

export const workspace = {
workspaceFolders: [],
getWorkspaceFolder: () => null,
onDidChangeWorkspaceFolders: () => mockDisposable,
createFileSystemWatcher: () => ({
onDidCreate: () => mockDisposable,
onDidChange: () => mockDisposable,
onDidDelete: () => mockDisposable,
dispose: () => {},
}),
fs: {
readFile: () => Promise.resolve(new Uint8Array()),
writeFile: () => Promise.resolve(),
stat: () => Promise.resolve({ type: 1, ctime: 0, mtime: 0, size: 0 }),
},
}

export const window = {
activeTextEditor: null,
onDidChangeActiveTextEditor: () => mockDisposable,
showErrorMessage: () => Promise.resolve(),
showWarningMessage: () => Promise.resolve(),
showInformationMessage: () => Promise.resolve(),
createOutputChannel: () => ({
appendLine: () => {},
append: () => {},
clear: () => {},
show: () => {},
dispose: () => {},
}),
}

export const commands = {
registerCommand: () => mockDisposable,
executeCommand: () => Promise.resolve(),
}

export const languages = {
createDiagnosticCollection: () => ({
set: () => {},
delete: () => {},
clear: () => {},
dispose: () => {},
}),
}

export const extensions = {
getExtension: () => null,
}

export const env = {
openExternal: () => Promise.resolve(),
}

export const Uri = mockUri
export const Range = mockRange
export const Position = mockPosition
export const Selection = mockSelection
export const Disposable = mockDisposable

export const FileType = {
File: 1,
Directory: 2,
SymbolicLink: 64,
}

export const DiagnosticSeverity = {
Error: 0,
Warning: 1,
Information: 2,
Hint: 3,
}

export const OverviewRulerLane = {
Left: 1,
Center: 2,
Right: 4,
Full: 7,
}

export const EventEmitter = mockEventEmitter

export default {
workspace,
window,
commands,
languages,
extensions,
env,
Uri,
Range,
Position,
Selection,
Disposable,
FileType,
DiagnosticSeverity,
OverviewRulerLane,
EventEmitter,
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { vitest, describe, it, expect, beforeEach } from "vitest"
import * as vscode from "vscode"
import * as path from "path"
import * as fs from "fs/promises"
Expand All @@ -6,16 +7,16 @@ import { GlobalFileNames } from "../shared/globalFileNames"
import { migrateSettings } from "../utils/migrateSettings"

// Mock dependencies
jest.mock("vscode")
jest.mock("fs/promises", () => ({
mkdir: jest.fn().mockResolvedValue(undefined),
readFile: jest.fn(),
writeFile: jest.fn().mockResolvedValue(undefined),
rename: jest.fn().mockResolvedValue(undefined),
unlink: jest.fn().mockResolvedValue(undefined),
vitest.mock("vscode")
vitest.mock("fs/promises", () => ({
mkdir: vitest.fn().mockResolvedValue(undefined),
readFile: vitest.fn(),
writeFile: vitest.fn().mockResolvedValue(undefined),
rename: vitest.fn().mockResolvedValue(undefined),
unlink: vitest.fn().mockResolvedValue(undefined),
}))
jest.mock("fs")
jest.mock("../utils/fs")
vitest.mock("fs")
vitest.mock("../utils/fs")

describe("Settings Migration", () => {
let mockContext: vscode.ExtensionContext
Expand All @@ -33,16 +34,16 @@ describe("Settings Migration", () => {
const newMcpSettingsPath = path.join(mockSettingsDir, GlobalFileNames.mcpSettings)

beforeEach(() => {
jest.clearAllMocks()
vitest.clearAllMocks()

// Mock output channel
mockOutputChannel = {
appendLine: jest.fn(),
append: jest.fn(),
clear: jest.fn(),
show: jest.fn(),
hide: jest.fn(),
dispose: jest.fn(),
appendLine: vitest.fn(),
append: vitest.fn(),
clear: vitest.fn(),
show: vitest.fn(),
hide: vitest.fn(),
dispose: vitest.fn(),
} as unknown as vscode.OutputChannel

// Mock extension context
Expand All @@ -56,13 +57,13 @@ describe("Settings Migration", () => {

it("should migrate custom modes file if old file exists and new file doesn't", async () => {
// Clear all previous mocks to ensure clean test environment
jest.clearAllMocks()
vitest.clearAllMocks()

// Setup mock for rename function
const mockRename = (fs.rename as jest.Mock).mockResolvedValue(undefined)
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)

// Mock file existence checks - only return true for paths we want to exist
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
if (path === mockSettingsDir) return true
if (path === legacyClineCustomModesPath) return true
return false // All other paths don't exist, including destination files
Expand All @@ -77,13 +78,13 @@ describe("Settings Migration", () => {

it("should migrate MCP settings file if old file exists and new file doesn't", async () => {
// Clear all previous mocks to ensure clean test environment
jest.clearAllMocks()
vitest.clearAllMocks()

// Setup mock for rename function
const mockRename = (fs.rename as jest.Mock).mockResolvedValue(undefined)
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)

// Ensure the other files don't interfere with this test
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
if (path === mockSettingsDir) return true
if (path === legacyMcpSettingsPath) return true
if (path === legacyClineCustomModesPath) return false // Ensure this file doesn't exist
Expand All @@ -100,13 +101,13 @@ describe("Settings Migration", () => {

it("should not migrate if new file already exists", async () => {
// Clear all previous mocks to ensure clean test environment
jest.clearAllMocks()
vitest.clearAllMocks()

// Setup mock for rename function
const mockRename = (fs.rename as jest.Mock).mockResolvedValue(undefined)
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)

// Mock file existence checks - both source and destination exist
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
if (path === mockSettingsDir) return true
if (path === legacyClineCustomModesPath) return true
if (path === legacyCustomModesJson) return true // Destination already exists
Expand All @@ -123,10 +124,10 @@ describe("Settings Migration", () => {

it("should handle errors gracefully", async () => {
// Clear mocks
jest.clearAllMocks()
vitest.clearAllMocks()

// Mock file existence to throw error
;(fileExistsAtPath as jest.Mock).mockRejectedValue(new Error("Test error"))
vitest.mocked(fileExistsAtPath).mockRejectedValue(new Error("Test error"))

await migrateSettings(mockContext, mockOutputChannel)

Expand All @@ -138,24 +139,24 @@ describe("Settings Migration", () => {

it("should convert custom_modes.json to YAML format", async () => {
// Clear all previous mocks to ensure clean test environment
jest.clearAllMocks()
vitest.clearAllMocks()

const testJsonContent = JSON.stringify({ customModes: [{ slug: "test-mode", name: "Test Mode" }] })

// Setup mock functions
const mockWrite = (fs.writeFile as jest.Mock).mockResolvedValue(undefined)
const mockUnlink = (fs.unlink as jest.Mock).mockResolvedValue(undefined)
const mockWrite = vitest.mocked(fs.writeFile).mockResolvedValue(undefined)
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)

// Mock file read to return JSON content
;(fs.readFile as jest.Mock).mockImplementation(async (path: any) => {
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
if (path === legacyCustomModesJson) {
return testJsonContent
}
throw new Error("File not found: " + path)
})

// Isolate this test by making sure only the specific JSON file exists
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
if (path === mockSettingsDir) return true
if (path === legacyCustomModesJson) return true
if (path === legacyClineCustomModesPath) return false
Expand All @@ -178,22 +179,22 @@ describe("Settings Migration", () => {

it("should handle corrupt JSON gracefully", async () => {
// Clear all previous mocks to ensure clean test environment
jest.clearAllMocks()
vitest.clearAllMocks()

// Setup mock functions
const mockWrite = (fs.writeFile as jest.Mock).mockResolvedValue(undefined)
const mockUnlink = (fs.unlink as jest.Mock).mockResolvedValue(undefined)
const mockWrite = vitest.mocked(fs.writeFile).mockResolvedValue(undefined)
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)

// Mock file read to return corrupt JSON
;(fs.readFile as jest.Mock).mockImplementation(async (path: any) => {
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
if (path === legacyCustomModesJson) {
return "{ invalid json content" // This will cause an error when parsed
}
throw new Error("File not found: " + path)
})

// Isolate this test
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
if (path === mockSettingsDir) return true
if (path === legacyCustomModesJson) return true
if (path === legacyClineCustomModesPath) return false
Expand All @@ -215,22 +216,22 @@ describe("Settings Migration", () => {

it("should skip migration when YAML file already exists", async () => {
// Clear all previous mocks to ensure clean test environment
jest.clearAllMocks()
vitest.clearAllMocks()

// Setup mock functions
const mockWrite = (fs.writeFile as jest.Mock).mockResolvedValue(undefined)
const mockUnlink = (fs.unlink as jest.Mock).mockResolvedValue(undefined)
const mockWrite = vitest.mocked(fs.writeFile).mockResolvedValue(undefined)
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)

// Mock file read
;(fs.readFile as jest.Mock).mockImplementation(async (path: any) => {
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
if (path === legacyCustomModesJson) {
return JSON.stringify({ customModes: [] })
}
throw new Error("File not found: " + path)
})

// Mock file existence checks - both source and yaml destination exist
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
if (path === mockSettingsDir) return true
if (path === legacyCustomModesJson) return true
if (path === newCustomModesYaml) return true // YAML already exists
Expand Down
Loading