Skip to content

Commit 94928c2

Browse files
committed
test(webview): type the TaskHeader thinking-effort spec doubles
Replace the any-typed test doubles in the thinking-effort chip spec: mockState now carries ClineMessage[]/HistoryItem[] arrays and a full HistoryItem currentTaskItem (typed factory), the context provider and findLastIndex mocks are parameter-typed/generic, mockModelInfo is a ModelInfo built from a shared fixture, and the ProviderSettings fixtures come from a typed factory instead of as-assertions. Test data and behavior unchanged. (CodeRabbit on trial PR 1379)
1 parent 8fac968 commit 94928c2

1 file changed

Lines changed: 43 additions & 39 deletions

File tree

webview-ui/src/components/chat/__tests__/TaskHeader.thinking-effort.spec.tsx

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react"
22
import { renderWithExtensionState, screen } from "@/utils/test-utils"
3-
import type { ProviderSettings } from "@roo-code/types"
3+
import type { ClineMessage, Experiments, HistoryItem, ModelInfo, ProviderSettings } from "@roo-code/types"
44

55
import TaskHeader, { TaskHeaderProps } from "../TaskHeader"
66

@@ -32,41 +32,60 @@ vi.mock("@vscode/webview-ui-toolkit/react", () => ({
3232
VSCodeBadge: ({ children }: { children: React.ReactNode }) => <div data-testid="vscode-badge">{children}</div>,
3333
}))
3434

35+
// DTE series 4/5: typed test doubles — structurally valid ExtensionState subset,
36+
// full ModelInfo / HistoryItem values and a ProviderSettings fixture factory
37+
// instead of any-typed assertions.
38+
const makeTaskItem = (id: string): HistoryItem => ({
39+
id,
40+
number: 1,
41+
ts: Date.now(),
42+
task: "Test task",
43+
tokensIn: 100,
44+
tokensOut: 50,
45+
totalCost: 0.05,
46+
})
47+
48+
const anthropicSettings = (overrides: Pick<ProviderSettings, "reasoningEffort"> = {}): ProviderSettings => ({
49+
apiProvider: "anthropic",
50+
apiKey: "test-key",
51+
apiModelId: "claude-3-opus-20240229",
52+
...overrides,
53+
})
54+
55+
const baseModelInfo: ModelInfo = {
56+
contextWindow: 1_000_000,
57+
maxTokens: 128_000,
58+
supportsPromptCache: true,
59+
supportsReasoningEffort: ["low", "medium", "high"],
60+
reasoningEffort: "medium",
61+
}
62+
3563
const mockState: {
3664
apiConfiguration: ProviderSettings
37-
currentTaskItem: { id: string } | null
38-
clineMessages: any[]
39-
taskHistory: any[]
40-
experiments: Record<string, boolean>
65+
currentTaskItem: HistoryItem | null
66+
clineMessages: ClineMessage[]
67+
taskHistory: HistoryItem[]
68+
experiments: Experiments
4169
taskThinkingEffort: { effort: string; source: string } | undefined
4270
} = {
43-
apiConfiguration: {
44-
apiProvider: "anthropic",
45-
apiKey: "test-key",
46-
apiModelId: "claude-3-opus-20240229",
47-
} as ProviderSettings,
48-
currentTaskItem: { id: "test-task-id" },
71+
apiConfiguration: anthropicSettings(),
72+
currentTaskItem: makeTaskItem("test-task-id"),
4973
clineMessages: [],
5074
taskHistory: [],
5175
experiments: { dynamicThinkingEffort: true },
5276
taskThinkingEffort: undefined,
5377
}
5478
vi.mock("@src/context/ExtensionStateContext", () => ({
55-
ExtensionStateContextProvider: ({ children }: any) => children,
79+
ExtensionStateContextProvider: ({ children }: { children: React.ReactNode }) => children,
5680
useExtensionState: () => mockState,
5781
}))
5882

5983
vi.mock("@roo/array", () => ({
60-
findLastIndex: (array: any[], predicate: (item: any) => boolean) => array.map(predicate).findLastIndex(Boolean),
84+
findLastIndex: <T,>(array: T[], predicate: (item: T) => boolean): number =>
85+
array.map(predicate).findLastIndex(Boolean),
6186
}))
6287

63-
let mockModelInfo: any = {
64-
contextWindow: 1_000_000,
65-
maxTokens: 128_000,
66-
supportsPromptCache: true,
67-
supportsReasoningEffort: ["low", "medium", "high"],
68-
reasoningEffort: "medium",
69-
}
88+
let mockModelInfo: ModelInfo = { ...baseModelInfo }
7089
vi.mock("@/components/ui/hooks/useSelectedModel", () => ({
7190
useSelectedModel: () => ({
7291
provider: "anthropic",
@@ -97,18 +116,8 @@ describe("TaskHeader - thinking effort chip (DTE series 4/5)", () => {
97116
mockMaxOutputTokens = 0
98117
mockState.experiments = { dynamicThinkingEffort: true }
99118
mockState.taskThinkingEffort = undefined
100-
mockState.apiConfiguration = {
101-
apiProvider: "anthropic",
102-
apiKey: "test-key",
103-
apiModelId: "claude-3-opus-20240229",
104-
} as ProviderSettings
105-
mockModelInfo = {
106-
contextWindow: 1_000_000,
107-
maxTokens: 128_000,
108-
supportsPromptCache: true,
109-
supportsReasoningEffort: ["low", "medium", "high"],
110-
reasoningEffort: "medium",
111-
}
119+
mockState.apiConfiguration = anthropicSettings()
120+
mockModelInfo = { ...baseModelInfo }
112121
})
113122

114123
const renderChip = () => renderWithExtensionState(<TaskHeader {...defaultProps} />)
@@ -128,19 +137,14 @@ describe("TaskHeader - thinking effort chip (DTE series 4/5)", () => {
128137
})
129138

130139
it("shows the settings-derived effort with a 'default' source badge", () => {
131-
mockState.apiConfiguration = { apiProvider: "anthropic", reasoningEffort: "medium" } as ProviderSettings
140+
mockState.apiConfiguration = anthropicSettings({ reasoningEffort: "medium" })
132141
renderChip()
133142
expect(screen.getByText("medium")).toBeInTheDocument()
134143
expect(screen.getByText("default")).toBeInTheDocument()
135144
})
136145

137146
it("shows the adaptive soft-guidance level with 'Zoo (auto)' for boolean-class models", () => {
138-
mockModelInfo = {
139-
contextWindow: 1_000_000,
140-
maxTokens: 128_000,
141-
supportsPromptCache: false,
142-
supportsReasoningEffort: true,
143-
}
147+
mockModelInfo = { ...baseModelInfo, supportsPromptCache: false, supportsReasoningEffort: true }
144148
renderChip()
145149
expect(screen.getByText("adaptive")).toBeInTheDocument()
146150
expect(screen.getByText("Zoo (auto)")).toBeInTheDocument()

0 commit comments

Comments
 (0)