[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:
134
domain/toolbarItemLayout.test.ts
Normal file
134
domain/toolbarItemLayout.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import {
|
||||
moveToolbarItem,
|
||||
normalizeToolbarItemLayout,
|
||||
partitionToolbarItems,
|
||||
reorderToolbarItems,
|
||||
resetToolbarItemLayout,
|
||||
setToolbarItemPlacement,
|
||||
type ToolbarItemLayoutDefaults,
|
||||
} from './toolbarItemLayout.ts';
|
||||
|
||||
const defaults: ToolbarItemLayoutDefaults = {
|
||||
order: ['a', 'b', 'c', 'd'],
|
||||
placement: {
|
||||
a: 'show',
|
||||
b: 'show',
|
||||
c: 'collapse',
|
||||
d: 'hide',
|
||||
},
|
||||
lockedIds: ['a'],
|
||||
};
|
||||
|
||||
test('normalize restores defaults for null/invalid values', () => {
|
||||
assert.deepEqual(normalizeToolbarItemLayout(null, defaults), {
|
||||
order: ['a', 'b', 'c', 'd'],
|
||||
placement: { a: 'show', b: 'show', c: 'collapse', d: 'hide' },
|
||||
});
|
||||
assert.deepEqual(normalizeToolbarItemLayout('nope', defaults), resetToolbarItemLayout(defaults));
|
||||
});
|
||||
|
||||
test('normalize accepts legacy order-only arrays', () => {
|
||||
const layout = normalizeToolbarItemLayout(['d', 'a', 'b', 'c'], defaults);
|
||||
assert.deepEqual(layout.order, ['d', 'a', 'b', 'c']);
|
||||
assert.equal(layout.placement.a, 'show');
|
||||
assert.equal(layout.placement.c, 'collapse');
|
||||
assert.equal(layout.placement.d, 'hide');
|
||||
});
|
||||
|
||||
test('normalize appends new default ids and drops unknown ones', () => {
|
||||
const layout = normalizeToolbarItemLayout(
|
||||
{ order: ['c', 'ghost', 'a'], placement: { c: 'show', a: 'collapse' } },
|
||||
defaults,
|
||||
);
|
||||
assert.deepEqual(layout.order, ['c', 'a', 'b', 'd']);
|
||||
assert.equal(layout.placement.a, 'collapse');
|
||||
assert.equal(layout.placement.b, 'show');
|
||||
});
|
||||
|
||||
test('locked ids cannot be hidden', () => {
|
||||
const layout = normalizeToolbarItemLayout(
|
||||
{ order: ['a', 'b', 'c', 'd'], placement: { a: 'hide', b: 'show', c: 'show', d: 'show' } },
|
||||
defaults,
|
||||
);
|
||||
assert.equal(layout.placement.a, 'show');
|
||||
|
||||
const next = setToolbarItemPlacement(layout, 'a', 'hide', defaults);
|
||||
assert.equal(next.placement.a, 'show');
|
||||
});
|
||||
|
||||
test('partition filters by availability and placement', () => {
|
||||
const layout = normalizeToolbarItemLayout(null, defaults);
|
||||
assert.deepEqual(partitionToolbarItems(layout), {
|
||||
shown: ['a', 'b'],
|
||||
collapsed: ['c'],
|
||||
hidden: ['d'],
|
||||
});
|
||||
assert.deepEqual(partitionToolbarItems(layout, ['a', 'c', 'd']), {
|
||||
shown: ['a'],
|
||||
collapsed: ['c'],
|
||||
hidden: ['d'],
|
||||
});
|
||||
});
|
||||
|
||||
test('set placement forces at least one reachable item', () => {
|
||||
const layout = normalizeToolbarItemLayout(
|
||||
{
|
||||
order: ['a', 'b'],
|
||||
placement: { a: 'show', b: 'hide' },
|
||||
},
|
||||
{ order: ['a', 'b'], requireReachable: true },
|
||||
);
|
||||
const next = setToolbarItemPlacement(layout, 'a', 'hide', {
|
||||
order: ['a', 'b'],
|
||||
requireReachable: true,
|
||||
});
|
||||
// a was the only reachable; hide is refused via ensureReachable restoring a
|
||||
assert.equal(next.placement.a, 'show');
|
||||
});
|
||||
|
||||
test('requireReachable ignores unavailable filler ids', () => {
|
||||
const layout = normalizeToolbarItemLayout(
|
||||
{
|
||||
order: ['a', 'b', 'serialOnly'],
|
||||
placement: { a: 'hide', b: 'hide', serialOnly: 'show' },
|
||||
},
|
||||
{
|
||||
order: ['a', 'b', 'serialOnly'],
|
||||
requireReachable: true,
|
||||
},
|
||||
);
|
||||
// serialOnly is still "show" but not available for this session — must restore a/b.
|
||||
const next = setToolbarItemPlacement(
|
||||
layout,
|
||||
'a',
|
||||
'hide',
|
||||
{ order: ['a', 'b', 'serialOnly'], requireReachable: true },
|
||||
['a', 'b'],
|
||||
);
|
||||
assert.equal(next.placement.a === 'show' || next.placement.b === 'show', true);
|
||||
});
|
||||
|
||||
test('move skips unavailable neighbors when availableIds is provided', () => {
|
||||
const layout = normalizeToolbarItemLayout(
|
||||
{
|
||||
order: ['a', 'serialOnly', 'b'],
|
||||
placement: { a: 'show', serialOnly: 'show', b: 'show' },
|
||||
},
|
||||
{ order: ['a', 'serialOnly', 'b'] },
|
||||
);
|
||||
const moved = moveToolbarItem(layout, 'a', 'later', ['a', 'b']);
|
||||
assert.deepEqual(moved.order, ['b', 'serialOnly', 'a']);
|
||||
});
|
||||
|
||||
test('reorder and move preserve placement map', () => {
|
||||
const layout = normalizeToolbarItemLayout(null, defaults);
|
||||
const reordered = reorderToolbarItems(layout, 'c', 'a', 'before');
|
||||
assert.deepEqual(reordered.order, ['c', 'a', 'b', 'd']);
|
||||
assert.equal(reordered.placement.c, 'collapse');
|
||||
|
||||
const moved = moveToolbarItem(layout, 'b', 'later');
|
||||
assert.deepEqual(moved.order, ['a', 'c', 'b', 'd']);
|
||||
});
|
||||
Reference in New Issue
Block a user