test: add 3 tests for regex boundary and flag logic gaps (round 93)

- getSessionStats: drive letter without slash (Z:nosession.tmp) treated as content
- countInFile: case-insensitive regex with g flag auto-appended (/foo/i → /foo/ig)
- countInFile: case-insensitive regex with g flag preserved (/foo/gi stays /foo/gi)
This commit is contained in:
Affaan Mustafa
2026-02-13 14:21:03 -08:00
parent b9a38b2680
commit 910ffa5530
2 changed files with 48 additions and 0 deletions

View File

@@ -1474,6 +1474,20 @@ src/main.ts
'UNC path should be treated as single-line content (not a recognized path)');
})) passed++; else failed++;
// ── Round 93: getSessionStats with drive letter but no slash (regex boundary) ──
console.log('\nRound 93: getSessionStats (drive letter without slash — regex boundary):');
if (test('getSessionStats treats drive letter without slash as content (not a path)', () => {
// session-manager.js line 166: /^[A-Za-z]:[/\\]/ requires a '/' or '\'
// immediately after the colon. 'Z:nosession.tmp' has 'Z:n' which does NOT
// match, so looksLikePath is false even though .endsWith('.tmp') is true.
const stats = sessionManager.getSessionStats('Z:nosession.tmp');
assert.strictEqual(stats.lineCount, 1,
'Z:nosession.tmp (no slash) should be treated as single-line content');
assert.strictEqual(stats.totalItems, 0,
'Content without session items should have 0 totalItems');
})) passed++; else failed++;
// Summary
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);

View File

@@ -1248,6 +1248,40 @@ function runTests() {
}
})) passed++; else failed++;
// ── Round 93: countInFile with /pattern/i (g flag appended) ──
console.log('\nRound 93: countInFile (case-insensitive RegExp, g flag auto-appended):');
if (test('countInFile with /pattern/i appends g flag and counts case-insensitively', () => {
// utils.js line 440: pattern.flags = 'i', 'i'.includes('g') → false,
// so new RegExp(source, 'i' + 'g') → /pattern/ig
const testFile = path.join(utils.getTempDir(), `utils-test-ci-flag-${Date.now()}.txt`);
try {
utils.writeFile(testFile, 'Foo foo FOO fOo bar baz');
const count = utils.countInFile(testFile, /foo/i);
assert.strictEqual(count, 4,
'Case-insensitive regex with auto-appended g should match all 4 occurrences');
} finally {
try { fs.unlinkSync(testFile); } catch { /* best-effort */ }
}
})) passed++; else failed++;
// ── Round 93: countInFile with /pattern/gi (g flag already present) ──
console.log('\nRound 93: countInFile (case-insensitive RegExp, g flag preserved):');
if (test('countInFile with /pattern/gi preserves existing flags and counts correctly', () => {
// utils.js line 440: pattern.flags = 'gi', 'gi'.includes('g') → true,
// so new RegExp(source, 'gi') — flags preserved unchanged
const testFile = path.join(utils.getTempDir(), `utils-test-gi-flag-${Date.now()}.txt`);
try {
utils.writeFile(testFile, 'Foo foo FOO fOo bar baz');
const count = utils.countInFile(testFile, /foo/gi);
assert.strictEqual(count, 4,
'Case-insensitive regex with pre-existing g should match all 4 occurrences');
} finally {
try { fs.unlinkSync(testFile); } catch { /* best-effort */ }
}
})) passed++; else failed++;
// Summary
console.log('\n=== Test Results ===');
console.log(`Passed: ${passed}`);