-
-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathInputBar.test.ts
More file actions
118 lines (98 loc) · 3.73 KB
/
InputBar.test.ts
File metadata and controls
118 lines (98 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { describe, expect, it, beforeEach, afterEach, vi } from "vitest";
import type { SlashCommand } from "@/types";
import {
LOCAL_CLEAR_COMMAND,
getAvailableSlashCommands,
getSlashCommandReplacement,
isClearCommandText,
} from "./InputBar";
// Mock localStorage for Node environment
const localStorageMock = (() => {
let store: Record<string, string> = {};
return {
getItem: (key: string) => store[key] || null,
setItem: (key: string, value: string) => {
store[key] = value.toString();
},
clear: () => {
store = {};
},
};
})();
global.localStorage = localStorageMock as any;
describe("InputBar slash command helpers", () => {
it("always includes the local clear command first", () => {
const commands: SlashCommand[] = [
{ name: "compact", description: "Compact context", source: "claude" },
];
expect(getAvailableSlashCommands(commands)).toEqual([
LOCAL_CLEAR_COMMAND,
commands[0],
]);
});
it("deduplicates engine-provided clear commands in favor of the local one", () => {
const commands: SlashCommand[] = [
{ name: "clear", description: "Engine clear", source: "claude" },
{ name: "help", description: "Help", source: "claude" },
];
expect(getAvailableSlashCommands(commands)).toEqual([
LOCAL_CLEAR_COMMAND,
commands[1],
]);
});
it("detects the exact /clear command text", () => {
expect(isClearCommandText("/clear")).toBe(true);
expect(isClearCommandText(" /clear ")).toBe(true);
expect(isClearCommandText("/clear now")).toBe(false);
expect(isClearCommandText("/compact")).toBe(false);
});
it("builds replacement text for local and engine commands", () => {
expect(getSlashCommandReplacement(LOCAL_CLEAR_COMMAND)).toBe("/clear");
expect(getSlashCommandReplacement({ name: "compact", description: "", source: "claude" })).toBe("/compact ");
expect(getSlashCommandReplacement({ name: "open", description: "", source: "codex-app", appSlug: "jira" })).toBe("$jira ");
expect(
getSlashCommandReplacement({ name: "fix", description: "", source: "codex-skill", defaultPrompt: "bug" }),
).toBe("$fix bug");
});
});
describe("Model favorites localStorage", () => {
beforeEach(() => {
// Clear localStorage before each test
localStorage.clear();
});
afterEach(() => {
localStorage.clear();
});
it("persists favorite models to localStorage", () => {
const favorites = ["claude-opus-4-5", "claude-sonnet-4-5"];
localStorage.setItem("harnss-favorite-models", JSON.stringify(favorites));
const stored = localStorage.getItem("harnss-favorite-models");
expect(stored).toBeTruthy();
expect(JSON.parse(stored!)).toEqual(favorites);
});
it("loads favorite models from localStorage", () => {
const favorites = ["claude-haiku-4"];
localStorage.setItem("harnss-favorite-models", JSON.stringify(favorites));
const stored = localStorage.getItem("harnss-favorite-models");
const parsed = stored ? new Set(JSON.parse(stored)) : new Set();
expect(parsed.has("claude-haiku-4")).toBe(true);
expect(parsed.size).toBe(1);
});
it("handles empty favorites gracefully", () => {
const stored = localStorage.getItem("harnss-favorite-models");
expect(stored).toBeNull();
const parsed = stored ? new Set(JSON.parse(stored)) : new Set();
expect(parsed.size).toBe(0);
});
it("handles corrupted localStorage data", () => {
localStorage.setItem("harnss-favorite-models", "invalid-json{");
let parsed: Set<string>;
try {
const stored = localStorage.getItem("harnss-favorite-models");
parsed = stored ? new Set(JSON.parse(stored)) : new Set();
} catch {
parsed = new Set();
}
expect(parsed.size).toBe(0);
});
});