basant307/AI_Governance_Project
045
1/**2 * @license3 * Copyright 2025 Google LLC4 * SPDX-License-Identifier: Apache-2.05 */6 7import { describe, it, expect, vi, beforeEach } from 'vitest';8import {9 computeWindowTitle,10 writeTerminalTitle,11 formatSessionWindowTitle,12} from './windowTitle.js';13 14describe('computeWindowTitle', () => {15 let originalEnv: NodeJS.ProcessEnv;16 17 beforeEach(() => {18 originalEnv = process.env;19 vi.stubEnv('CLI_TITLE', undefined);20 });21 22 afterEach(() => {23 process.env = originalEnv;24 });25 26 it('should use default Qwen title when CLI_TITLE is not set', () => {27 const result = computeWindowTitle();28 expect(result).toBe('Qwen - qwen');29 });30 31 it('should use CLI_TITLE environment variable when set', () => {32 vi.stubEnv('CLI_TITLE', 'Custom Title');33 const result = computeWindowTitle();34 expect(result).toBe('Custom Title');35 });36 37 it('should use Qwen prefix with folder name when CLI_TITLE is not set', () => {38 const result = computeWindowTitle('my-project');39 expect(result).toBe('Qwen - my-project');40 });41 42 it('should prefer CLI_TITLE over folder name', () => {43 vi.stubEnv('CLI_TITLE', 'Custom Title');44 const result = computeWindowTitle('my-project');45 expect(result).toBe('Custom Title');46 });47 48 it('should remove C0 control characters from title', () => {49 vi.stubEnv('CLI_TITLE', 'Title\x1b[31m with \x07 control chars');50 const result = computeWindowTitle();51 // The \x1b[31m (ANSI escape sequence) and \x07 (bell character) should be removed52 expect(result).toBe('Title[31m with control chars');53 });54 55 it('should remove C1 control characters from title', () => {56 vi.stubEnv('CLI_TITLE', 'Title\x9C with \x90 C1\x9F control');57 const result = computeWindowTitle();58 expect(result).toBe('Title with C1 control');59 });60 61 it('should fall back to default when folderName is empty string', () => {62 const result = computeWindowTitle('');63 expect(result).toBe('Qwen - qwen');64 });65});66 67describe('writeTerminalTitle', () => {68 beforeEach(() => {69 vi.unstubAllEnvs();70 });71 72 afterEach(() => {73 vi.unstubAllEnvs();74 });75 76 it('should write both common terminal title sequences with 80-char padding', () => {77 // Stub multiplexer env vars to ensure non-multiplexer path is taken78 vi.stubEnv('TMUX', undefined);79 vi.stubEnv('STY', undefined);80 vi.stubEnv('ZELLIJ', undefined);81 vi.stubEnv('DVTM', undefined);82 const write = vi.fn();83 84 writeTerminalTitle(write, 'Fix terminal title');85 86 const padded = 'Fix terminal title'.padEnd(80, ' ');87 expect(write).toHaveBeenCalledWith(88 `\x1b]0;${padded}\x07\x1b]2;${padded}\x07`,89 );90 });91 92 it('should pad short titles to 80 characters', () => {93 vi.stubEnv('TMUX', undefined);94 vi.stubEnv('STY', undefined);95 vi.stubEnv('ZELLIJ', undefined);96 vi.stubEnv('DVTM', undefined);97 const write = vi.fn();98 99 writeTerminalTitle(write, 'qwen');100 101 const padded = 'qwen'.padEnd(80, ' ');102 expect(write).toHaveBeenCalledWith(103 `\x1b]0;${padded}\x07\x1b]2;${padded}\x07`,104 );105 });106 107 it('should only write OSC 2 inside tmux', () => {108 vi.stubEnv('TMUX', '/tmp/tmux-0/default');109 const write = vi.fn();110 111 writeTerminalTitle(write, 'test');112 113 expect(write).toHaveBeenCalledWith(`\x1b]2;test\x07`);114 });115 116 it('should only write OSC 2 inside screen', () => {117 vi.stubEnv('STY', '12345.pts-0.host');118 const write = vi.fn();119 120 writeTerminalTitle(write, 'test');121 122 expect(write).toHaveBeenCalledWith(`\x1b]2;test\x07`);123 });124 125 it('should only write OSC 2 inside Zellij', () => {126 vi.stubEnv('ZELLIJ', '1');127 const write = vi.fn();128 129 writeTerminalTitle(write, 'test');130 131 expect(write).toHaveBeenCalledWith(`\x1b]2;test\x07`);132 });133 134 it('should only write OSC 2 inside dvtm', () => {135 vi.stubEnv('DVTM', '1');136 const write = vi.fn();137 138 writeTerminalTitle(write, 'test');139 140 expect(write).toHaveBeenCalledWith(`\x1b]2;test\x07`);141 });142 143 it('should truncate titles longer than 80 characters', () => {144 vi.stubEnv('TMUX', undefined);145 vi.stubEnv('STY', undefined);146 vi.stubEnv('ZELLIJ', undefined);147 vi.stubEnv('DVTM', undefined);148 const write = vi.fn();149 const longTitle = 'A'.repeat(120);150 151 writeTerminalTitle(write, longTitle);152 153 const expected = 'A'.repeat(80);154 expect(write).toHaveBeenCalledWith(155 `\x1b]0;${expected}\x07\x1b]2;${expected}\x07`,156 );157 });158 159 it('should write empty OSC sequences without padding for empty title', () => {160 vi.stubEnv('TMUX', undefined);161 vi.stubEnv('STY', undefined);162 vi.stubEnv('ZELLIJ', undefined);163 vi.stubEnv('DVTM', undefined);164 const write = vi.fn();165 166 writeTerminalTitle(write, '');167 168 expect(write).toHaveBeenCalledWith('\x1b]0;\x07\x1b]2;\x07');169 });170 171 it('should write empty OSC 2 sequence inside tmux for empty title', () => {172 vi.stubEnv('TMUX', '/tmp/tmux-0/default');173 const write = vi.fn();174 175 writeTerminalTitle(write, '');176 177 expect(write).toHaveBeenCalledWith('\x1b]2;\x07');178 });179});180 181describe('formatSessionWindowTitle', () => {182 beforeEach(() => {183 vi.stubEnv('CLI_TITLE', undefined);184 });185 186 afterEach(() => {187 vi.unstubAllEnvs();188 });189 190 it('should return session name when set', () => {191 expect(formatSessionWindowTitle('Fix terminal title')).toBe(192 'Fix terminal title',193 );194 });195 196 it('should fall back to computeWindowTitle when sessionName is null', () => {197 expect(formatSessionWindowTitle(null, 'my-project')).toBe(198 'Qwen - my-project',199 );200 });201 202 it('should prefer CLI_TITLE over folder name when sessionName is null', () => {203 vi.stubEnv('CLI_TITLE', 'Custom Title');204 expect(formatSessionWindowTitle(null, 'my-project')).toBe('Custom Title');205 });206 207 it('should sanitize control characters from session name', () => {208 expect(formatSessionWindowTitle('Bad\x07Title')).toBe('BadTitle');209 });210 211 it('should use default title when sessionName is null and no folder', () => {212 expect(formatSessionWindowTitle(null)).toBe('Qwen - qwen');213 });214});215 