Skip to content

Commit bbc64c3

Browse files
committed
refactor: use the new refeshTerminal function
1 parent 449f6d4 commit bbc64c3

File tree

2 files changed

+83
-37
lines changed

2 files changed

+83
-37
lines changed

cli/src/commands/__tests__/theme.test.ts

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,25 @@ import type { CommandContext } from "../core/types.js"
88
import type { Theme } from "../../types/theme.js"
99
import type { CLIConfig } from "../../config/types.js"
1010

11+
// Mock the generateMessage utility
12+
vi.mock("../../ui/utils/messages.js", () => ({
13+
generateMessage: vi.fn(() => ({
14+
id: "mock-id",
15+
createdAt: Date.now(),
16+
})),
17+
}))
18+
1119
describe("/theme command", () => {
1220
let mockContext: CommandContext
1321
let addMessageMock: ReturnType<typeof vi.fn>
1422
let setThemeMock: ReturnType<typeof vi.fn>
23+
let refreshTerminalMock: ReturnType<typeof vi.fn>
24+
let mockConfig: CLIConfig
1525

1626
const mockTheme: Theme = {
1727
id: "custom-theme",
1828
name: "Test Theme",
19-
type: "Custom",
29+
type: "custom",
2030
brand: {
2131
primary: "#007acc",
2232
secondary: "#005a9e",
@@ -83,6 +93,19 @@ describe("/theme command", () => {
8393
beforeEach(() => {
8494
addMessageMock = vi.fn()
8595
setThemeMock = vi.fn().mockResolvedValue(undefined)
96+
refreshTerminalMock = vi.fn().mockResolvedValue(undefined)
97+
98+
// Create mock config
99+
mockConfig = {
100+
version: "1.0.0",
101+
mode: "code",
102+
telemetry: true,
103+
provider: "test-provider",
104+
providers: [],
105+
customThemes: {
106+
"custom-theme": mockTheme,
107+
},
108+
}
86109

87110
// Mock config loading
88111
vi.doMock("../../config/persistence.js", () => ({
@@ -111,7 +134,7 @@ describe("/theme command", () => {
111134
dark: {
112135
id: "dark",
113136
name: "Dark",
114-
type: "Dark",
137+
type: "dark",
115138
brand: { primary: "#3b82f6", secondary: "#1d4ed8" },
116139
semantic: {
117140
success: "#4ade80",
@@ -146,7 +169,7 @@ describe("/theme command", () => {
146169
light: {
147170
id: "light",
148171
name: "Light",
149-
type: "Light",
172+
type: "light",
150173
brand: { primary: "#3b82f6", secondary: "#1d4ed8" },
151174
semantic: {
152175
success: "#4ade80",
@@ -184,7 +207,7 @@ describe("/theme command", () => {
184207
themes[id] || {
185208
id: "unknown",
186209
name: "Unknown Theme",
187-
type: "Dark",
210+
type: "dark",
188211
brand: { primary: "#000000", secondary: "#000000" },
189212
semantic: {
190213
success: "#000000",
@@ -230,14 +253,19 @@ describe("/theme command", () => {
230253
input: "/theme",
231254
args: [],
232255
options: {},
256+
config: mockConfig,
233257
sendMessage: vi.fn().mockResolvedValue(undefined),
234258
addMessage: addMessageMock,
235259
clearMessages: vi.fn(),
236260
replaceMessages: vi.fn(),
261+
setMessageCutoffTimestamp: vi.fn(),
237262
clearTask: vi.fn().mockResolvedValue(undefined),
238263
setMode: vi.fn(),
239264
exit: vi.fn(),
240265
setTheme: setThemeMock,
266+
setCommittingParallelMode: vi.fn(),
267+
isParallelMode: false,
268+
refreshTerminal: refreshTerminalMock,
241269
// Model-related context
242270
routerModels: null,
243271
currentProvider: null,
@@ -251,6 +279,21 @@ describe("/theme command", () => {
251279
balanceData: null,
252280
profileLoading: false,
253281
balanceLoading: false,
282+
// Task history context
283+
taskHistoryData: null,
284+
taskHistoryFilters: {
285+
workspace: "current",
286+
sort: "newest",
287+
favoritesOnly: false,
288+
},
289+
taskHistoryLoading: false,
290+
taskHistoryError: null,
291+
fetchTaskHistory: vi.fn().mockResolvedValue(undefined),
292+
updateTaskHistoryFilters: vi.fn().mockResolvedValue(null),
293+
changeTaskHistoryPage: vi.fn().mockResolvedValue(null),
294+
nextTaskHistoryPage: vi.fn().mockResolvedValue(null),
295+
previousTaskHistoryPage: vi.fn().mockResolvedValue(null),
296+
sendWebviewMessage: vi.fn().mockResolvedValue(undefined),
254297
}
255298
})
256299

@@ -308,17 +351,17 @@ describe("/theme command", () => {
308351
const message = addMessageMock.mock.calls[0][0]
309352
expect(message.type).toBe("system")
310353
expect(message.content).toContain("Available Themes:")
311-
expect(message.content).toContain("**Dark:**")
312-
expect(message.content).toContain("**Light:**")
313-
expect(message.content).toContain("**Custom:**")
354+
expect(message.content).toContain("**dark:**")
355+
expect(message.content).toContain("**light:**")
356+
expect(message.content).toContain("**custom:**")
314357
expect(message.content).toContain("Usage: /theme <theme-name>")
315358
})
316359

317360
it("should show custom themes when present", async () => {
318361
await themeCommand.handler(mockContext)
319362

320363
const message = addMessageMock.mock.calls[0][0]
321-
expect(message.content).toContain("**Custom:**")
364+
expect(message.content).toContain("**custom:**")
322365
expect(message.content).toContain("Test Theme")
323366
expect(message.content).toContain("(custom-theme)")
324367
})
@@ -330,27 +373,29 @@ describe("/theme command", () => {
330373

331374
await themeCommand.handler(mockContext)
332375

333-
expect(setThemeMock).toHaveBeenCalledTimes(1)
334-
expect(setThemeMock).toHaveBeenCalledWith("dark")
335-
336376
expect(addMessageMock).toHaveBeenCalledTimes(1)
337377
const message = addMessageMock.mock.calls[0][0]
338378
expect(message.type).toBe("system")
339379
expect(message.content).toContain("Switched to **Dark** theme.")
380+
381+
expect(setThemeMock).toHaveBeenCalledTimes(1)
382+
expect(setThemeMock).toHaveBeenCalledWith("dark")
383+
expect(refreshTerminalMock).toHaveBeenCalledTimes(1)
340384
})
341385

342386
it("should switch to a custom theme", async () => {
343387
mockContext.args = ["custom-theme"]
344388

345389
await themeCommand.handler(mockContext)
346390

347-
expect(setThemeMock).toHaveBeenCalledTimes(1)
348-
expect(setThemeMock).toHaveBeenCalledWith("custom-theme")
349-
350391
expect(addMessageMock).toHaveBeenCalledTimes(1)
351392
const message = addMessageMock.mock.calls[0][0]
352393
expect(message.type).toBe("system")
353394
expect(message.content).toContain("Switched to **Test Theme** theme.")
395+
396+
expect(setThemeMock).toHaveBeenCalledTimes(1)
397+
expect(setThemeMock).toHaveBeenCalledWith("custom-theme")
398+
expect(refreshTerminalMock).toHaveBeenCalledTimes(1)
354399
})
355400

356401
it("should show error for invalid theme", async () => {
@@ -375,13 +420,18 @@ describe("/theme command", () => {
375420

376421
await themeCommand.handler(mockContext)
377422

378-
expect(setThemeMock).toHaveBeenCalledWith("dark")
423+
// Message is added before setTheme, then error message is added
424+
expect(addMessageMock).toHaveBeenCalledTimes(2)
425+
const successMessage = addMessageMock.mock.calls[0][0]
426+
expect(successMessage.type).toBe("system")
427+
expect(successMessage.content).toContain("Switched to **Dark** theme.")
379428

380-
expect(addMessageMock).toHaveBeenCalledTimes(1)
381-
const message = addMessageMock.mock.calls[0][0]
382-
expect(message.type).toBe("error")
383-
expect(message.content).toContain("Failed to switch to **Dark** theme")
384-
expect(message.content).toContain("Theme switching failed")
429+
const errorMessage = addMessageMock.mock.calls[1][0]
430+
expect(errorMessage.type).toBe("error")
431+
expect(errorMessage.content).toContain("Failed to switch to **Dark** theme")
432+
expect(errorMessage.content).toContain("Theme switching failed")
433+
434+
expect(setThemeMock).toHaveBeenCalledWith("dark")
385435
})
386436

387437
it("should handle case insensitive theme names", async () => {
@@ -476,9 +526,9 @@ describe("/theme command", () => {
476526
expect(firstSuggestion).toHaveProperty("matchScore")
477527

478528
// Check that we have themes of different types
479-
const hasDark = suggestions.some((s) => typeof s !== "string" && s.description === "Dark")
480-
const hasLight = suggestions.some((s) => typeof s !== "string" && s.description === "Light")
481-
const hasCustom = suggestions.some((s) => typeof s !== "string" && s.description === "Custom")
529+
const hasDark = suggestions.some((s) => typeof s !== "string" && s.description === "dark")
530+
const hasLight = suggestions.some((s) => typeof s !== "string" && s.description === "light")
531+
const hasCustom = suggestions.some((s) => typeof s !== "string" && s.description === "custom")
482532

483533
expect(hasDark).toBe(true)
484534
expect(hasLight).toBe(true)
@@ -517,7 +567,7 @@ describe("/theme command", () => {
517567
command: themeCommand,
518568
commandContext: {
519569
...mockContext,
520-
config: {} as Record<string, unknown>, // Using an empty object to simulate config loading issues
570+
config: {} as CLIConfig,
521571
},
522572
}
523573

cli/src/commands/theme.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import type { Command, ArgumentProviderContext } from "./core/types.js"
66
import type { CLIConfig } from "../config/types.js"
77
import { getThemeById, getAvailableThemes } from "../constants/themes/index.js"
8-
import { messageResetCounterAtom } from "../state/atoms/ui.js"
8+
import { generateMessage } from "../ui/utils/messages.js"
99

1010
/**
1111
* Autocomplete provider for theme names
@@ -107,7 +107,7 @@ export const themeCommand: Command = {
107107
},
108108
],
109109
handler: async (context) => {
110-
const { args, addMessage, setTheme, config } = context
110+
const { args, addMessage, setTheme, config, refreshTerminal } = context
111111
const availableThemeIds = getAvailableThemes(config)
112112

113113
try {
@@ -154,10 +154,9 @@ export const themeCommand: Command = {
154154
helpText.push("Usage: /theme <theme-name>")
155155

156156
addMessage({
157-
id: Date.now().toString(),
157+
...generateMessage(),
158158
type: "system",
159159
content: helpText.join("\n"),
160-
ts: Date.now(),
161160
})
162161
return
163162
}
@@ -166,10 +165,9 @@ export const themeCommand: Command = {
166165

167166
if (!availableThemeIds.includes(requestedTheme)) {
168167
addMessage({
169-
id: Date.now().toString(),
168+
...generateMessage(),
170169
type: "error",
171170
content: `Invalid theme "${requestedTheme}". Available themes: ${availableThemeIds.join(", ")}`,
172-
ts: Date.now(),
173171
})
174172
return
175173
}
@@ -180,27 +178,25 @@ export const themeCommand: Command = {
180178

181179
try {
182180
addMessage({
183-
id: Date.now().toString(),
181+
...generateMessage(),
184182
type: "system",
185183
content: `Switched to **${themeName}** theme.`,
186-
ts: Date.now(),
187184
})
188-
setTheme(requestedTheme)
185+
await setTheme(requestedTheme)
186+
await refreshTerminal()
189187
} catch (error) {
190188
addMessage({
191-
id: Date.now().toString(),
189+
...generateMessage(),
192190
type: "error",
193191
content: `Failed to switch to **${themeName}** theme: ${error instanceof Error ? error.message : String(error)}`,
194-
ts: Date.now(),
195192
})
196193
}
197194
} catch (error) {
198195
// Handler-level error for unexpected issues (e.g., config corruption)
199196
addMessage({
200-
id: Date.now().toString(),
197+
...generateMessage(),
201198
type: "error",
202199
content: `Theme command failed: ${error instanceof Error ? error.message : String(error)}`,
203-
ts: Date.now(),
204200
})
205201
}
206202
},

0 commit comments

Comments
 (0)