test: add 3 tests for Round 107 (881 total)

- grepFile with ^$ pattern verifies empty line matching including trailing newline phantom
- replaceInFile with self-reintroducing replacement confirms single-pass behavior
- setAlias with whitespace-only title exposes missing trim validation vs sessionPath
This commit is contained in:
Affaan Mustafa
2026-02-13 17:11:32 -08:00
parent 69799f2f80
commit 882157ac09
2 changed files with 57 additions and 0 deletions

View File

@@ -1375,6 +1375,26 @@ function runTests() {
'Another path-traversal pattern also returned unchanged');
})) passed++; else failed++;
// ── Round 107: setAlias with whitespace-only title (not trimmed unlike sessionPath) ──
console.log('\nRound 107: setAlias (whitespace-only title — truthy string stored as-is, unlike sessionPath which is trim-checked):');
if (test('setAlias stores whitespace-only title as-is (no trim validation, unlike sessionPath)', () => {
resetAliases();
// sessionPath with whitespace is rejected (line 195: sessionPath.trim().length === 0)
const pathResult = aliases.setAlias('ws-path', ' ');
assert.strictEqual(pathResult.success, false,
'Whitespace-only sessionPath is rejected by trim check');
// But title with whitespace is stored as-is (line 221: title || null — whitespace is truthy)
const titleResult = aliases.setAlias('ws-title', '/valid/path', ' ');
assert.strictEqual(titleResult.success, true,
'Whitespace-only title is accepted (no trim check on title)');
assert.strictEqual(titleResult.title, ' ',
'Title stored as whitespace string (truthy, so title || null returns the whitespace)');
// Verify persisted correctly
const loaded = aliases.loadAliases();
assert.strictEqual(loaded.aliases['ws-title'].title, ' ',
'Whitespace title persists in JSON as-is');
})) passed++; else failed++;
// Summary
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);

View File

@@ -1548,6 +1548,43 @@ function runTests() {
}
})) passed++; else failed++;
// ── Round 107: grepFile with ^$ pattern — empty line matching after split ──
console.log('\nRound 107: grepFile (empty line matching — ^$ on split lines, trailing \\n creates extra empty element):');
if (test('grepFile matches empty lines with ^$ pattern including trailing newline phantom line', () => {
const tmpDir = fs.mkdtempSync(path.join(utils.getTempDir(), 'r107-grep-empty-'));
const testFile = path.join(tmpDir, 'test.txt');
try {
// 'line1\n\nline3\n\n'.split('\n') → ['line1','','line3','',''] (5 elements, 3 empty)
fs.writeFileSync(testFile, 'line1\n\nline3\n\n');
const results = utils.grepFile(testFile, /^$/);
assert.strictEqual(results.length, 3,
'Should match 3 empty lines: line 2, line 4, and trailing phantom line 5');
assert.strictEqual(results[0].lineNumber, 2, 'First empty line at position 2');
assert.strictEqual(results[1].lineNumber, 4, 'Second empty line at position 4');
assert.strictEqual(results[2].lineNumber, 5, 'Third empty line is the trailing phantom from split');
} finally {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
})) passed++; else failed++;
// ── Round 107: replaceInFile where replacement re-introduces search pattern (single-pass) ──
console.log('\nRound 107: replaceInFile (replacement contains search pattern — String.replace is single-pass):');
if (test('replaceInFile does not re-scan replacement text (single-pass, no infinite loop)', () => {
const tmpDir = fs.mkdtempSync(path.join(utils.getTempDir(), 'r107-replace-reintr-'));
const testFile = path.join(tmpDir, 'test.txt');
try {
fs.writeFileSync(testFile, 'foo bar baz');
// Replace "foo" with "foo extra foo" — should only replace the first occurrence
const result = utils.replaceInFile(testFile, 'foo', 'foo extra foo');
assert.strictEqual(result, true, 'replaceInFile should return true');
const content = utils.readFile(testFile);
assert.strictEqual(content, 'foo extra foo bar baz',
'Only the original "foo" is replaced — replacement text is not re-scanned');
} finally {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
})) passed++; else failed++;
// ── Round 106: countInFile with named capture groups — match(g) ignores group details ──
console.log('\nRound 106: countInFile (named capture groups — String.match(g) returns full matches only):');
if (test('countInFile with named capture groups counts matches not groups', () => {