mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-01 06:33:27 +08:00
fix: clamp progressBar to prevent RangeError on overflow, add 10 tests
progressBar() in skill-create-output.js could crash with RangeError when percent > 100 because repeat() received a negative count. Fixed by clamping filled to [0, width]. New tests: - progressBar edge cases: 0%, 100%, and >100% confidence - Empty patterns/instincts arrays - post-edit-format: null tool_input, missing file_path, prettier failure - setup-package-manager: --detect output completeness, current marker
This commit is contained in:
@@ -53,7 +53,7 @@ function stripAnsi(str) {
|
||||
}
|
||||
|
||||
function progressBar(percent, width = 30) {
|
||||
const filled = Math.round(width * percent / 100);
|
||||
const filled = Math.min(width, Math.max(0, Math.round(width * percent / 100)));
|
||||
const empty = width - filled;
|
||||
const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
|
||||
return `${bar} ${chalk.bold(percent)}%`;
|
||||
|
||||
@@ -680,6 +680,27 @@ async function runTests() {
|
||||
assert.strictEqual(result.code, 0, 'Should exit 0 for invalid JSON');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (await asyncTest('handles null tool_input gracefully', async () => {
|
||||
const stdinJson = JSON.stringify({ tool_input: null });
|
||||
const result = await runScript(path.join(scriptsDir, 'post-edit-format.js'), stdinJson);
|
||||
assert.strictEqual(result.code, 0, 'Should exit 0 for null tool_input');
|
||||
assert.ok(result.stdout.includes('tool_input'), 'Should pass through data');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (await asyncTest('handles missing file_path in tool_input', async () => {
|
||||
const stdinJson = JSON.stringify({ tool_input: {} });
|
||||
const result = await runScript(path.join(scriptsDir, 'post-edit-format.js'), stdinJson);
|
||||
assert.strictEqual(result.code, 0, 'Should exit 0 for missing file_path');
|
||||
assert.ok(result.stdout.includes('tool_input'), 'Should pass through data');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (await asyncTest('exits 0 and passes data when prettier is unavailable', async () => {
|
||||
const stdinJson = JSON.stringify({ tool_input: { file_path: '/nonexistent/path/file.ts' } });
|
||||
const result = await runScript(path.join(scriptsDir, 'post-edit-format.js'), stdinJson);
|
||||
assert.strictEqual(result.code, 0, 'Should exit 0 even when prettier fails');
|
||||
assert.ok(result.stdout.includes('tool_input'), 'Should pass through original data');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// post-edit-typecheck.js tests
|
||||
console.log('\npost-edit-typecheck.js:');
|
||||
|
||||
|
||||
@@ -159,6 +159,22 @@ function runTests() {
|
||||
assert.ok(result.stdout.includes('pnpm'));
|
||||
})) passed++; else failed++;
|
||||
|
||||
// --detect output completeness
|
||||
console.log('\n--detect output completeness:');
|
||||
|
||||
if (test('shows all three command types in detection output', () => {
|
||||
const result = run(['--detect']);
|
||||
assert.strictEqual(result.code, 0);
|
||||
assert.ok(result.stdout.includes('Install:'), 'Should show Install command');
|
||||
assert.ok(result.stdout.includes('Run script:'), 'Should show Run script command');
|
||||
assert.ok(result.stdout.includes('Execute binary:'), 'Should show Execute binary command');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('shows current marker for active package manager', () => {
|
||||
const result = run(['--detect']);
|
||||
assert.ok(result.stdout.includes('(current)'), 'Should mark current PM');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
|
||||
@@ -179,6 +179,54 @@ function runTests() {
|
||||
assert.ok(combined.includes('Everything Claude Code'), 'Should include project name');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// progressBar edge cases (tests the clamp fix)
|
||||
console.log('\nprogressBar edge cases:');
|
||||
|
||||
if (test('does not crash with confidence > 1.0 (percent > 100)', () => {
|
||||
const output = new SkillCreateOutput('repo');
|
||||
// confidence 1.5 => percent 150 — previously crashed with RangeError
|
||||
const logs = captureLog(() => output.patterns([
|
||||
{ name: 'Overconfident', trigger: 'always', confidence: 1.5, evidence: 'too much' },
|
||||
]));
|
||||
const combined = stripAnsi(logs.join('\n'));
|
||||
assert.ok(combined.includes('150%'), 'Should show 150%');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('renders 0% confidence bar without crash', () => {
|
||||
const output = new SkillCreateOutput('repo');
|
||||
const logs = captureLog(() => output.patterns([
|
||||
{ name: 'Zero Confidence', trigger: 'never', confidence: 0.0, evidence: 'none' },
|
||||
]));
|
||||
const combined = stripAnsi(logs.join('\n'));
|
||||
assert.ok(combined.includes('0%'), 'Should show 0%');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('renders 100% confidence bar without crash', () => {
|
||||
const output = new SkillCreateOutput('repo');
|
||||
const logs = captureLog(() => output.patterns([
|
||||
{ name: 'Perfect', trigger: 'always', confidence: 1.0, evidence: 'certain' },
|
||||
]));
|
||||
const combined = stripAnsi(logs.join('\n'));
|
||||
assert.ok(combined.includes('100%'), 'Should show 100%');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Empty array edge cases
|
||||
console.log('\nempty array edge cases:');
|
||||
|
||||
if (test('patterns() with empty array produces header but no entries', () => {
|
||||
const output = new SkillCreateOutput('repo');
|
||||
const logs = captureLog(() => output.patterns([]));
|
||||
const combined = logs.join('\n');
|
||||
assert.ok(combined.includes('Patterns'), 'Should show header');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('instincts() with empty array produces box but no entries', () => {
|
||||
const output = new SkillCreateOutput('repo');
|
||||
const logs = captureLog(() => output.instincts([]));
|
||||
const combined = logs.join('\n');
|
||||
assert.ok(combined.includes('Instincts'), 'Should show box title');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Box drawing crash fix (regression test)
|
||||
console.log('\nbox() crash prevention:');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user