Prettier backfill

This commit is contained in:
Matt Rubens
2025-01-17 14:11:28 -05:00
parent 3bcb4ff8c5
commit 60a0a824b9
174 changed files with 15715 additions and 15428 deletions

View File

@@ -45,7 +45,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
setShowCopyModal(true)
setTimeout(() => setShowCopyModal(false), 2000)
} catch (error) {
console.error('Failed to copy to clipboard:', error)
console.error("Failed to copy to clipboard:", error)
}
}
@@ -70,7 +70,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
const fzf = useMemo(() => {
return new Fzf(presentableTasks, {
selector: item => item.task
selector: (item) => item.task,
})
}, [presentableTasks])
@@ -78,34 +78,34 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
let results = presentableTasks
if (searchQuery) {
const searchResults = fzf.find(searchQuery)
results = searchResults.map(result => ({
results = searchResults.map((result) => ({
...result.item,
task: highlightFzfMatch(result.item.task, Array.from(result.positions))
task: highlightFzfMatch(result.item.task, Array.from(result.positions)),
}))
}
// First apply search if needed
const searchResults = searchQuery ? results : presentableTasks;
const searchResults = searchQuery ? results : presentableTasks
// Then sort the results
return [...searchResults].sort((a, b) => {
switch (sortOption) {
case "oldest":
return (a.ts || 0) - (b.ts || 0);
return (a.ts || 0) - (b.ts || 0)
case "mostExpensive":
return (b.totalCost || 0) - (a.totalCost || 0);
return (b.totalCost || 0) - (a.totalCost || 0)
case "mostTokens":
const aTokens = (a.tokensIn || 0) + (a.tokensOut || 0) + (a.cacheWrites || 0) + (a.cacheReads || 0);
const bTokens = (b.tokensIn || 0) + (b.tokensOut || 0) + (b.cacheWrites || 0) + (b.cacheReads || 0);
return bTokens - aTokens;
const aTokens = (a.tokensIn || 0) + (a.tokensOut || 0) + (a.cacheWrites || 0) + (a.cacheReads || 0)
const bTokens = (b.tokensIn || 0) + (b.tokensOut || 0) + (b.cacheWrites || 0) + (b.cacheReads || 0)
return bTokens - aTokens
case "mostRelevant":
// Keep fuse order if searching, otherwise sort by newest
return searchQuery ? 0 : (b.ts || 0) - (a.ts || 0);
return searchQuery ? 0 : (b.ts || 0) - (a.ts || 0)
case "newest":
default:
return (b.ts || 0) - (a.ts || 0);
return (b.ts || 0) - (a.ts || 0)
}
});
})
}, [presentableTasks, searchQuery, fzf, sortOption])
return (
@@ -144,11 +144,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
}
`}
</style>
{showCopyModal && (
<div className="copy-modal">
Prompt Copied to Clipboard
</div>
)}
{showCopyModal && <div className="copy-modal">Prompt Copied to Clipboard</div>}
<div
style={{
position: "fixed",
@@ -231,7 +227,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
components={{
List: React.forwardRef((props, ref) => (
<div {...props} ref={ref} data-testid="virtuoso-item-list" />
))
)),
}}
itemContent={(index, item) => (
<div
@@ -271,21 +267,21 @@ const HistoryView = ({ onDone }: HistoryViewProps) => {
</span>
<div style={{ display: "flex", gap: "4px" }}>
<button
title="Copy Prompt"
className="copy-button"
data-appearance="icon"
onClick={(e) => handleCopyTask(e, item.task)}>
<span className="codicon codicon-copy"></span>
title="Copy Prompt"
className="copy-button"
data-appearance="icon"
onClick={(e) => handleCopyTask(e, item.task)}>
<span className="codicon codicon-copy"></span>
</button>
<button
title="Delete Task"
className="delete-button"
data-appearance="icon"
onClick={(e) => {
e.stopPropagation()
handleDeleteHistoryItem(item.id)
}}>
<span className="codicon codicon-trash"></span>
title="Delete Task"
className="delete-button"
data-appearance="icon"
onClick={(e) => {
e.stopPropagation()
handleDeleteHistoryItem(item.id)
}}>
<span className="codicon codicon-trash"></span>
</button>
</div>
</div>

View File

@@ -1,232 +1,235 @@
import React from 'react'
import { render, screen, fireEvent, within, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import HistoryView from '../HistoryView'
import { useExtensionState } from '../../../context/ExtensionStateContext'
import { vscode } from '../../../utils/vscode'
import React from "react"
import { render, screen, fireEvent, within, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import HistoryView from "../HistoryView"
import { useExtensionState } from "../../../context/ExtensionStateContext"
import { vscode } from "../../../utils/vscode"
// Mock dependencies
jest.mock('../../../context/ExtensionStateContext')
jest.mock('../../../utils/vscode')
jest.mock('react-virtuoso', () => ({
Virtuoso: ({ data, itemContent }: any) => (
<div data-testid="virtuoso-container">
{data.map((item: any, index: number) => (
<div key={item.id} data-testid={`virtuoso-item-${item.id}`}>
{itemContent(index, item)}
</div>
))}
</div>
),
jest.mock("../../../context/ExtensionStateContext")
jest.mock("../../../utils/vscode")
jest.mock("react-virtuoso", () => ({
Virtuoso: ({ data, itemContent }: any) => (
<div data-testid="virtuoso-container">
{data.map((item: any, index: number) => (
<div key={item.id} data-testid={`virtuoso-item-${item.id}`}>
{itemContent(index, item)}
</div>
))}
</div>
),
}))
const mockTaskHistory = [
{
id: '1',
task: 'Test task 1',
ts: new Date('2022-02-16T00:00:00').getTime(),
tokensIn: 100,
tokensOut: 50,
totalCost: 0.002,
},
{
id: '2',
task: 'Test task 2',
ts: new Date('2022-02-17T00:00:00').getTime(),
tokensIn: 200,
tokensOut: 100,
cacheWrites: 50,
cacheReads: 25,
},
{
id: "1",
task: "Test task 1",
ts: new Date("2022-02-16T00:00:00").getTime(),
tokensIn: 100,
tokensOut: 50,
totalCost: 0.002,
},
{
id: "2",
task: "Test task 2",
ts: new Date("2022-02-17T00:00:00").getTime(),
tokensIn: 200,
tokensOut: 100,
cacheWrites: 50,
cacheReads: 25,
},
]
describe('HistoryView', () => {
beforeEach(() => {
// Reset all mocks before each test
jest.clearAllMocks()
jest.useFakeTimers()
// Mock useExtensionState implementation
;(useExtensionState as jest.Mock).mockReturnValue({
taskHistory: mockTaskHistory,
})
})
describe("HistoryView", () => {
beforeEach(() => {
// Reset all mocks before each test
jest.clearAllMocks()
jest.useFakeTimers()
afterEach(() => {
jest.useRealTimers()
})
// Mock useExtensionState implementation
;(useExtensionState as jest.Mock).mockReturnValue({
taskHistory: mockTaskHistory,
})
})
it('renders history items correctly', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
afterEach(() => {
jest.useRealTimers()
})
// Check if both tasks are rendered
expect(screen.getByTestId('virtuoso-item-1')).toBeInTheDocument()
expect(screen.getByTestId('virtuoso-item-2')).toBeInTheDocument()
expect(screen.getByText('Test task 1')).toBeInTheDocument()
expect(screen.getByText('Test task 2')).toBeInTheDocument()
})
it("renders history items correctly", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
it('handles search functionality', async () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Check if both tasks are rendered
expect(screen.getByTestId("virtuoso-item-1")).toBeInTheDocument()
expect(screen.getByTestId("virtuoso-item-2")).toBeInTheDocument()
expect(screen.getByText("Test task 1")).toBeInTheDocument()
expect(screen.getByText("Test task 2")).toBeInTheDocument()
})
// Get search input and radio group
const searchInput = screen.getByPlaceholderText('Fuzzy search history...')
const radioGroup = screen.getByRole('radiogroup')
// Type in search
await userEvent.type(searchInput, 'task 1')
it("handles search functionality", async () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Check if sort option automatically changes to "Most Relevant"
const mostRelevantRadio = within(radioGroup).getByLabelText('Most Relevant')
expect(mostRelevantRadio).not.toBeDisabled()
// Click and wait for radio update
fireEvent.click(mostRelevantRadio)
// Get search input and radio group
const searchInput = screen.getByPlaceholderText("Fuzzy search history...")
const radioGroup = screen.getByRole("radiogroup")
// Wait for radio button to be checked
const updatedRadio = await within(radioGroup).findByRole('radio', { name: 'Most Relevant', checked: true })
expect(updatedRadio).toBeInTheDocument()
})
// Type in search
await userEvent.type(searchInput, "task 1")
it('handles sort options correctly', async () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Check if sort option automatically changes to "Most Relevant"
const mostRelevantRadio = within(radioGroup).getByLabelText("Most Relevant")
expect(mostRelevantRadio).not.toBeDisabled()
const radioGroup = screen.getByRole('radiogroup')
// Click and wait for radio update
fireEvent.click(mostRelevantRadio)
// Test changing sort options
const oldestRadio = within(radioGroup).getByLabelText('Oldest')
fireEvent.click(oldestRadio)
// Wait for oldest radio to be checked
const checkedOldestRadio = await within(radioGroup).findByRole('radio', { name: 'Oldest', checked: true })
expect(checkedOldestRadio).toBeInTheDocument()
// Wait for radio button to be checked
const updatedRadio = await within(radioGroup).findByRole("radio", { name: "Most Relevant", checked: true })
expect(updatedRadio).toBeInTheDocument()
})
const mostExpensiveRadio = within(radioGroup).getByLabelText('Most Expensive')
fireEvent.click(mostExpensiveRadio)
// Wait for most expensive radio to be checked
const checkedExpensiveRadio = await within(radioGroup).findByRole('radio', { name: 'Most Expensive', checked: true })
expect(checkedExpensiveRadio).toBeInTheDocument()
})
it("handles sort options correctly", async () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
it('handles task selection', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
const radioGroup = screen.getByRole("radiogroup")
// Click on first task
fireEvent.click(screen.getByText('Test task 1'))
// Test changing sort options
const oldestRadio = within(radioGroup).getByLabelText("Oldest")
fireEvent.click(oldestRadio)
// Verify vscode message was sent
expect(vscode.postMessage).toHaveBeenCalledWith({
type: 'showTaskWithId',
text: '1',
})
})
// Wait for oldest radio to be checked
const checkedOldestRadio = await within(radioGroup).findByRole("radio", { name: "Oldest", checked: true })
expect(checkedOldestRadio).toBeInTheDocument()
it('handles task deletion', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
const mostExpensiveRadio = within(radioGroup).getByLabelText("Most Expensive")
fireEvent.click(mostExpensiveRadio)
// Find and hover over first task
const taskContainer = screen.getByTestId('virtuoso-item-1')
fireEvent.mouseEnter(taskContainer)
const deleteButton = within(taskContainer).getByTitle('Delete Task')
fireEvent.click(deleteButton)
// Wait for most expensive radio to be checked
const checkedExpensiveRadio = await within(radioGroup).findByRole("radio", {
name: "Most Expensive",
checked: true,
})
expect(checkedExpensiveRadio).toBeInTheDocument()
})
// Verify vscode message was sent
expect(vscode.postMessage).toHaveBeenCalledWith({
type: 'deleteTaskWithId',
text: '1',
})
})
it("handles task selection", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
it('handles task copying', async () => {
const mockClipboard = {
writeText: jest.fn().mockResolvedValue(undefined),
}
Object.assign(navigator, { clipboard: mockClipboard })
// Click on first task
fireEvent.click(screen.getByText("Test task 1"))
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Verify vscode message was sent
expect(vscode.postMessage).toHaveBeenCalledWith({
type: "showTaskWithId",
text: "1",
})
})
// Find and hover over first task
const taskContainer = screen.getByTestId('virtuoso-item-1')
fireEvent.mouseEnter(taskContainer)
const copyButton = within(taskContainer).getByTitle('Copy Prompt')
await userEvent.click(copyButton)
it("handles task deletion", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Verify clipboard API was called
expect(navigator.clipboard.writeText).toHaveBeenCalledWith('Test task 1')
// Wait for copy modal to appear
const copyModal = await screen.findByText('Prompt Copied to Clipboard')
expect(copyModal).toBeInTheDocument()
// Find and hover over first task
const taskContainer = screen.getByTestId("virtuoso-item-1")
fireEvent.mouseEnter(taskContainer)
// Fast-forward timers and wait for modal to disappear
jest.advanceTimersByTime(2000)
await waitFor(() => {
expect(screen.queryByText('Prompt Copied to Clipboard')).not.toBeInTheDocument()
})
})
const deleteButton = within(taskContainer).getByTitle("Delete Task")
fireEvent.click(deleteButton)
it('formats dates correctly', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Verify vscode message was sent
expect(vscode.postMessage).toHaveBeenCalledWith({
type: "deleteTaskWithId",
text: "1",
})
})
// Find first task container and check date format
const taskContainer = screen.getByTestId('virtuoso-item-1')
const dateElement = within(taskContainer).getByText((content) => {
return content.includes('FEBRUARY 16') && content.includes('12:00 AM')
})
expect(dateElement).toBeInTheDocument()
})
it("handles task copying", async () => {
const mockClipboard = {
writeText: jest.fn().mockResolvedValue(undefined),
}
Object.assign(navigator, { clipboard: mockClipboard })
it('displays token counts correctly', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Find first task container
const taskContainer = screen.getByTestId('virtuoso-item-1')
// Find and hover over first task
const taskContainer = screen.getByTestId("virtuoso-item-1")
fireEvent.mouseEnter(taskContainer)
// Find token counts within the task container
const tokensContainer = within(taskContainer).getByTestId('tokens-container')
expect(within(tokensContainer).getByTestId('tokens-in')).toHaveTextContent('100')
expect(within(tokensContainer).getByTestId('tokens-out')).toHaveTextContent('50')
})
const copyButton = within(taskContainer).getByTitle("Copy Prompt")
await userEvent.click(copyButton)
it('displays cache information when available', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Verify clipboard API was called
expect(navigator.clipboard.writeText).toHaveBeenCalledWith("Test task 1")
// Find second task container
const taskContainer = screen.getByTestId('virtuoso-item-2')
// Wait for copy modal to appear
const copyModal = await screen.findByText("Prompt Copied to Clipboard")
expect(copyModal).toBeInTheDocument()
// Find cache info within the task container
const cacheContainer = within(taskContainer).getByTestId('cache-container')
expect(within(cacheContainer).getByTestId('cache-writes')).toHaveTextContent('+50')
expect(within(cacheContainer).getByTestId('cache-reads')).toHaveTextContent('25')
})
// Fast-forward timers and wait for modal to disappear
jest.advanceTimersByTime(2000)
await waitFor(() => {
expect(screen.queryByText("Prompt Copied to Clipboard")).not.toBeInTheDocument()
})
})
it('handles export functionality', () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
it("formats dates correctly", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Find and hover over second task
const taskContainer = screen.getByTestId('virtuoso-item-2')
fireEvent.mouseEnter(taskContainer)
const exportButton = within(taskContainer).getByText('EXPORT')
fireEvent.click(exportButton)
// Find first task container and check date format
const taskContainer = screen.getByTestId("virtuoso-item-1")
const dateElement = within(taskContainer).getByText((content) => {
return content.includes("FEBRUARY 16") && content.includes("12:00 AM")
})
expect(dateElement).toBeInTheDocument()
})
// Verify vscode message was sent
expect(vscode.postMessage).toHaveBeenCalledWith({
type: 'exportTaskWithId',
text: '2',
})
})
})
it("displays token counts correctly", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Find first task container
const taskContainer = screen.getByTestId("virtuoso-item-1")
// Find token counts within the task container
const tokensContainer = within(taskContainer).getByTestId("tokens-container")
expect(within(tokensContainer).getByTestId("tokens-in")).toHaveTextContent("100")
expect(within(tokensContainer).getByTestId("tokens-out")).toHaveTextContent("50")
})
it("displays cache information when available", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Find second task container
const taskContainer = screen.getByTestId("virtuoso-item-2")
// Find cache info within the task container
const cacheContainer = within(taskContainer).getByTestId("cache-container")
expect(within(cacheContainer).getByTestId("cache-writes")).toHaveTextContent("+50")
expect(within(cacheContainer).getByTestId("cache-reads")).toHaveTextContent("25")
})
it("handles export functionality", () => {
const onDone = jest.fn()
render(<HistoryView onDone={onDone} />)
// Find and hover over second task
const taskContainer = screen.getByTestId("virtuoso-item-2")
fireEvent.mouseEnter(taskContainer)
const exportButton = within(taskContainer).getByText("EXPORT")
fireEvent.click(exportButton)
// Verify vscode message was sent
expect(vscode.postMessage).toHaveBeenCalledWith({
type: "exportTaskWithId",
text: "2",
})
})
})