Files
NetMesh/application/state/usePluginTerminalProviders.test.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

115 lines
4.6 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import fs from 'node:fs';
import type { TerminalTheme } from '../../domain/models.ts';
import {
applyCurrentProviderResponse,
isPluginTerminalProviderRefreshCurrent,
mergePluginTerminalThemeColors,
resolvePluginTerminalTheme,
waitForProviderResponse,
} from './usePluginTerminalProviders.ts';
const baseTheme = {
id: 'base',
name: 'Base',
type: 'dark',
colors: {
background: '#000000', foreground: '#ffffff', cursor: '#ffffff', selection: '#333333',
black: '#000000', red: '#ff0000', green: '#00ff00', yellow: '#ffff00', blue: '#0000ff',
magenta: '#ff00ff', cyan: '#00ffff', white: '#ffffff', brightBlack: '#777777',
brightRed: '#ff7777', brightGreen: '#77ff77', brightYellow: '#ffff77', brightBlue: '#7777ff',
brightMagenta: '#ff77ff', brightCyan: '#77ffff', brightWhite: '#ffffff',
},
} as const satisfies TerminalTheme;
test('terminal theme Providers merge deterministically over the host theme', () => {
const merged = mergePluginTerminalThemeColors([
{ background: '#102030', cursor: '#abcdef' },
{ background: '#ffffff', foreground: '#f0f0f0' },
]);
assert.deepEqual(merged, {
background: '#102030',
cursor: '#abcdef',
foreground: '#f0f0f0',
});
assert.deepEqual(resolvePluginTerminalTheme(baseTheme, merged).colors, {
...baseTheme.colors,
...merged,
});
assert.equal(resolvePluginTerminalTheme(baseTheme, {}).id, baseTheme.id);
});
test('terminal components delegate Provider state to the application hook', () => {
const terminal = fs.readFileSync(new URL('../../components/Terminal.tsx', import.meta.url), 'utf8');
const effects = fs.readFileSync(new URL('../../components/terminal/useTerminalEffects.ts', import.meta.url), 'utf8');
assert.match(terminal, /usePluginTerminalProviders\(/);
assert.doesNotMatch(terminal, /getWindowPluginTerminalProviderRegistry|PluginTerminalProviderAvailability/);
assert.doesNotMatch(effects, /getWindowPluginTerminalProviderRegistry|PluginTerminalProviderAvailability/);
});
test('application-owned Provider timeout aborts and returns a stale response', async () => {
const controller = new AbortController();
const result = await waitForProviderResponse(new Promise(() => {}), controller, 1);
assert.equal(controller.signal.aborted, true);
assert.deepEqual(result, { requestId: '', stale: true, results: [] });
});
test('a deferred Provider response cannot update state after the live session disconnects', async () => {
let resolveResponse!: (value: { requestId: string; stale: boolean; results: [] }) => void;
const response = new Promise<{ requestId: string; stale: boolean; results: [] }>((resolve) => {
resolveResponse = resolve;
});
const initial = {
sessionId: 'session-a',
hostId: 'host-a',
workspaceId: 'workspace-a',
protocol: 'ssh',
status: 'connected',
shellType: 'posix',
baseTheme,
} as const;
let current = { ...initial } as Parameters<typeof isPluginTerminalProviderRefreshCurrent>[1];
let applied = false;
const pending = applyCurrentProviderResponse(
response,
() => isPluginTerminalProviderRefreshCurrent(initial, current),
() => { applied = true; },
() => { applied = true; },
);
current = { ...current, status: 'disconnected' };
resolveResponse({ requestId: 'late', stale: false, results: [] });
await pending;
assert.equal(applied, false);
});
test('session identity and shell discovery invalidate Provider output metadata', () => {
const initial = {
sessionId: 'session-a',
hostId: 'host-a',
workspaceId: 'workspace-a',
protocol: 'ssh',
status: 'connected',
shellType: undefined,
baseTheme,
} as const;
assert.equal(isPluginTerminalProviderRefreshCurrent(initial, { ...initial, shellType: 'posix' }), false);
assert.equal(isPluginTerminalProviderRefreshCurrent(initial, { ...initial, sessionId: 'session-b' }), false);
assert.equal(isPluginTerminalProviderRefreshCurrent(initial, { ...initial, hostId: 'host-b' }), false);
assert.equal(isPluginTerminalProviderRefreshCurrent(initial, { ...initial, workspaceId: 'workspace-b' }), false);
assert.equal(isPluginTerminalProviderRefreshCurrent(initial, { ...initial, protocol: 'telnet' }), false);
assert.equal(isPluginTerminalProviderRefreshCurrent(initial, initial), true);
});
test('a current stale Provider response clears the previous output', async () => {
let cleared = false;
await applyCurrentProviderResponse(
Promise.resolve({ requestId: 'timeout', stale: true, results: [] }),
() => true,
() => assert.fail('stale response must not be applied'),
() => { cleared = true; },
);
assert.equal(cleared, true);
});