/ src / output.test.ts
output.test.ts
 1  import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
 2  import { render } from './output.js';
 3  
 4  describe('output TTY detection', () => {
 5    const originalIsTTY = process.stdout.isTTY;
 6    let logSpy: ReturnType<typeof vi.spyOn>;
 7  
 8    beforeEach(() => {
 9      logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
10    });
11  
12    afterEach(() => {
13      Object.defineProperty(process.stdout, 'isTTY', { value: originalIsTTY, writable: true });
14      logSpy.mockRestore();
15    });
16  
17    it('outputs YAML in non-TTY when format is default table', () => {
18      Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
19      // commanderAdapter always passes fmt:'table' as default — this must still trigger downgrade
20      render([{ name: 'alice', score: 10 }], { fmt: 'table', columns: ['name', 'score'] });
21      const out = logSpy.mock.calls.map((c: unknown[]) => c[0]).join('\n');
22      expect(out).toContain('name: alice');
23      expect(out).toContain('score: 10');
24    });
25  
26    it('outputs table in TTY when format is default table', () => {
27      Object.defineProperty(process.stdout, 'isTTY', { value: true, writable: true });
28      render([{ name: 'alice', score: 10 }], { fmt: 'table', columns: ['name', 'score'] });
29      const out = logSpy.mock.calls.map((c: unknown[]) => c[0]).join('\n');
30      expect(out).toContain('alice');
31    });
32  
33    it('respects explicit -f json even in non-TTY', () => {
34      Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
35      render([{ name: 'alice' }], { fmt: 'json' });
36      const out = logSpy.mock.calls.map((c: unknown[]) => c[0]).join('\n');
37      expect(JSON.parse(out)).toEqual([{ name: 'alice' }]);
38    });
39  
40    it('shows elapsed time when elapsed is 0', () => {
41      Object.defineProperty(process.stdout, 'isTTY', { value: true, writable: true });
42      render([{ name: 'alice' }], { fmt: 'table', columns: ['name'], elapsed: 0 });
43      const out = logSpy.mock.calls.map((c: unknown[]) => c[0]).join('\n');
44      expect(out).toContain('0.0s');
45    });
46  
47    it('explicit -f table overrides non-TTY auto-downgrade', () => {
48      Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
49      render([{ name: 'alice' }], { fmt: 'table', fmtExplicit: true, columns: ['name'] });
50      const out = logSpy.mock.calls.map((c: unknown[]) => c[0]).join('\n');
51      // Should be table output, not YAML
52      expect(out).not.toContain('name: alice');
53      expect(out).toContain('alice');
54    });
55  });