[Init] Initial commit - NetMesh terminal manager
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
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
This commit is contained in:
128
application/state/usePluginTerminalSessionLifecycle.test.ts
Normal file
128
application/state/usePluginTerminalSessionLifecycle.test.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import {
|
||||
beginPluginTerminalSessionMountLifecycle,
|
||||
normalizePluginTerminalProtocol,
|
||||
ownsPluginTerminalBackendLifecycle,
|
||||
shouldPublishPluginTerminalSessionMountLifecycle,
|
||||
shouldPublishPluginTerminalEvent,
|
||||
transitionPluginTerminalConnectionState,
|
||||
} from './usePluginTerminalSessionLifecycle.ts';
|
||||
|
||||
test('an attached renderer does not claim creation or disposal of the reused backend session', () => {
|
||||
assert.equal(ownsPluginTerminalBackendLifecycle(undefined), true);
|
||||
assert.equal(ownsPluginTerminalBackendLifecycle(true), true);
|
||||
assert.equal(ownsPluginTerminalBackendLifecycle(false), false);
|
||||
for (const type of ['created', 'connected', 'reconnected', 'disconnected', 'disposed'] as const) {
|
||||
assert.equal(shouldPublishPluginTerminalEvent(type, false), false);
|
||||
}
|
||||
assert.equal(shouldPublishPluginTerminalEvent('resized', false), true);
|
||||
});
|
||||
|
||||
const connectedState = {
|
||||
cwd: '/srv/old',
|
||||
title: 'old backend',
|
||||
cols: 120,
|
||||
rows: 40,
|
||||
alternateScreen: true,
|
||||
};
|
||||
|
||||
test('disconnect clears connection-scoped terminal Provider metadata before publishing', () => {
|
||||
assert.deepEqual(
|
||||
transitionPluginTerminalConnectionState(connectedState, 'disconnected', true, 137),
|
||||
{
|
||||
snapshotState: { cols: 120, rows: 40 },
|
||||
everConnected: true,
|
||||
eventType: 'disconnected',
|
||||
eventDetails: { exitCode: 137 },
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('disconnect omits an exit code when the backend did not provide one', () => {
|
||||
assert.deepEqual(
|
||||
transitionPluginTerminalConnectionState(connectedState, 'disconnected', true),
|
||||
{
|
||||
snapshotState: { cols: 120, rows: 40 },
|
||||
everConnected: true,
|
||||
eventType: 'disconnected',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('reconnect clears stale backend metadata while retaining viewport dimensions', () => {
|
||||
assert.deepEqual(
|
||||
transitionPluginTerminalConnectionState(connectedState, 'connected', true),
|
||||
{
|
||||
snapshotState: { cols: 120, rows: 40 },
|
||||
everConnected: true,
|
||||
eventType: 'reconnected',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('the initial connection preserves its initial cwd snapshot', () => {
|
||||
assert.deepEqual(
|
||||
transitionPluginTerminalConnectionState({ cwd: '/srv/initial' }, 'connected', false),
|
||||
{
|
||||
snapshotState: { cwd: '/srv/initial' },
|
||||
everConnected: true,
|
||||
eventType: 'connected',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('a reconnecting transition clears stale metadata before any later disposal', () => {
|
||||
assert.deepEqual(
|
||||
transitionPluginTerminalConnectionState(connectedState, 'connecting', true),
|
||||
{
|
||||
snapshotState: { cols: 120, rows: 40 },
|
||||
everConnected: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('transition snapshots remain writable for later cwd and title updates', () => {
|
||||
const transition = transitionPluginTerminalConnectionState(connectedState, 'connected', true);
|
||||
transition.snapshotState.cwd = '/srv/new';
|
||||
transition.snapshotState.title = 'new backend';
|
||||
|
||||
assert.deepEqual(transition.snapshotState, {
|
||||
cols: 120,
|
||||
rows: 40,
|
||||
cwd: '/srv/new',
|
||||
title: 'new backend',
|
||||
});
|
||||
});
|
||||
|
||||
test('terminal lifecycle snapshots preserve dynamic protocol identifiers', () => {
|
||||
assert.equal(
|
||||
normalizePluginTerminalProtocol('com.example.transport'),
|
||||
'com.example.transport',
|
||||
);
|
||||
assert.equal(normalizePluginTerminalProtocol('mosh'), 'mosh');
|
||||
assert.equal(normalizePluginTerminalProtocol(undefined), 'ssh');
|
||||
});
|
||||
|
||||
test('an attach popup does not publish backend session mount or disposal lifecycle', () => {
|
||||
assert.equal(shouldPublishPluginTerminalSessionMountLifecycle(true), false);
|
||||
assert.equal(shouldPublishPluginTerminalSessionMountLifecycle(false), true);
|
||||
|
||||
const events: string[] = [];
|
||||
const cleanup = beginPluginTerminalSessionMountLifecycle(
|
||||
shouldPublishPluginTerminalSessionMountLifecycle(true),
|
||||
() => events.push('created'),
|
||||
() => events.push('disposed'),
|
||||
);
|
||||
cleanup?.();
|
||||
assert.deepEqual(events, []);
|
||||
|
||||
const ownerCleanup = beginPluginTerminalSessionMountLifecycle(
|
||||
shouldPublishPluginTerminalSessionMountLifecycle(false),
|
||||
() => events.push('created'),
|
||||
() => events.push('disposed'),
|
||||
);
|
||||
ownerCleanup?.();
|
||||
assert.deepEqual(events, ['created', 'disposed']);
|
||||
});
|
||||
Reference in New Issue
Block a user