Skip to content

Commit 395f55b

Browse files
Convert jest tests to vitest and disable default watch mode for vitest (#4568)
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
1 parent 5d8b161 commit 395f55b

File tree

72 files changed

+1425
-1127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1425
-1127
lines changed

apps/web-evals/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { defineConfig } from "vitest/config"
33
export default defineConfig({
44
test: {
55
globals: true,
6+
watch: false,
67
},
78
})

packages/build/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ export default defineConfig({
44
test: {
55
globals: true,
66
environment: "node",
7+
watch: false,
78
},
89
})

packages/cloud/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export default defineConfig({
44
test: {
55
globals: true,
66
environment: "node",
7+
watch: false,
78
},
89
resolve: {
910
alias: {

packages/evals/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ export default defineConfig({
55
globals: true,
66
environment: "node",
77
globalSetup: "./vitest-global-setup.ts",
8+
watch: false,
89
},
910
})

packages/telemetry/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ export default defineConfig({
44
test: {
55
globals: true,
66
environment: "node",
7+
watch: false,
78
},
89
})

packages/types/vitest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import { defineConfig } from "vitest/config"
33
export default defineConfig({
44
test: {
55
globals: true,
6+
watch: false,
67
},
78
})

src/__mocks__/vitest-vscode-mock.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Mock VSCode API for Vitest tests
2+
const mockEventEmitter = () => ({
3+
event: () => () => {},
4+
fire: () => {},
5+
dispose: () => {},
6+
})
7+
8+
const mockDisposable = {
9+
dispose: () => {},
10+
}
11+
12+
const mockUri = {
13+
file: (path) => ({ fsPath: path, path, scheme: "file" }),
14+
parse: (path) => ({ fsPath: path, path, scheme: "file" }),
15+
}
16+
17+
const mockRange = class {
18+
constructor(start, end) {
19+
this.start = start
20+
this.end = end
21+
}
22+
}
23+
24+
const mockPosition = class {
25+
constructor(line, character) {
26+
this.line = line
27+
this.character = character
28+
}
29+
}
30+
31+
const mockSelection = class extends mockRange {
32+
constructor(start, end) {
33+
super(start, end)
34+
this.anchor = start
35+
this.active = end
36+
}
37+
}
38+
39+
export const workspace = {
40+
workspaceFolders: [],
41+
getWorkspaceFolder: () => null,
42+
onDidChangeWorkspaceFolders: () => mockDisposable,
43+
createFileSystemWatcher: () => ({
44+
onDidCreate: () => mockDisposable,
45+
onDidChange: () => mockDisposable,
46+
onDidDelete: () => mockDisposable,
47+
dispose: () => {},
48+
}),
49+
fs: {
50+
readFile: () => Promise.resolve(new Uint8Array()),
51+
writeFile: () => Promise.resolve(),
52+
stat: () => Promise.resolve({ type: 1, ctime: 0, mtime: 0, size: 0 }),
53+
},
54+
}
55+
56+
export const window = {
57+
activeTextEditor: null,
58+
onDidChangeActiveTextEditor: () => mockDisposable,
59+
showErrorMessage: () => Promise.resolve(),
60+
showWarningMessage: () => Promise.resolve(),
61+
showInformationMessage: () => Promise.resolve(),
62+
createOutputChannel: () => ({
63+
appendLine: () => {},
64+
append: () => {},
65+
clear: () => {},
66+
show: () => {},
67+
dispose: () => {},
68+
}),
69+
}
70+
71+
export const commands = {
72+
registerCommand: () => mockDisposable,
73+
executeCommand: () => Promise.resolve(),
74+
}
75+
76+
export const languages = {
77+
createDiagnosticCollection: () => ({
78+
set: () => {},
79+
delete: () => {},
80+
clear: () => {},
81+
dispose: () => {},
82+
}),
83+
}
84+
85+
export const extensions = {
86+
getExtension: () => null,
87+
}
88+
89+
export const env = {
90+
openExternal: () => Promise.resolve(),
91+
}
92+
93+
export const Uri = mockUri
94+
export const Range = mockRange
95+
export const Position = mockPosition
96+
export const Selection = mockSelection
97+
export const Disposable = mockDisposable
98+
99+
export const FileType = {
100+
File: 1,
101+
Directory: 2,
102+
SymbolicLink: 64,
103+
}
104+
105+
export const DiagnosticSeverity = {
106+
Error: 0,
107+
Warning: 1,
108+
Information: 2,
109+
Hint: 3,
110+
}
111+
112+
export const OverviewRulerLane = {
113+
Left: 1,
114+
Center: 2,
115+
Right: 4,
116+
Full: 7,
117+
}
118+
119+
export const EventEmitter = mockEventEmitter
120+
121+
export default {
122+
workspace,
123+
window,
124+
commands,
125+
languages,
126+
extensions,
127+
env,
128+
Uri,
129+
Range,
130+
Position,
131+
Selection,
132+
Disposable,
133+
FileType,
134+
DiagnosticSeverity,
135+
OverviewRulerLane,
136+
EventEmitter,
137+
}

src/__tests__/migrateSettings.test.ts renamed to src/__tests__/migrateSettings.spec.ts

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { vitest, describe, it, expect, beforeEach } from "vitest"
12
import * as vscode from "vscode"
23
import * as path from "path"
34
import * as fs from "fs/promises"
@@ -6,16 +7,16 @@ import { GlobalFileNames } from "../shared/globalFileNames"
67
import { migrateSettings } from "../utils/migrateSettings"
78

89
// Mock dependencies
9-
jest.mock("vscode")
10-
jest.mock("fs/promises", () => ({
11-
mkdir: jest.fn().mockResolvedValue(undefined),
12-
readFile: jest.fn(),
13-
writeFile: jest.fn().mockResolvedValue(undefined),
14-
rename: jest.fn().mockResolvedValue(undefined),
15-
unlink: jest.fn().mockResolvedValue(undefined),
10+
vitest.mock("vscode")
11+
vitest.mock("fs/promises", () => ({
12+
mkdir: vitest.fn().mockResolvedValue(undefined),
13+
readFile: vitest.fn(),
14+
writeFile: vitest.fn().mockResolvedValue(undefined),
15+
rename: vitest.fn().mockResolvedValue(undefined),
16+
unlink: vitest.fn().mockResolvedValue(undefined),
1617
}))
17-
jest.mock("fs")
18-
jest.mock("../utils/fs")
18+
vitest.mock("fs")
19+
vitest.mock("../utils/fs")
1920

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

3536
beforeEach(() => {
36-
jest.clearAllMocks()
37+
vitest.clearAllMocks()
3738

3839
// Mock output channel
3940
mockOutputChannel = {
40-
appendLine: jest.fn(),
41-
append: jest.fn(),
42-
clear: jest.fn(),
43-
show: jest.fn(),
44-
hide: jest.fn(),
45-
dispose: jest.fn(),
41+
appendLine: vitest.fn(),
42+
append: vitest.fn(),
43+
clear: vitest.fn(),
44+
show: vitest.fn(),
45+
hide: vitest.fn(),
46+
dispose: vitest.fn(),
4647
} as unknown as vscode.OutputChannel
4748

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

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

6162
// Setup mock for rename function
62-
const mockRename = (fs.rename as jest.Mock).mockResolvedValue(undefined)
63+
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)
6364

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

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

8283
// Setup mock for rename function
83-
const mockRename = (fs.rename as jest.Mock).mockResolvedValue(undefined)
84+
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)
8485

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

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

105106
// Setup mock for rename function
106-
const mockRename = (fs.rename as jest.Mock).mockResolvedValue(undefined)
107+
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)
107108

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

124125
it("should handle errors gracefully", async () => {
125126
// Clear mocks
126-
jest.clearAllMocks()
127+
vitest.clearAllMocks()
127128

128129
// Mock file existence to throw error
129-
;(fileExistsAtPath as jest.Mock).mockRejectedValue(new Error("Test error"))
130+
vitest.mocked(fileExistsAtPath).mockRejectedValue(new Error("Test error"))
130131

131132
await migrateSettings(mockContext, mockOutputChannel)
132133

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

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

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

145146
// Setup mock functions
146-
const mockWrite = (fs.writeFile as jest.Mock).mockResolvedValue(undefined)
147-
const mockUnlink = (fs.unlink as jest.Mock).mockResolvedValue(undefined)
147+
const mockWrite = vitest.mocked(fs.writeFile).mockResolvedValue(undefined)
148+
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)
148149

149150
// Mock file read to return JSON content
150-
;(fs.readFile as jest.Mock).mockImplementation(async (path: any) => {
151+
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
151152
if (path === legacyCustomModesJson) {
152153
return testJsonContent
153154
}
154155
throw new Error("File not found: " + path)
155156
})
156157

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

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

183184
// Setup mock functions
184-
const mockWrite = (fs.writeFile as jest.Mock).mockResolvedValue(undefined)
185-
const mockUnlink = (fs.unlink as jest.Mock).mockResolvedValue(undefined)
185+
const mockWrite = vitest.mocked(fs.writeFile).mockResolvedValue(undefined)
186+
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)
186187

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

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

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

220221
// Setup mock functions
221-
const mockWrite = (fs.writeFile as jest.Mock).mockResolvedValue(undefined)
222-
const mockUnlink = (fs.unlink as jest.Mock).mockResolvedValue(undefined)
222+
const mockWrite = vitest.mocked(fs.writeFile).mockResolvedValue(undefined)
223+
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)
223224

224225
// Mock file read
225-
;(fs.readFile as jest.Mock).mockImplementation(async (path: any) => {
226+
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
226227
if (path === legacyCustomModesJson) {
227228
return JSON.stringify({ customModes: [] })
228229
}
229230
throw new Error("File not found: " + path)
230231
})
231232

232233
// Mock file existence checks - both source and yaml destination exist
233-
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
234+
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
234235
if (path === mockSettingsDir) return true
235236
if (path === legacyCustomModesJson) return true
236237
if (path === newCustomModesYaml) return true // YAML already exists

0 commit comments

Comments
 (0)