"use strict";
/**
 * CLI Test Generator
 * Generates Jest tests for CLI commands
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CliTestGenerator = void 0;
const path = __importStar(require("path"));
class CliTestGenerator {
    id = 'cli-unit-tests';
    name = 'CLI Unit Test Generator';
    description = 'Generates Jest unit tests for CLI commands';
    testFramework = 'cli-jest';
    generate(context) {
        const { workflow, outputDirectory } = context;
        const files = [];
        if (!workflow.testing?.unit_tests) {
            return { files: [] };
        }
        // Filter unit tests for CLI components
        const cliTests = workflow.testing.unit_tests.filter((test) => {
            const [componentName] = test.component.split('.');
            const component = workflow.stack[componentName];
            return component?.type === 'cli';
        });
        for (const test of cliTests) {
            const [componentName, commandId] = test.component.split('.');
            const stackComponent = workflow.stack[componentName];
            if (!stackComponent)
                continue;
            // Find the specific command definition
            const command = stackComponent.commands?.find((c) => c.id === commandId);
            if (!command)
                continue;
            // Generate test file
            files.push(this.generateCommandTest(componentName, command, test.scenarios, outputDirectory));
        }
        // Generate Jest config if we have tests
        if (files.length > 0) {
            const cliComponent = Object.entries(workflow.stack).find(([_, c]) => c.type === 'cli');
            if (cliComponent) {
                files.push(this.generateJestConfig(cliComponent[0], outputDirectory));
            }
        }
        return { files };
    }
    generateCommandTest(componentName, command, scenarios, outputDir) {
        const commandName = command.name || command.id;
        let content = `import { Command } from 'commander';
import { ${this.toCamelCase(commandName)}Command } from '../commands/${commandName}';

describe('${commandName} command', () => {
  let program: Command;
  let consoleLogSpy: jest.SpyInstance;

  beforeEach(() => {
    program = new Command();
    ${this.toCamelCase(commandName)}Command(program);
    consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
  });

  afterEach(() => {
    consoleLogSpy.mockRestore();
  });

`;
        // Generate test cases for each scenario
        for (const scenario of scenarios) {
            content += this.generateScenarioTest(scenario, command);
        }
        content += `});
`;
        return {
            path: path.join(outputDir, componentName, 'src', 'commands', `${commandName}.test.ts`),
            content,
            overwrite: true,
        };
    }
    generateScenarioTest(scenario, command) {
        const lowerScenario = scenario.toLowerCase();
        if (lowerScenario.includes('default')) {
            return this.generateDefaultTest(command);
        }
        if (lowerScenario.includes('custom') || lowerScenario.includes('provided')) {
            return this.generateCustomArgumentTest(command);
        }
        // Generic test case
        return `  it('${scenario}', async () => {
    // TODO: Implement test for: ${scenario}
    expect(true).toBe(true);
  });

`;
    }
    generateDefaultTest(command) {
        const commandName = command.name || command.id;
        const args = command.arguments || [];
        const defaultArg = args.find((a) => a.default);
        return `  it('displays default greeting message', async () => {
    await program.parseAsync(['node', 'cli', '${commandName}']);

    expect(consoleLogSpy).toHaveBeenCalled();
    ${defaultArg ? `expect(consoleLogSpy.mock.calls[0][0]).toContain('${defaultArg.default}');` : ''}
  });

`;
    }
    generateCustomArgumentTest(command) {
        const commandName = command.name || command.id;
        const args = command.arguments || [];
        const _firstArg = args[0];
        return `  it('displays custom greeting with provided name', async () => {
    await program.parseAsync(['node', 'cli', '${commandName}', 'Alice']);

    expect(consoleLogSpy).toHaveBeenCalled();
    expect(consoleLogSpy.mock.calls[0][0]).toContain('Alice');
  });

`;
    }
    generateJestConfig(componentName, outputDir) {
        const config = `module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  roots: ['<rootDir>/src'],
  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
  transform: {
    '^.+\\\\.ts$': 'ts-jest',
  },
  collectCoverageFrom: [
    'src/**/*.ts',
    '!src/**/*.d.ts',
    '!src/**/*.test.ts',
  ],
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov', 'html'],
};
`;
        return {
            path: path.join(outputDir, componentName, 'jest.config.js'),
            content: config,
            overwrite: false,
        };
    }
    toCamelCase(str) {
        return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
    }
}
exports.CliTestGenerator = CliTestGenerator;
//# sourceMappingURL=cli-test-generator.js.map