mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-14 13:53:29 +08:00
test: add edge-case tests for listAliases type coercion, replaceInFile options.all with RegExp, and output BigInt serialization (round 114)
This commit is contained in:
@@ -1452,6 +1452,37 @@ function runTests() {
|
|||||||
'Cyrillic homoglyph "е" (U+0435) should be rejected even though it looks like "e"');
|
'Cyrillic homoglyph "е" (U+0435) should be rejected even though it looks like "e"');
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
// ── Round 114: listAliases with non-string search (number) — TypeError on toLowerCase ──
|
||||||
|
console.log('\nRound 114: listAliases (non-string search — number triggers TypeError):');
|
||||||
|
if (test('listAliases throws TypeError when search option is a number (no toLowerCase method)', () => {
|
||||||
|
resetAliases();
|
||||||
|
|
||||||
|
// Set up some aliases to search through
|
||||||
|
aliases.setAlias('alpha-session', '/path/to/alpha');
|
||||||
|
aliases.setAlias('beta-session', '/path/to/beta');
|
||||||
|
|
||||||
|
// String search works fine — baseline
|
||||||
|
const stringResult = aliases.listAliases({ search: 'alpha' });
|
||||||
|
assert.strictEqual(stringResult.length, 1, 'String search should find 1 match');
|
||||||
|
assert.strictEqual(stringResult[0].name, 'alpha-session');
|
||||||
|
|
||||||
|
// Numeric search — search.toLowerCase() at line 261 of session-aliases.js
|
||||||
|
// throws TypeError because Number.prototype has no toLowerCase method.
|
||||||
|
// The code does NOT guard against non-string search values.
|
||||||
|
assert.throws(
|
||||||
|
() => aliases.listAliases({ search: 123 }),
|
||||||
|
(err) => err instanceof TypeError && /toLowerCase/.test(err.message),
|
||||||
|
'Numeric search value should throw TypeError from toLowerCase call'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Boolean search — also lacks toLowerCase
|
||||||
|
assert.throws(
|
||||||
|
() => aliases.listAliases({ search: true }),
|
||||||
|
(err) => err instanceof TypeError && /toLowerCase/.test(err.message),
|
||||||
|
'Boolean search value should also throw TypeError'
|
||||||
|
);
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
// Summary
|
// Summary
|
||||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||||
process.exit(failed > 0 ? 1 : 0);
|
process.exit(failed > 0 ? 1 : 0);
|
||||||
|
|||||||
@@ -1728,6 +1728,77 @@ function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
// ── Round 114: replaceInFile options.all is silently ignored for RegExp search ──
|
||||||
|
console.log('\nRound 114: replaceInFile (options.all silently ignored for RegExp search):');
|
||||||
|
if (test('replaceInFile ignores options.all when search is a RegExp — falls through to .replace()', () => {
|
||||||
|
const tmpDir = fs.mkdtempSync(path.join(utils.getTempDir(), 'r114-all-regex-'));
|
||||||
|
const testFile = path.join(tmpDir, 'test.txt');
|
||||||
|
try {
|
||||||
|
// File with repeated pattern: "foo bar foo baz foo"
|
||||||
|
fs.writeFileSync(testFile, 'foo bar foo baz foo');
|
||||||
|
|
||||||
|
// With options.all=true and a non-global RegExp:
|
||||||
|
// Line 411: (options.all && typeof search === 'string') → false (RegExp !== string)
|
||||||
|
// Falls through to content.replace(regex, replace) — only replaces FIRST match
|
||||||
|
const result = utils.replaceInFile(testFile, /foo/, 'QUX', { all: true });
|
||||||
|
assert.strictEqual(result, true, 'Should succeed');
|
||||||
|
const content = utils.readFile(testFile);
|
||||||
|
assert.strictEqual(content, 'QUX bar foo baz foo',
|
||||||
|
'Non-global RegExp with options.all=true should still only replace FIRST match');
|
||||||
|
|
||||||
|
// Contrast: global RegExp replaces all regardless of options.all
|
||||||
|
fs.writeFileSync(testFile, 'foo bar foo baz foo');
|
||||||
|
utils.replaceInFile(testFile, /foo/g, 'QUX', { all: true });
|
||||||
|
const globalContent = utils.readFile(testFile);
|
||||||
|
assert.strictEqual(globalContent, 'QUX bar QUX baz QUX',
|
||||||
|
'Global RegExp replaces all matches (options.all irrelevant for RegExp)');
|
||||||
|
|
||||||
|
// String with options.all=true — uses replaceAll, replaces ALL occurrences
|
||||||
|
fs.writeFileSync(testFile, 'foo bar foo baz foo');
|
||||||
|
utils.replaceInFile(testFile, 'foo', 'QUX', { all: true });
|
||||||
|
const allContent = utils.readFile(testFile);
|
||||||
|
assert.strictEqual(allContent, 'QUX bar QUX baz QUX',
|
||||||
|
'String with options.all=true uses replaceAll — replaces ALL occurrences');
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
// ── Round 114: output with object containing BigInt — JSON.stringify throws ──
|
||||||
|
console.log('\nRound 114: output (object containing BigInt — JSON.stringify throws):');
|
||||||
|
if (test('output throws TypeError when object contains BigInt values (JSON.stringify cannot serialize)', () => {
|
||||||
|
// Capture original console.log to prevent actual output during test
|
||||||
|
const originalLog = console.log;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Plain BigInt — typeof is 'bigint', not 'object', so goes to else branch
|
||||||
|
// console.log can handle BigInt directly (prints "42n")
|
||||||
|
let captured = null;
|
||||||
|
console.log = (val) => { captured = val; };
|
||||||
|
utils.output(BigInt(42));
|
||||||
|
// Node.js console.log prints BigInt as-is
|
||||||
|
assert.strictEqual(captured, BigInt(42), 'Plain BigInt goes to else branch, logged directly');
|
||||||
|
|
||||||
|
// Object containing BigInt — typeof is 'object', so JSON.stringify is called
|
||||||
|
// JSON.stringify(BigInt) throws: "Do not know how to serialize a BigInt"
|
||||||
|
console.log = originalLog; // restore before throw test
|
||||||
|
assert.throws(
|
||||||
|
() => utils.output({ value: BigInt(42) }),
|
||||||
|
(err) => err instanceof TypeError && /BigInt/.test(err.message),
|
||||||
|
'Object with BigInt should throw TypeError from JSON.stringify'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Array containing BigInt — also typeof 'object'
|
||||||
|
assert.throws(
|
||||||
|
() => utils.output([BigInt(1), BigInt(2)]),
|
||||||
|
(err) => err instanceof TypeError && /BigInt/.test(err.message),
|
||||||
|
'Array with BigInt should also throw TypeError from JSON.stringify'
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
console.log = originalLog;
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
// Summary
|
// Summary
|
||||||
console.log('\n=== Test Results ===');
|
console.log('\n=== Test Results ===');
|
||||||
console.log(`Passed: ${passed}`);
|
console.log(`Passed: ${passed}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user