"use strict";
/**
 * CommandExecutor单元测试
 * 测试命令执行器的核心功能和错误处理
 */
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const command_executor_1 = require("../../../src/utils/command-executor");
const errors_1 = require("../../../src/types/errors");
describe('CommandExecutor Unit Tests', function () {
    let executor;
    beforeEach(function () {
        executor = new command_executor_1.CommandExecutor('test-platform', {
            timeout: 5000,
            encoding: 'utf8'
        });
    });
    describe('基本命令执行', function () {
        it('应该能够执行简单的系统命令', async function () {
            // 使用跨平台兼容的命令
            const command = process.platform === 'win32' ? 'echo hello' : 'echo "hello"';
            const result = await executor.execute(command);
            (0, chai_1.expect)(result.stdout.trim()).to.equal('hello');
            (0, chai_1.expect)(result.stderr).to.equal('');
            (0, chai_1.expect)(result.exitCode).to.equal(0);
            (0, chai_1.expect)(result.platform).to.equal('test-platform');
            (0, chai_1.expect)(result.command).to.equal(command);
            (0, chai_1.expect)(result.executionTime).to.be.a('number');
        });
        it('应该正确处理命令执行失败', async function () {
            try {
                await executor.execute('nonexistent-command-12345');
                // 如果没有抛出错误，则测试失败
                chai_1.expect.fail('应该抛出错误');
            }
            catch (error) {
                (0, chai_1.expect)(error).to.be.an('error');
                // 检查是否是MonitorError
                if (error.code) {
                    (0, chai_1.expect)(error.code).to.be.oneOf(['COMMAND_FAILED', 'FILE_NOT_FOUND']);
                }
            }
        });
        it('应该正确处理有stderr输出但成功的命令', async function () {
            // 某些命令会向stderr输出信息但仍然成功
            const command = process.platform === 'win32'
                ? 'echo error>&2 & echo success'
                : 'echo "error" >&2; echo "success"';
            const result = await executor.execute(command);
            (0, chai_1.expect)(result.stdout.trim()).to.include('success');
            (0, chai_1.expect)(result.exitCode).to.equal(0);
        });
    });
    describe('超时处理', function () {
        it('应该在超时后终止命令', async function () {
            this.timeout(3000); // 设置测试超时
            const shortTimeout = new command_executor_1.CommandExecutor('test-platform', { timeout: 100 });
            // 创建一个会运行较长时间的命令
            const command = process.platform === 'win32'
                ? 'ping -n 10 127.0.0.1'
                : 'sleep 5';
            try {
                await shortTimeout.execute(command);
                chai_1.expect.fail('应该抛出超时错误');
            }
            catch (error) {
                (0, chai_1.expect)(error).to.be.an('error');
                if (error.code) {
                    (0, chai_1.expect)(error.code).to.equal('TIMEOUT');
                }
            }
        });
    });
    describe('输出处理', function () {
        it('应该正确处理大量输出', async function () {
            // 生成大量输出的命令
            const command = process.platform === 'win32'
                ? 'for /L %i in (1,1,10) do @echo Line %i'
                : 'for i in {1..10}; do echo "Line $i"; done';
            const result = await executor.execute(command);
            const lines = result.stdout.trim().split('\n');
            (0, chai_1.expect)(lines.length).to.be.at.least(5); // 至少有一些行
            (0, chai_1.expect)(result.exitCode).to.equal(0);
        });
        it('应该正确处理空输出', async function () {
            const command = process.platform === 'win32' ? 'echo.' : 'true';
            const result = await executor.execute(command);
            (0, chai_1.expect)(result.exitCode).to.equal(0);
        });
    });
    describe('平台特定命令', function () {
        it('应该能够执行平台特定的系统信息命令', async function () {
            let command;
            switch (process.platform) {
                case 'darwin':
                    command = 'uname -s';
                    break;
                case 'linux':
                    command = 'uname -s';
                    break;
                case 'win32':
                    command = 'ver';
                    break;
                default:
                    this.skip();
                    return;
            }
            const result = await executor.execute(command);
            (0, chai_1.expect)(result.stdout).to.be.a('string');
            (0, chai_1.expect)(result.stdout.length).to.be.greaterThan(0);
            (0, chai_1.expect)(result.exitCode).to.equal(0);
        });
    });
    describe('配置选项', function () {
        it('应该使用自定义配置', async function () {
            const customExecutor = new command_executor_1.CommandExecutor('custom-platform', {
                timeout: 1000,
                encoding: 'utf8'
            });
            const command = process.platform === 'win32' ? 'echo test' : 'echo "test"';
            const result = await customExecutor.execute(command);
            (0, chai_1.expect)(result.stdout.trim()).to.equal('test');
            (0, chai_1.expect)(result.platform).to.equal('custom-platform');
        });
    });
    describe('并发执行', function () {
        it('应该能够并发执行多个命令', async function () {
            const commands = [
                process.platform === 'win32' ? 'echo 1' : 'echo "1"',
                process.platform === 'win32' ? 'echo 2' : 'echo "2"',
                process.platform === 'win32' ? 'echo 3' : 'echo "3"'
            ];
            const promises = commands.map(cmd => executor.execute(cmd));
            const results = await Promise.all(promises);
            results.forEach((result, index) => {
                (0, chai_1.expect)(result.stdout.trim()).to.equal((index + 1).toString());
                (0, chai_1.expect)(result.exitCode).to.equal(0);
            });
        });
    });
    describe('流式执行', function () {
        it('应该在禁用 shell 时正确处理包含空格的命令', async function () {
            const script = 'console.log("stream output")';
            const command = executor.buildCommand(process.execPath, ['-e', script]);
            const chunks = [];
            const result = await executor.executeStream(command, (data) => {
                chunks.push(data);
            }, { shell: false });
            (0, chai_1.expect)(result.exitCode).to.equal(0);
            (0, chai_1.expect)(chunks.join('')).to.contain('stream output');
        });
    });
});
describe('CommandExecutor — Deno 兼容性：非标准异常处理', function () {
    it('T023: 应将字符串类型的非标准异常统一捕获为 MonitorError(COMMAND_FAILED)', async function () {
        const executor = new command_executor_1.CommandExecutor('test-platform');
        const internal = executor;
        // 模拟 Deno 兼容层抛出非 Error 实例（字符串）
        internal.executeWithTimeout = async () => {
            // eslint-disable-next-line @typescript-eslint/no-throw-literal
            throw 'Deno compat layer: exec failed unexpectedly';
        };
        try {
            await executor.execute('echo test');
            chai_1.expect.fail('应该抛出错误');
        }
        catch (error) {
            (0, chai_1.expect)(error).to.be.instanceOf(errors_1.MonitorError);
            (0, chai_1.expect)(error.code).to.equal(errors_1.ErrorCode.COMMAND_FAILED);
        }
    });
    it('T023: 应将自定义对象类型的非标准异常统一捕获为 MonitorError(COMMAND_FAILED)', async function () {
        const executor = new command_executor_1.CommandExecutor('test-platform');
        const internal = executor;
        // 模拟 Deno 兼容层抛出普通对象（非 Error 实例）
        internal.executeWithTimeout = async () => {
            // eslint-disable-next-line @typescript-eslint/no-throw-literal
            throw { message: 'DENO_EXEC_ERROR', code: 'ERR_DENO_COMPAT' };
        };
        try {
            await executor.execute('echo test');
            chai_1.expect.fail('应该抛出错误');
        }
        catch (error) {
            (0, chai_1.expect)(error).to.be.instanceOf(errors_1.MonitorError);
            (0, chai_1.expect)(error.code).to.equal(errors_1.ErrorCode.COMMAND_FAILED);
        }
    });
});
//# sourceMappingURL=command-executor.test.js.map