From 910ffa55309ce391fe89bb6783739f2ce04bbd5c Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Fri, 13 Feb 2026 14:21:03 -0800 Subject: [PATCH] test: add 3 tests for regex boundary and flag logic gaps (round 93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- tests/lib/session-manager.test.js | 14 +++++++++++++ tests/lib/utils.test.js | 34 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/tests/lib/session-manager.test.js b/tests/lib/session-manager.test.js index 6e83cc6c..ff1c023d 100644 --- a/tests/lib/session-manager.test.js +++ b/tests/lib/session-manager.test.js @@ -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); diff --git a/tests/lib/utils.test.js b/tests/lib/utils.test.js index 515f6383..bfbc61bd 100644 --- a/tests/lib/utils.test.js +++ b/tests/lib/utils.test.js @@ -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}`);