/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { vi, describe, expect, it, beforeEach, afterEach } from 'vitest';
import { readStdin } from './readStdin.js';
// Mock process.stdin
const mockStdin = {
    setEncoding: vi.fn(),
    read: vi.fn(),
    on: vi.fn(),
    removeListener: vi.fn(),
    destroy: vi.fn(),
};
describe('readStdin', () => {
    let originalStdin;
    let onReadableHandler;
    let onEndHandler;
    beforeEach(() => {
        vi.clearAllMocks();
        originalStdin = process.stdin;
        // Replace process.stdin with our mock
        Object.defineProperty(process, 'stdin', {
            value: mockStdin,
            writable: true,
            configurable: true,
        });
        // Capture event handlers
        mockStdin.on.mockImplementation((event, handler) => {
            if (event === 'readable')
                onReadableHandler = handler;
            if (event === 'end')
                onEndHandler = handler;
        });
    });
    afterEach(() => {
        vi.restoreAllMocks();
        Object.defineProperty(process, 'stdin', {
            value: originalStdin,
            writable: true,
            configurable: true,
        });
    });
    it('should read and accumulate data from stdin', async () => {
        mockStdin.read
            .mockReturnValueOnce('I love ')
            .mockReturnValueOnce('Gemini!')
            .mockReturnValueOnce(null);
        const promise = readStdin();
        // Trigger readable event
        onReadableHandler();
        // Trigger end to resolve
        onEndHandler();
        await expect(promise).resolves.toBe('I love Gemini!');
    });
    it('should handle empty stdin input', async () => {
        mockStdin.read.mockReturnValue(null);
        const promise = readStdin();
        // Trigger end immediately
        onEndHandler();
        await expect(promise).resolves.toBe('');
    });
    // Emulate terminals where stdin is not TTY (eg: git bash)
    it('should timeout and resolve with empty string when no input is available', async () => {
        vi.useFakeTimers();
        const promise = readStdin();
        // Fast-forward past the timeout (to run test faster)
        vi.advanceTimersByTime(500);
        await expect(promise).resolves.toBe('');
        vi.useRealTimers();
    });
    it('should clear timeout once when data is received and resolve with data', async () => {
        const clearTimeoutSpy = vi.spyOn(global, 'clearTimeout');
        mockStdin.read
            .mockReturnValueOnce('chunk1')
            .mockReturnValueOnce('chunk2')
            .mockReturnValueOnce(null);
        const promise = readStdin();
        // Trigger readable event
        onReadableHandler();
        expect(clearTimeoutSpy).toHaveBeenCalledOnce();
        // Trigger end to resolve
        onEndHandler();
        await expect(promise).resolves.toBe('chunk1chunk2');
    });
});
//# sourceMappingURL=readStdin.test.js.map