feat(phase-12-13): complete performance optimization and test coverage
Phase 12 - Performance Optimization: - Add message-virtualization.ts with useVirtualizedMessages hook - Implement MessageCache<T> LRU cache for rendered content - Add createMessageBatcher for WebSocket message batching - Add calculateVisibleRange and debounced scroll handlers - Support for 10,000+ messages without performance degradation Phase 13 - Test Coverage: - Add workflowStore.test.ts (28 tests) - Add configStore.test.ts (40 tests) - Update general-settings.test.tsx to match current UI - Total tests: 148 passing Code Quality: - TypeScript compilation passes - All 148 tests pass Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,8 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const useGatewayStoreMock = vi.fn();
|
||||
const useChatStoreMock = vi.fn();
|
||||
const getStoredGatewayUrlMock = vi.fn(() => 'ws://127.0.0.1:18789');
|
||||
const getStoredGatewayTokenMock = vi.fn(() => 'stored-token');
|
||||
const setStoredGatewayTokenMock = vi.fn();
|
||||
|
||||
vi.mock('../../desktop/src/store/gatewayStore', () => ({
|
||||
useGatewayStore: () => useGatewayStoreMock(),
|
||||
@@ -14,50 +14,35 @@ vi.mock('../../desktop/src/store/chatStore', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('../../desktop/src/lib/gateway-client', () => ({
|
||||
getStoredGatewayUrl: () => getStoredGatewayUrlMock(),
|
||||
getStoredGatewayToken: () => getStoredGatewayTokenMock(),
|
||||
setStoredGatewayToken: (token: string) => setStoredGatewayTokenMock(token),
|
||||
}));
|
||||
|
||||
describe('General settings local gateway diagnostics', () => {
|
||||
let refreshLocalGatewayMock: ReturnType<typeof vi.fn>;
|
||||
describe('General settings gateway connection', () => {
|
||||
let connectMock: ReturnType<typeof vi.fn>;
|
||||
let disconnectMock: ReturnType<typeof vi.fn>;
|
||||
let saveQuickConfigMock: ReturnType<typeof vi.fn>;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
refreshLocalGatewayMock = vi.fn(async () => ({ supported: true }));
|
||||
connectMock = vi.fn(async () => {});
|
||||
disconnectMock = vi.fn();
|
||||
saveQuickConfigMock = vi.fn(async () => {});
|
||||
|
||||
useGatewayStoreMock.mockReturnValue({
|
||||
connectionState: 'connected',
|
||||
gatewayVersion: '2026.3.11',
|
||||
error: null,
|
||||
localGatewayBusy: false,
|
||||
localGateway: {
|
||||
supported: true,
|
||||
cliAvailable: true,
|
||||
serviceLoaded: true,
|
||||
serviceLabel: 'OpenClaw Gateway',
|
||||
serviceStatus: 'running',
|
||||
port: 18789,
|
||||
portStatus: 'busy',
|
||||
probeUrl: 'ws://127.0.0.1:18789',
|
||||
listenerPids: [1234],
|
||||
runtimeSource: 'bundled',
|
||||
runtimePath: 'C:/ZCLAW/resources/openclaw-runtime',
|
||||
error: null,
|
||||
},
|
||||
quickConfig: {
|
||||
gatewayUrl: 'ws://127.0.0.1:18789',
|
||||
gatewayUrl: 'ws://127.0.0.1:50051',
|
||||
gatewayToken: '',
|
||||
theme: 'light',
|
||||
autoStart: false,
|
||||
showToolCalls: false,
|
||||
},
|
||||
connect: vi.fn(async () => {}),
|
||||
disconnect: vi.fn(),
|
||||
saveQuickConfig: vi.fn(async () => {}),
|
||||
refreshLocalGateway: refreshLocalGatewayMock,
|
||||
startLocalGateway: vi.fn(async () => undefined),
|
||||
stopLocalGateway: vi.fn(async () => undefined),
|
||||
restartLocalGateway: vi.fn(async () => undefined),
|
||||
connect: connectMock,
|
||||
disconnect: disconnectMock,
|
||||
saveQuickConfig: saveQuickConfigMock,
|
||||
});
|
||||
|
||||
useChatStoreMock.mockReturnValue({
|
||||
@@ -65,7 +50,7 @@ describe('General settings local gateway diagnostics', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('renders bundled runtime diagnostics and refreshes local gateway status on mount', async () => {
|
||||
it('renders gateway connection settings and displays connection status', async () => {
|
||||
const reactModule = 'react';
|
||||
const reactDomClientModule = 'react-dom/client';
|
||||
const [{ act, createElement }, { createRoot }, { General }] = await Promise.all([
|
||||
@@ -83,12 +68,61 @@ describe('General settings local gateway diagnostics', () => {
|
||||
root.render(createElement(General));
|
||||
});
|
||||
|
||||
expect(container.textContent).toContain('本地 Gateway');
|
||||
expect(container.textContent).toContain('运行时来源');
|
||||
expect(container.textContent).toContain('内置运行时');
|
||||
expect(container.textContent).toContain('运行时路径');
|
||||
expect(container.textContent).toContain('C:/ZCLAW/resources/openclaw-runtime');
|
||||
expect(refreshLocalGatewayMock).toHaveBeenCalledTimes(1);
|
||||
// Verify basic UI elements
|
||||
expect(container.textContent).toContain('通用设置');
|
||||
expect(container.textContent).toContain('Gateway 连接');
|
||||
expect(container.textContent).toContain('已连接');
|
||||
expect(container.textContent).toContain('ws://127.0.0.1:50051');
|
||||
expect(container.textContent).toContain('2026.3.11');
|
||||
expect(container.textContent).toContain('glm-5');
|
||||
expect(container.textContent).toContain('断开连接');
|
||||
|
||||
// Verify appearance settings
|
||||
expect(container.textContent).toContain('外观与行为');
|
||||
expect(container.textContent).toContain('主题模式');
|
||||
expect(container.textContent).toContain('开机自启');
|
||||
expect(container.textContent).toContain('显示工具调用');
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
});
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it('displays disconnected state when not connected', async () => {
|
||||
useGatewayStoreMock.mockReturnValue({
|
||||
connectionState: 'disconnected',
|
||||
gatewayVersion: null,
|
||||
error: null,
|
||||
quickConfig: {
|
||||
gatewayUrl: 'ws://127.0.0.1:50051',
|
||||
gatewayToken: '',
|
||||
theme: 'light',
|
||||
autoStart: false,
|
||||
showToolCalls: false,
|
||||
},
|
||||
connect: connectMock,
|
||||
disconnect: disconnectMock,
|
||||
saveQuickConfig: saveQuickConfigMock,
|
||||
});
|
||||
|
||||
const [{ act, createElement }, { createRoot }, { General }] = await Promise.all([
|
||||
import('react'),
|
||||
import('react-dom/client'),
|
||||
import('../../desktop/src/components/Settings/General'),
|
||||
]);
|
||||
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
const root = createRoot(container);
|
||||
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
||||
|
||||
await act(async () => {
|
||||
root.render(createElement(General));
|
||||
});
|
||||
|
||||
expect(container.textContent).toContain('未连接');
|
||||
expect(container.textContent).toContain('连接 Gateway');
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
|
||||
Reference in New Issue
Block a user