Co-Authored-By: Claude Haiku 4.5 <[email protected]>
64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import { act } from 'react';
|
|
import { createRoot, type Root } from 'react-dom/client';
|
|
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
import { ToolCallList } from './tool-call-list';
|
|
|
|
beforeAll(() => {
|
|
Object.defineProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT', {
|
|
configurable: true,
|
|
value: true,
|
|
});
|
|
});
|
|
|
|
afterAll(() => {
|
|
Reflect.deleteProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT');
|
|
});
|
|
|
|
let root: Root | null;
|
|
let container: HTMLElement | null;
|
|
|
|
async function render(node: Parameters<Root['render']>[0]): Promise<void> {
|
|
container = document.createElement('div');
|
|
document.body.append(container);
|
|
root = createRoot(container);
|
|
await act(async () => {
|
|
root?.render(node);
|
|
});
|
|
}
|
|
|
|
afterEach(async () => {
|
|
await act(async () => {
|
|
root?.unmount();
|
|
});
|
|
document.body.replaceChildren();
|
|
root = null;
|
|
container = null;
|
|
});
|
|
|
|
describe('ToolCallList', () => {
|
|
it('renders two entries independently, without a duplicate-key warning, when a valid toolCallId is shared', async () => {
|
|
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
|
|
await render(
|
|
<ToolCallList
|
|
tools={[
|
|
{ toolCallId: 'dup', toolName: 'search', status: 'success' },
|
|
{ toolCallId: 'dup', toolName: 'search', status: 'running' },
|
|
]}
|
|
/>,
|
|
);
|
|
|
|
const items = [...(container?.querySelectorAll('li') ?? [])];
|
|
expect(items).toHaveLength(2);
|
|
expect(items[0]?.textContent).toContain('success');
|
|
expect(items[1]?.textContent).toContain('running');
|
|
|
|
const duplicateKeyWarning = consoleError.mock.calls.some((args) =>
|
|
args.some((arg) => typeof arg === 'string' && arg.includes('same key')),
|
|
);
|
|
expect(duplicateKeyWarning).toBe(false);
|
|
|
|
consoleError.mockRestore();
|
|
});
|
|
});
|