/** * Jest Configuration Testing Template * * Test CLI configuration file handling, validation, and persistence */ import { execSync } from 'child_process'; import fs from 'fs'; import path from 'path'; import os from 'os'; describe('CLI Configuration Tests', () => { const CLI_PATH = path.join(__dirname, '../bin/mycli'); const TEST_CONFIG_DIR = path.join(os.tmpdir(), 'cli-test-config'); const TEST_CONFIG_FILE = path.join(TEST_CONFIG_DIR, '.myclirc'); function runCLI(args: string, env: Record = {}): { stdout: string; stderr: string; code: number; } { try { const stdout = execSync(`${CLI_PATH} ${args}`, { encoding: 'utf8', stdio: 'pipe', env: { ...process.env, HOME: TEST_CONFIG_DIR, ...env, }, }); return { stdout, stderr: '', code: 0 }; } catch (error: any) { return { stdout: error.stdout || '', stderr: error.stderr || '', code: error.status || 1, }; } } beforeEach(() => { // Create temporary config directory if (!fs.existsSync(TEST_CONFIG_DIR)) { fs.mkdirSync(TEST_CONFIG_DIR, { recursive: true }); } }); afterEach(() => { // Clean up test config directory if (fs.existsSync(TEST_CONFIG_DIR)) { fs.rmSync(TEST_CONFIG_DIR, { recursive: true, force: true }); } }); describe('config initialization', () => { test('should create config file on first run', () => { runCLI('config init'); expect(fs.existsSync(TEST_CONFIG_FILE)).toBe(true); }); test('should not overwrite existing config', () => { fs.writeFileSync(TEST_CONFIG_FILE, 'existing: data\n'); const { stderr, code } = runCLI('config init'); expect(code).toBe(1); expect(stderr).toContain('Config file already exists'); }); test('should create config with default values', () => { runCLI('config init'); const config = fs.readFileSync(TEST_CONFIG_FILE, 'utf8'); expect(config).toContain('api_key: your_api_key_here'); expect(config).toContain('environment: development'); }); }); describe('config set operations', () => { beforeEach(() => { runCLI('config init'); }); test('should set string value', () => { const { code } = runCLI('config set api_key test_key_123'); expect(code).toBe(0); const config = fs.readFileSync(TEST_CONFIG_FILE, 'utf8'); expect(config).toContain('api_key: test_key_123'); }); test('should set boolean value', () => { const { code } = runCLI('config set verbose true'); expect(code).toBe(0); const config = fs.readFileSync(TEST_CONFIG_FILE, 'utf8'); expect(config).toContain('verbose: true'); }); test('should set nested value', () => { const { code } = runCLI('config set logging.level debug'); expect(code).toBe(0); const config = fs.readFileSync(TEST_CONFIG_FILE, 'utf8'); expect(config).toContain('level: debug'); }); test('should handle invalid key names', () => { const { stderr, code } = runCLI('config set invalid..key value'); expect(code).toBe(1); expect(stderr).toContain('Invalid key name'); }); }); describe('config get operations', () => { beforeEach(() => { runCLI('config init'); runCLI('config set api_key test_key_123'); runCLI('config set environment production'); }); test('should get existing value', () => { const { stdout, code } = runCLI('config get api_key'); expect(code).toBe(0); expect(stdout).toContain('test_key_123'); }); test('should handle non-existent key', () => { const { stderr, code } = runCLI('config get nonexistent'); expect(code).toBe(1); expect(stderr).toContain('Key not found'); }); test('should get nested value', () => { runCLI('config set database.host localhost'); const { stdout, code } = runCLI('config get database.host'); expect(code).toBe(0); expect(stdout).toContain('localhost'); }); }); describe('config list operations', () => { beforeEach(() => { runCLI('config init'); runCLI('config set api_key test_key_123'); runCLI('config set verbose true'); }); test('should list all configuration', () => { const { stdout, code } = runCLI('config list'); expect(code).toBe(0); expect(stdout).toContain('api_key'); expect(stdout).toContain('verbose'); }); test('should format list output', () => { const { stdout, code } = runCLI('config list --format json'); expect(code).toBe(0); const config = JSON.parse(stdout); expect(config.api_key).toBe('test_key_123'); expect(config.verbose).toBe(true); }); }); describe('config validation', () => { test('should validate config file on load', () => { fs.writeFileSync(TEST_CONFIG_FILE, 'invalid yaml: [}'); const { stderr, code } = runCLI('config list'); expect(code).toBe(1); expect(stderr).toContain('Invalid configuration file'); }); test('should validate required fields', () => { runCLI('config init'); fs.writeFileSync(TEST_CONFIG_FILE, 'optional: value\n'); const { stderr, code } = runCLI('deploy production'); expect(code).toBe(1); expect(stderr).toContain('api_key is required'); }); }); describe('environment variable overrides', () => { beforeEach(() => { runCLI('config init'); runCLI('config set api_key file_key_123'); }); test('should override with environment variable', () => { const { stdout } = runCLI('config get api_key', { MYCLI_API_KEY: 'env_key_123', }); expect(stdout).toContain('env_key_123'); }); test('should use file value when env var not set', () => { const { stdout } = runCLI('config get api_key'); expect(stdout).toContain('file_key_123'); }); }); });