vicky469_aside/tests/viewState.test.ts
vicky469 d126027923 feat(sidebar): add mode tabs, thread groups, thought trail source
- Extract sidebar mode tabs into sidebarModeTabs.ts
- Extract thread groups into sidebarThreadGroups.ts
- Extract thought trail source into sidebarThoughtTrailSource.ts
- Remove non-working Tags tab and Tags radio button from thought trail
- Remove redundant Related Files h4 heading from thought trail section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 17:19:32 +08:00

158 lines
5.5 KiB
TypeScript

import * as assert from "node:assert/strict";
import test from "node:test";
import {
normalizeIndexSidebarMode,
normalizeSidebarPrimaryMode,
normalizeIndexFileFilterRootPath,
resolvePinnedSidebarStateByFilePathFromState,
resolvePinnedSidebarFilePathFromState,
resolveIndexFileFilterRootPathFromState,
shouldIgnorePinnedSidebarActiveFileUpdate,
} from "../src/ui/views/viewState";
test("normalizeSidebarPrimaryMode accepts the supported sidebar modes only", () => {
assert.equal(normalizeSidebarPrimaryMode("list"), "list");
assert.equal(normalizeSidebarPrimaryMode("tags"), "tags");
assert.equal(normalizeSidebarPrimaryMode("todo"), "todo");
assert.equal(normalizeSidebarPrimaryMode("agent"), "agent");
assert.equal(normalizeSidebarPrimaryMode("thought-trail"), "thought-trail");
assert.equal(normalizeSidebarPrimaryMode("queue"), null);
assert.equal(normalizeSidebarPrimaryMode(undefined), null);
});
test("normalizeIndexSidebarMode accepts index modes", () => {
assert.equal(normalizeIndexSidebarMode("list"), "list");
assert.equal(normalizeIndexSidebarMode("tags"), "tags");
assert.equal(normalizeIndexSidebarMode("todo"), "todo");
assert.equal(normalizeIndexSidebarMode("agent"), "agent");
assert.equal(normalizeIndexSidebarMode("thought-trail"), "thought-trail");
assert.equal(normalizeIndexSidebarMode("queue"), null);
assert.equal(normalizeIndexSidebarMode(undefined), null);
});
test("normalizeIndexFileFilterRootPath normalizes one file path", () => {
assert.equal(
normalizeIndexFileFilterRootPath(" docs\\Folder\\Note.md "),
"docs/Folder/Note.md",
);
assert.equal(normalizeIndexFileFilterRootPath(null), null);
});
test("resolveIndexFileFilterRootPathFromState prefers the explicit root path", () => {
assert.equal(
resolveIndexFileFilterRootPathFromState({
indexFileFilterRootPath: " docs\\a.md ",
indexFileFilterPaths: ["docs/b.md"],
}),
"docs/a.md",
);
});
test("resolveIndexFileFilterRootPathFromState migrates the first legacy file path", () => {
assert.equal(
resolveIndexFileFilterRootPathFromState({
indexFileFilterPaths: [" docs\\b.md ", "docs/a.md"],
}),
"docs/b.md",
);
assert.equal(
resolveIndexFileFilterRootPathFromState({
indexFileFilterPaths: [],
}),
null,
);
});
test("resolveIndexFileFilterRootPathFromState returns undefined when no filter state is present", () => {
assert.equal(
resolveIndexFileFilterRootPathFromState({}),
undefined,
);
});
test("resolvePinnedSidebarStateByFilePathFromState normalizes file paths and thread ids", () => {
assert.deepEqual(
resolvePinnedSidebarStateByFilePathFromState({
pinnedSidebarStateByFilePath: {
" docs\\a.md ": {
threadIds: [" thread-1 ", "thread-1", "", 2],
showPinnedThreadsOnly: true,
},
"": {
threadIds: ["thread-ignored"],
showPinnedThreadsOnly: true,
},
},
} as unknown as Parameters<typeof resolvePinnedSidebarStateByFilePathFromState>[0]),
{
"docs/a.md": {
threadIds: ["thread-1"],
showPinnedThreadsOnly: true,
},
},
);
});
test("resolvePinnedSidebarStateByFilePathFromState keeps pinned-only empty views but drops empty inactive entries", () => {
assert.deepEqual(
resolvePinnedSidebarStateByFilePathFromState({
pinnedSidebarStateByFilePath: {
"docs/a.md": {
threadIds: [],
showPinnedThreadsOnly: true,
},
"docs/b.md": {
threadIds: [],
showPinnedThreadsOnly: false,
},
},
} as unknown as Parameters<typeof resolvePinnedSidebarStateByFilePathFromState>[0]),
{
"docs/a.md": {
threadIds: [],
showPinnedThreadsOnly: true,
},
},
);
});
test("resolvePinnedSidebarStateByFilePathFromState returns undefined when pin state is absent", () => {
assert.equal(
resolvePinnedSidebarStateByFilePathFromState({}),
undefined,
);
});
test("resolvePinnedSidebarFilePathFromState normalizes the pinned sidebar file path", () => {
assert.equal(
resolvePinnedSidebarFilePathFromState({ pinnedSidebarFilePath: " docs\\a.md " }),
"docs/a.md",
);
assert.equal(
resolvePinnedSidebarFilePathFromState({ pinnedSidebarFilePath: "" }),
null,
);
assert.equal(
resolvePinnedSidebarFilePathFromState({ pinnedSidebarFilePath: null }),
null,
);
assert.equal(
resolvePinnedSidebarFilePathFromState({}),
undefined,
);
});
test("shouldIgnorePinnedSidebarActiveFileUpdate freezes the sidebar away from other active files only", () => {
assert.equal(shouldIgnorePinnedSidebarActiveFileUpdate({
pinnedSidebarFilePath: "docs/a.md",
nextFilePath: "docs/b.md",
}), true);
assert.equal(shouldIgnorePinnedSidebarActiveFileUpdate({
pinnedSidebarFilePath: "docs/a.md",
nextFilePath: "docs/a.md",
}), false);
assert.equal(shouldIgnorePinnedSidebarActiveFileUpdate({
pinnedSidebarFilePath: null,
nextFilePath: "docs/b.md",
}), false);
});