Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Loading