176 lines
5.0 KiB
TypeScript
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
|
|
});
|
|
});
|