generated from nhcarrigan/template
fa906684c2
## Summary - **fix**: `show_thinking_blocks` setting now persists across sessions — it was defined on the TypeScript side but missing from the Rust `HikariConfig` struct, so serde silently dropped it on every save/load - **feat**: Tool calls are now rendered as collapsible blocks matching the Extended Thinking block aesthetic, replacing the old inline dropdown approach - **feat**: Add configurable max output tokens setting - **feat**: Use random creative names for conversation tabs - **test**: Significantly expanded frontend unit test coverage - **docs**: Require tests for all changes in CLAUDE.md - **feat**: Allow users to specify a custom terminal font (Closes #176) - **feat**: Display friendly names for memory files derived from the first heading (Closes #177) - **feat**: Add custom UI font support for the app chrome (buttons, labels, tabs) - **fix**: Apply custom UI font to the full app interface — `.app-container` was hardcoded, blocking inheritance from `body`; also renamed "Custom Font" to "Custom Terminal Font" for clarity ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #175 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
99 lines
3.0 KiB
TypeScript
99 lines
3.0 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
|
|
// Mirror pure logic functions from MemoryBrowserPanel.svelte
|
|
|
|
interface MemoryFileInfo {
|
|
path: string;
|
|
heading: string | null;
|
|
}
|
|
|
|
function getFileName(path: string): string {
|
|
return path.split("/").pop() || path;
|
|
}
|
|
|
|
function getDisplayName(file: MemoryFileInfo): string {
|
|
return file.heading ?? getFileName(file.path);
|
|
}
|
|
|
|
describe("getFileName", () => {
|
|
it("extracts the filename from an absolute Unix path", () => {
|
|
expect(getFileName("/home/naomi/.claude/projects/foo/memory/MEMORY.md")).toBe("MEMORY.md");
|
|
});
|
|
|
|
it("extracts the filename from a nested path", () => {
|
|
expect(getFileName("/home/naomi/.claude/projects/foo/memory/debugging.md")).toBe(
|
|
"debugging.md"
|
|
);
|
|
});
|
|
|
|
it("returns the path itself when there is no slash", () => {
|
|
expect(getFileName("MEMORY.md")).toBe("MEMORY.md");
|
|
});
|
|
|
|
it("returns the path when the path ends with a slash (empty filename)", () => {
|
|
// split('/').pop() returns '' for trailing slash → falls back to full path
|
|
expect(getFileName("/some/dir/")).toBe("/some/dir/");
|
|
});
|
|
|
|
it("handles single-component paths", () => {
|
|
expect(getFileName("notes.md")).toBe("notes.md");
|
|
});
|
|
|
|
it("handles Windows-style paths passed as Unix strings", () => {
|
|
// If the path contains no forward slashes, the whole string is the filename
|
|
expect(getFileName("C:\\Users\\naomi\\memory\\file.md")).toBe(
|
|
"C:\\Users\\naomi\\memory\\file.md"
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("getDisplayName", () => {
|
|
it("returns the heading when the file has one", () => {
|
|
const file: MemoryFileInfo = {
|
|
path: "/home/naomi/.claude/projects/foo/memory/MEMORY.md",
|
|
heading: "Hikari Desktop - Memory",
|
|
};
|
|
expect(getDisplayName(file)).toBe("Hikari Desktop - Memory");
|
|
});
|
|
|
|
it("falls back to the filename when heading is null", () => {
|
|
const file: MemoryFileInfo = {
|
|
path: "/home/naomi/.claude/projects/foo/memory/debugging.md",
|
|
heading: null,
|
|
};
|
|
expect(getDisplayName(file)).toBe("debugging.md");
|
|
});
|
|
|
|
it("falls back to the filename when heading is an empty string stored as null", () => {
|
|
const file: MemoryFileInfo = {
|
|
path: "/home/naomi/.claude/projects/foo/memory/patterns.md",
|
|
heading: null,
|
|
};
|
|
expect(getDisplayName(file)).toBe("patterns.md");
|
|
});
|
|
|
|
it("returns the heading even when it matches the filename", () => {
|
|
const file: MemoryFileInfo = {
|
|
path: "/home/naomi/.claude/projects/foo/memory/MEMORY.md",
|
|
heading: "MEMORY",
|
|
};
|
|
expect(getDisplayName(file)).toBe("MEMORY");
|
|
});
|
|
|
|
it("returns a multi-word heading verbatim", () => {
|
|
const file: MemoryFileInfo = {
|
|
path: "/some/path/foo.md",
|
|
heading: "My Detailed Debugging Notes",
|
|
};
|
|
expect(getDisplayName(file)).toBe("My Detailed Debugging Notes");
|
|
});
|
|
|
|
it("falls back gracefully when path has no directory separators", () => {
|
|
const file: MemoryFileInfo = {
|
|
path: "lonely-file.md",
|
|
heading: null,
|
|
};
|
|
expect(getDisplayName(file)).toBe("lonely-file.md");
|
|
});
|
|
});
|