-
Notifications
You must be signed in to change notification settings - Fork 212
Expand file tree
/
Copy pathContextWindowProgress.spec.tsx
More file actions
132 lines (105 loc) · 4.91 KB
/
Copy pathContextWindowProgress.spec.tsx
File metadata and controls
132 lines (105 loc) · 4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// npm run test ContextWindowProgress.spec.tsx
import { render, screen, fireEvent } from "@/utils/test-utils"
import TaskHeader from "@src/components/chat/TaskHeader"
// Mock formatLargeNumber function
vi.mock("@/utils/format", () => ({
formatLargeNumber: vi.fn((num) => num.toString()),
}))
// Mock VSCodeBadge component for all tests
vi.mock("@vscode/webview-ui-toolkit/react", () => ({
VSCodeBadge: ({ children }: { children: React.ReactNode }) => <div data-testid="vscode-badge">{children}</div>,
}))
// Mock ExtensionStateContext since we use useExtensionState
vi.mock("@src/context/ExtensionStateContext", () => ({
useExtensionState: vi.fn(() => ({
apiConfiguration: { apiProvider: "openai" },
currentTaskItem: { id: "test-id", number: 1, size: 1024 },
})),
}))
// Mock highlighting function to avoid JSX parsing issues in tests
vi.mock("@src/components/chat/TaskHeader", async () => {
const originalModule = await vi.importActual("@src/components/chat/TaskHeader")
return {
...originalModule,
highlightMentions: vi.fn((text) => text),
}
})
// Mock useSelectedModel hook
vi.mock("@src/components/ui/hooks/useSelectedModel", () => ({
useSelectedModel: vi.fn(() => ({
id: "test",
info: { contextWindow: 4000 },
})),
}))
describe("ContextWindowProgress", () => {
// Helper function to render just the ContextWindowProgress part through TaskHeader
const renderComponent = (props: Record<string, any>) => {
// Create a simple mock of the task that avoids importing the actual types
const defaultProps = {
task: { ts: Date.now(), type: "say" as const, say: "text" as const, text: "Test task" },
tokensIn: 100,
tokensOut: 50,
totalCost: 0.001,
contextTokens: 1000,
onClose: vi.fn(),
buttonsDisabled: false,
handleCondenseContext: vi.fn((_taskId: string) => {}),
}
return render(<TaskHeader {...defaultProps} {...props} />)
}
beforeEach(() => vi.clearAllMocks())
it("renders correctly with valid inputs", () => {
renderComponent({ contextTokens: 1000, contextWindow: 4000 })
// First expand the TaskHeader to access ContextWindowProgress
const taskHeader = screen.getByText("Test task")
fireEvent.click(taskHeader)
// Check for basic elements
// The context-window-label is not part of the ContextWindowProgress component
// but rather part of the parent TaskHeader component in expanded state
expect(screen.getByTestId("context-tokens-count")).toBeInTheDocument()
expect(screen.getByTestId("context-tokens-count")).toHaveTextContent("1000") // contextTokens
// The actual context window might be different than what we pass in
// due to the mock returning a default value from the API config
expect(screen.getByTestId("context-window-size")).toHaveTextContent(/(4000|128000)/) // contextWindow
})
it("handles zero context window gracefully", () => {
renderComponent({ contextTokens: 0, contextWindow: 0 })
// First expand the TaskHeader to access ContextWindowProgress
const taskHeader = screen.getByText("Test task")
fireEvent.click(taskHeader)
// In the current implementation, the component is still displayed with zero values
// rather than being hidden completely
// The context-window-label is not part of the ContextWindowProgress component
expect(screen.getByTestId("context-tokens-count")).toBeInTheDocument()
expect(screen.getByTestId("context-tokens-count")).toHaveTextContent("0")
})
it("handles edge cases with negative values", () => {
renderComponent({ contextTokens: -100, contextWindow: 4000 })
// First expand the TaskHeader to access ContextWindowProgress
const taskHeader = screen.getByText("Test task")
fireEvent.click(taskHeader)
// Should show 0 instead of -100
expect(screen.getByTestId("context-tokens-count")).toHaveTextContent("0")
// The actual context window might be different than what we pass in
expect(screen.getByTestId("context-window-size")).toHaveTextContent(/(4000|128000)/)
})
it("calculates percentages correctly", () => {
renderComponent({ contextTokens: 1000, contextWindow: 4000 })
// First expand the TaskHeader to access ContextWindowProgress
const taskHeader = screen.getByText("Test task")
fireEvent.click(taskHeader)
// Verify that the token count and window size are displayed correctly
const tokenCount = screen.getByTestId("context-tokens-count")
const windowSize = screen.getByTestId("context-window-size")
expect(tokenCount).toBeInTheDocument()
expect(tokenCount).toHaveTextContent("1000")
expect(windowSize).toBeInTheDocument()
expect(windowSize).toHaveTextContent("4000")
// The progress bar is now wrapped in tooltips, but we can verify the structure exists
// by checking for the progress bar container
const progressBarContainer = screen.getByTestId("context-tokens-count").parentElement
expect(progressBarContainer).toBeInTheDocument()
// Verify the flex container has the expected structure
expect(progressBarContainer?.querySelector(".flex-1.relative")).toBeInTheDocument()
})
})