Files
2025-11-30 09:04:14 +08:00

176 lines
5.0 KiB
TypeScript

/**
* 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
});
});