/** * Jest CLI Test Template * * Complete test suite for CLI tools using Jest and child_process.execSync * Tests command execution, exit codes, stdout/stderr output */ import { execSync } from 'child_process'; import fs from 'fs'; import path from 'path'; describe('CLI Tool Tests', () => { const CLI_PATH = path.join(__dirname, '../bin/mycli'); /** * Helper function to execute CLI commands and capture output * @param args - Command line arguments as string * @returns Object with stdout, stderr, and exit code */ function runCLI(args: string): { stdout: string; stderr: string; code: number; } { try { const stdout = execSync(`${CLI_PATH} ${args}`, { encoding: 'utf8', stdio: 'pipe', }); return { stdout, stderr: '', code: 0 }; } catch (error: any) { return { stdout: error.stdout || '', stderr: error.stderr || '', code: error.status || 1, }; } } // Version Testing describe('version command', () => { test('should display version with --version', () => { const { stdout, code } = runCLI('--version'); expect(code).toBe(0); expect(stdout).toContain('1.0.0'); }); test('should display version with -v', () => { const { stdout, code } = runCLI('-v'); expect(code).toBe(0); expect(stdout).toMatch(/\d+\.\d+\.\d+/); }); }); // Help Testing describe('help command', () => { test('should display help with --help', () => { const { stdout, code } = runCLI('--help'); expect(code).toBe(0); expect(stdout).toContain('Usage:'); expect(stdout).toContain('Commands:'); expect(stdout).toContain('Options:'); }); test('should display help with -h', () => { const { stdout, code } = runCLI('-h'); expect(code).toBe(0); expect(stdout).toContain('Usage:'); }); }); // Error Handling describe('error handling', () => { test('should handle unknown command', () => { const { stderr, code } = runCLI('unknown-command'); expect(code).toBe(1); expect(stderr).toContain('unknown command'); }); test('should handle invalid options', () => { const { stderr, code } = runCLI('--invalid-option'); expect(code).toBe(1); expect(stderr).toContain('unknown option'); }); test('should validate required arguments', () => { const { stderr, code } = runCLI('deploy'); expect(code).toBe(1); expect(stderr).toContain('missing required argument'); }); }); // Command Execution describe('command execution', () => { test('should execute deploy command', () => { const { stdout, code } = runCLI('deploy production --force'); expect(code).toBe(0); expect(stdout).toContain('Deploying to production'); expect(stdout).toContain('Force mode enabled'); }); test('should execute with flags', () => { const { stdout, code } = runCLI('build --verbose --output dist'); expect(code).toBe(0); expect(stdout).toContain('Building project'); expect(stdout).toContain('Output: dist'); }); }); // Configuration Testing describe('configuration', () => { test('should set configuration value', () => { const { stdout, code } = runCLI('config set key value'); expect(code).toBe(0); expect(stdout).toContain('Configuration updated'); }); test('should get configuration value', () => { runCLI('config set api_key your_key_here'); const { stdout, code } = runCLI('config get api_key'); expect(code).toBe(0); expect(stdout).toContain('your_key_here'); }); test('should list all configuration', () => { const { stdout, code } = runCLI('config list'); expect(code).toBe(0); expect(stdout).toContain('Configuration:'); }); }); // Exit Code Validation describe('exit codes', () => { test('should return 0 on success', () => { const { code } = runCLI('status'); expect(code).toBe(0); }); test('should return 1 on general error', () => { const { code } = runCLI('invalid-command'); expect(code).toBe(1); }); test('should return 2 on invalid arguments', () => { const { code } = runCLI('deploy --invalid-flag'); expect(code).toBe(2); }); }); // Output Format Testing describe('output formatting', () => { test('should output JSON when requested', () => { const { stdout, code } = runCLI('status --format json'); expect(code).toBe(0); expect(() => JSON.parse(stdout)).not.toThrow(); }); test('should output YAML when requested', () => { const { stdout, code } = runCLI('status --format yaml'); expect(code).toBe(0); expect(stdout).toContain(':'); }); test('should output table by default', () => { const { stdout, code } = runCLI('status'); expect(code).toBe(0); expect(stdout).toMatch(/[─┼│]/); // Table characters }); }); // Cleanup afterAll(() => { // Clean up any test artifacts }); });