Skip to content

Commit 29c563a

Browse files
m-mcgowanclaude
andcommitted
test: Add terminal title resolver tests
Tests cover placeholder resolution, segment dropping for empty placeholders, task file reading, string/object model formats, and null return when all segments are empty. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c68184d commit 29c563a

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { mkdirSync, rmSync, writeFileSync } from 'fs';
2+
import { tmpdir } from 'os';
3+
import { join } from 'path';
4+
import {
5+
afterEach,
6+
beforeEach,
7+
describe,
8+
expect,
9+
it,
10+
vi
11+
} from 'vitest';
12+
13+
import type { RenderContext } from '../../types/RenderContext';
14+
15+
// Mock homedir for task file reads
16+
vi.mock('os', async () => {
17+
const actual = await vi.importActual('os');
18+
return {
19+
...actual,
20+
homedir: () => join(tmpdir(), 'ccstatusline-test-home')
21+
};
22+
});
23+
24+
// Mock git commands
25+
vi.mock('../git', () => ({
26+
runGit: (cmd: string) => {
27+
if (cmd === 'branch --show-current') return 'main';
28+
if (cmd === 'rev-parse --show-toplevel') return '/Users/test/my-repo';
29+
return null;
30+
}
31+
}));
32+
33+
// Import after mocks
34+
const { resolveTerminalTitle } = await import('../terminal-title');
35+
36+
function taskDir(): string {
37+
return join(tmpdir(), 'ccstatusline-test-home', '.cache', 'ccstatusline', 'tasks');
38+
}
39+
40+
function writeTask(sessionId: string, data: Record<string, string>): void {
41+
const dir = taskDir();
42+
mkdirSync(dir, { recursive: true });
43+
writeFileSync(join(dir, `claude-task-${sessionId}`), JSON.stringify(data), 'utf8');
44+
}
45+
46+
const baseContext: RenderContext = {
47+
data: {
48+
session_id: 'test-session',
49+
model: { display_name: 'Opus 4.6' },
50+
workspace: { current_dir: '/Users/test/my-repo' }
51+
}
52+
};
53+
54+
describe('resolveTerminalTitle', () => {
55+
beforeEach(() => {
56+
mkdirSync(taskDir(), { recursive: true });
57+
});
58+
59+
afterEach(() => {
60+
try { rmSync(taskDir(), { recursive: true, force: true }); } catch { /* ignore */ }
61+
});
62+
63+
it('resolves repo and branch', () => {
64+
const result = resolveTerminalTitle('{repo}/{branch}', baseContext);
65+
expect(result).toBe('my-repo/main');
66+
});
67+
68+
it('resolves model', () => {
69+
const result = resolveTerminalTitle('{model}', baseContext);
70+
expect(result).toBe('Opus 4.6');
71+
});
72+
73+
it('resolves dir', () => {
74+
const result = resolveTerminalTitle('{dir}', baseContext);
75+
expect(result).toBe('my-repo');
76+
});
77+
78+
it('resolves task from file', () => {
79+
writeTask('test-session', { task: 'Fix auth bug' });
80+
const result = resolveTerminalTitle('{task}', baseContext);
81+
expect(result).toBe('Fix auth bug');
82+
});
83+
84+
it('drops empty segments', () => {
85+
// No task file exists, so {task} is empty
86+
const result = resolveTerminalTitle('{task} | {repo}/{branch}', baseContext);
87+
expect(result).toBe('my-repo/main');
88+
});
89+
90+
it('keeps both segments when task exists', () => {
91+
writeTask('test-session', { task: 'Build API' });
92+
const result = resolveTerminalTitle('{task} | {repo}/{branch}', baseContext);
93+
expect(result).toBe('Build API | my-repo/main');
94+
});
95+
96+
it('returns null when all segments are empty', () => {
97+
const emptyContext: RenderContext = { data: {} };
98+
const result = resolveTerminalTitle('{task}', emptyContext);
99+
expect(result).toBeNull();
100+
});
101+
102+
it('handles string model format', () => {
103+
const ctx: RenderContext = {
104+
data: { model: 'Claude Haiku' }
105+
};
106+
const result = resolveTerminalTitle('{model}', ctx);
107+
expect(result).toBe('Claude Haiku');
108+
});
109+
});

0 commit comments

Comments
 (0)