mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-02-16 03:13:08 +08:00
fix: header subtitle width mismatch in skill-create-output; add 9 tests (Round 34)
- Fix subtitle padding 55→59 so line 94 matches 64-char border width - Add 4 header width alignment tests (skill-create-output) - Add 3 getExecCommand non-string args tests (package-manager) - Add 2 detectFromPackageJson non-string type tests (package-manager)
This commit is contained in:
@@ -91,7 +91,7 @@ class SkillCreateOutput {
|
||||
console.log('\n');
|
||||
console.log(chalk.bold(chalk.magenta('╔════════════════════════════════════════════════════════════════╗')));
|
||||
console.log(chalk.bold(chalk.magenta('║')) + chalk.bold(' 🔮 ECC Skill Creator ') + chalk.bold(chalk.magenta('║')));
|
||||
console.log(chalk.bold(chalk.magenta('║')) + ` ${subtitle}${' '.repeat(Math.max(0, 55 - stripAnsi(subtitle).length))}` + chalk.bold(chalk.magenta('║')));
|
||||
console.log(chalk.bold(chalk.magenta('║')) + ` ${subtitle}${' '.repeat(Math.max(0, 59 - stripAnsi(subtitle).length))}` + chalk.bold(chalk.magenta('║')));
|
||||
console.log(chalk.bold(chalk.magenta('╚════════════════════════════════════════════════════════════════╝')));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
@@ -1093,6 +1093,77 @@ function runTests() {
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 34: getExecCommand non-string args & packageManager type ──
|
||||
console.log('\nRound 34: getExecCommand non-string args:');
|
||||
|
||||
if (test('getExecCommand with args=0 produces command without extra args', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'npm';
|
||||
const cmd = pm.getExecCommand('prettier', 0);
|
||||
// 0 is falsy, so ternary `args ? ' ' + args : ''` yields ''
|
||||
assert.ok(!cmd.includes(' 0'), 'Should not append 0 as args');
|
||||
assert.ok(cmd.includes('prettier'), 'Should include binary name');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
else delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getExecCommand with args=false produces command without extra args', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'npm';
|
||||
const cmd = pm.getExecCommand('eslint', false);
|
||||
assert.ok(!cmd.includes('false'), 'Should not append false as args');
|
||||
assert.ok(cmd.includes('eslint'), 'Should include binary name');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
else delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getExecCommand with args=null produces command without extra args', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'npm';
|
||||
const cmd = pm.getExecCommand('tsc', null);
|
||||
assert.ok(!cmd.includes('null'), 'Should not append null as args');
|
||||
assert.ok(cmd.includes('tsc'), 'Should include binary name');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
else delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
console.log('\nRound 34: detectFromPackageJson with non-string packageManager:');
|
||||
|
||||
if (test('detectFromPackageJson handles array packageManager field gracefully', () => {
|
||||
const tmpDir = createTestDir();
|
||||
try {
|
||||
// Write a malformed package.json with array instead of string
|
||||
fs.writeFileSync(path.join(tmpDir, 'package.json'),
|
||||
JSON.stringify({ packageManager: ['pnpm@8', 'yarn@3'] }));
|
||||
// Should not crash — try/catch in detectFromPackageJson catches TypeError
|
||||
const result = pm.getPackageManager({ projectDir: tmpDir });
|
||||
assert.ok(result.name, 'Should fallback to a valid package manager');
|
||||
} finally {
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('detectFromPackageJson handles numeric packageManager field gracefully', () => {
|
||||
const tmpDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(tmpDir, 'package.json'),
|
||||
JSON.stringify({ packageManager: 42 }));
|
||||
const result = pm.getPackageManager({ projectDir: tmpDir });
|
||||
assert.ok(result.name, 'Should fallback to a valid package manager');
|
||||
} finally {
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log('\n=== Test Results ===');
|
||||
console.log(`Passed: ${passed}`);
|
||||
|
||||
@@ -319,6 +319,61 @@ function runTests() {
|
||||
assert.ok(combined.includes('Powered by'), 'Should include attribution text');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 34: header width alignment ──
|
||||
console.log('\nheader() width alignment (Round 34):');
|
||||
|
||||
if (test('header subtitle line matches border width', () => {
|
||||
const output = new SkillCreateOutput('test-repo');
|
||||
const logs = captureLog(() => output.header());
|
||||
// Find the border and subtitle lines
|
||||
const lines = logs.map(l => stripAnsi(l));
|
||||
const borderLine = lines.find(l => l.includes('═══'));
|
||||
const subtitleLine = lines.find(l => l.includes('Extracting patterns'));
|
||||
assert.ok(borderLine, 'Should find border line');
|
||||
assert.ok(subtitleLine, 'Should find subtitle line');
|
||||
// Both lines should have the same visible width
|
||||
assert.strictEqual(subtitleLine.length, borderLine.length,
|
||||
`Subtitle width (${subtitleLine.length}) should match border width (${borderLine.length})`);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('header all lines have consistent width for short repo name', () => {
|
||||
const output = new SkillCreateOutput('abc');
|
||||
const logs = captureLog(() => output.header());
|
||||
const lines = logs.map(l => stripAnsi(l)).filter(l => l.includes('║') || l.includes('╔') || l.includes('╚'));
|
||||
assert.ok(lines.length >= 4, 'Should have at least 4 box lines');
|
||||
const widths = lines.map(l => l.length);
|
||||
const first = widths[0];
|
||||
widths.forEach((w, i) => {
|
||||
assert.strictEqual(w, first,
|
||||
`Line ${i} width (${w}) should match first line (${first})`);
|
||||
});
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('header subtitle has correct content area width of 64 chars', () => {
|
||||
const output = new SkillCreateOutput('myrepo');
|
||||
const logs = captureLog(() => output.header());
|
||||
const lines = logs.map(l => stripAnsi(l));
|
||||
const subtitleLine = lines.find(l => l.includes('Extracting patterns'));
|
||||
assert.ok(subtitleLine, 'Should find subtitle line');
|
||||
// Content between ║ and ║ should be 64 chars (border is 66 total)
|
||||
// Format: ║ + content(64) + ║ = 66
|
||||
assert.strictEqual(subtitleLine.length, 66,
|
||||
`Total subtitle line width should be 66, got ${subtitleLine.length}`);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('header subtitle line does not truncate with medium-length repo name', () => {
|
||||
const output = new SkillCreateOutput('my-medium-repo-name');
|
||||
const logs = captureLog(() => output.header());
|
||||
const combined = logs.join('\n');
|
||||
assert.ok(combined.includes('my-medium-repo-name'), 'Should include full repo name');
|
||||
const lines = logs.map(l => stripAnsi(l));
|
||||
const subtitleLine = lines.find(l => l.includes('Extracting patterns'));
|
||||
assert.ok(subtitleLine, 'Should have subtitle line');
|
||||
// Should still be 66 chars even with a longer name
|
||||
assert.strictEqual(subtitleLine.length, 66,
|
||||
`Subtitle line should be 66 chars, got ${subtitleLine.length}`);
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user