|
3 | 3 | */ |
4 | 4 |
|
5 | 5 | import { describe, expect, it, vi } from 'vitest'; |
6 | | -import { createTicker } from './ticker.js'; |
| 6 | +import { createTicker, isNoColor } from './ticker.js'; |
7 | 7 |
|
8 | 8 | describe('createTicker — non-TTY (CI mode)', () => { |
9 | 9 | it('update is a no-op (no writes)', () => { |
@@ -222,3 +222,65 @@ describe('createTicker — spy on process.stderr', () => { |
222 | 222 | } |
223 | 223 | }); |
224 | 224 | }); |
| 225 | + |
| 226 | +describe('createTicker — NO_COLOR support', () => { |
| 227 | + it('suppresses ANSI escape sequences when noColor=true on TTY', () => { |
| 228 | + const lines: string[] = []; |
| 229 | + const raw: string[] = []; |
| 230 | + const ticker = createTicker( |
| 231 | + line => lines.push(line), |
| 232 | + true, // isTTY = true |
| 233 | + text => raw.push(text), |
| 234 | + true, // noColor = true |
| 235 | + ); |
| 236 | + ticker.update('progress'); |
| 237 | + // Should use stderrWrite (line-oriented) instead of rawWrite with ANSI |
| 238 | + expect(raw).toHaveLength(0); |
| 239 | + expect(lines).toHaveLength(1); |
| 240 | + expect(lines[0]!).not.toContain('\x1b[2K'); |
| 241 | + expect(lines[0]!).not.toContain('\r'); |
| 242 | + expect(lines[0]!).toContain('progress'); |
| 243 | + }); |
| 244 | + |
| 245 | + it('finalize emits plain text without ANSI when noColor=true on TTY', () => { |
| 246 | + const lines: string[] = []; |
| 247 | + const raw: string[] = []; |
| 248 | + const ticker = createTicker( |
| 249 | + line => lines.push(line), |
| 250 | + true, |
| 251 | + text => raw.push(text), |
| 252 | + true, // noColor = true |
| 253 | + ); |
| 254 | + ticker.finalize('done'); |
| 255 | + expect(raw).toHaveLength(0); |
| 256 | + expect(lines).toHaveLength(1); |
| 257 | + expect(lines[0]!).not.toContain('\x1b[2K'); |
| 258 | + expect(lines[0]!).toContain('done'); |
| 259 | + }); |
| 260 | + |
| 261 | + it('normal ANSI output when noColor=false on TTY', () => { |
| 262 | + const raw: string[] = []; |
| 263 | + const ticker = createTicker( |
| 264 | + () => {}, |
| 265 | + true, |
| 266 | + text => raw.push(text), |
| 267 | + false, // noColor = false |
| 268 | + ); |
| 269 | + ticker.update('progress'); |
| 270 | + expect(raw).toHaveLength(1); |
| 271 | + expect(raw[0]!).toContain('\x1b[2K\r'); |
| 272 | + }); |
| 273 | +}); |
| 274 | + |
| 275 | +describe('isNoColor', () => { |
| 276 | + it('returns true when NO_COLOR is present in env', () => { |
| 277 | + expect(isNoColor({ NO_COLOR: '' })).toBe(true); |
| 278 | + expect(isNoColor({ NO_COLOR: '1' })).toBe(true); |
| 279 | + expect(isNoColor({ NO_COLOR: 'true' })).toBe(true); |
| 280 | + }); |
| 281 | + |
| 282 | + it('returns false when NO_COLOR is not present in env', () => { |
| 283 | + expect(isNoColor({})).toBe(false); |
| 284 | + expect(isNoColor({ OTHER_VAR: '1' })).toBe(false); |
| 285 | + }); |
| 286 | +}); |
0 commit comments