From 69799f2f803cb761310b0e8dfad84ad0a323373e Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Fri, 13 Feb 2026 17:07:13 -0800 Subject: [PATCH] test: add 3 tests for Round 106 (878 total) - countInFile with named capture groups verifies match(g) ignores group details - grepFile with multiline (m) flag confirms flag is preserved unlike stripped g - getAllSessions with array/object limit tests Number() coercion edge cases --- tests/lib/session-manager.test.js | 46 +++++++++++++++++++++++++++++++ tests/lib/utils.test.js | 44 +++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/tests/lib/session-manager.test.js b/tests/lib/session-manager.test.js index e3543e82..56a99502 100644 --- a/tests/lib/session-manager.test.js +++ b/tests/lib/session-manager.test.js @@ -1739,6 +1739,52 @@ file.ts 'In-progress item should be Task C'); })) passed++; else failed++; + // ── Round 106: getAllSessions with array/object limit — Number() coercion edge cases ── + console.log('\nRound 106: getAllSessions (array/object limit coercion — Number([5])→5, Number({})→NaN→50):'); + if (test('getAllSessions coerces array/object limit via Number() with NaN fallback to 50', () => { + const isoHome = path.join(os.tmpdir(), `ecc-r106-limit-coerce-${Date.now()}`); + const isoSessionsDir = path.join(isoHome, '.claude', 'sessions'); + fs.mkdirSync(isoSessionsDir, { recursive: true }); + // Create 3 test sessions + for (let i = 0; i < 3; i++) { + const name = `2026-03-0${i + 1}-aaaa${i}${i}${i}${i}-session.tmp`; + const filePath = path.join(isoSessionsDir, name); + fs.writeFileSync(filePath, `# Session ${i}`); + const mtime = new Date(Date.now() - (3 - i) * 60000); + fs.utimesSync(filePath, mtime, mtime); + } + const origHome = process.env.HOME; + const origUserProfile = process.env.USERPROFILE; + process.env.HOME = isoHome; + process.env.USERPROFILE = isoHome; + try { + delete require.cache[require.resolve('../../scripts/lib/session-manager')]; + delete require.cache[require.resolve('../../scripts/lib/utils')]; + const freshManager = require('../../scripts/lib/session-manager'); + // Object limit: Number({}) → NaN → fallback to 50 + const objResult = freshManager.getAllSessions({ limit: {} }); + assert.strictEqual(objResult.limit, 50, + 'Object limit should coerce to NaN → fallback to default 50'); + assert.strictEqual(objResult.total, 3, 'Should still find all 3 sessions'); + // Single-element array: Number([2]) → 2 + const arrResult = freshManager.getAllSessions({ limit: [2] }); + assert.strictEqual(arrResult.limit, 2, + 'Single-element array [2] coerces to Number 2 via Number([2])'); + assert.strictEqual(arrResult.sessions.length, 2, 'Should return only 2 sessions'); + assert.strictEqual(arrResult.hasMore, true, 'hasMore should be true with limit 2 of 3'); + // Multi-element array: Number([1,2]) → NaN → fallback to 50 + const multiArrResult = freshManager.getAllSessions({ limit: [1, 2] }); + assert.strictEqual(multiArrResult.limit, 50, + 'Multi-element array [1,2] coerces to NaN → fallback to 50'); + } finally { + process.env.HOME = origHome; + process.env.USERPROFILE = origUserProfile; + delete require.cache[require.resolve('../../scripts/lib/session-manager')]; + delete require.cache[require.resolve('../../scripts/lib/utils')]; + fs.rmSync(isoHome, { recursive: true, force: true }); + } + })) 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 2e3ddbbc..4b775de9 100644 --- a/tests/lib/utils.test.js +++ b/tests/lib/utils.test.js @@ -1548,6 +1548,50 @@ function runTests() { } })) 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', () => { + const tmpDir = fs.mkdtempSync(path.join(utils.getTempDir(), 'r106-count-named-')); + const testFile = path.join(tmpDir, 'test.txt'); + try { + fs.writeFileSync(testFile, 'foo bar baz\nfoo qux\nbar foo end'); + // Named capture group — should still count 3 matches for "foo" + const count = utils.countInFile(testFile, /(?foo)/); + assert.strictEqual(count, 3, + 'Named capture group should not inflate count — match(g) returns full matches only'); + // Compare with plain pattern + const plainCount = utils.countInFile(testFile, /foo/); + assert.strictEqual(plainCount, 3, 'Plain regex should also find 3 matches'); + assert.strictEqual(count, plainCount, + 'Named group pattern and plain pattern should return identical counts'); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + })) passed++; else failed++; + + // ── Round 106: grepFile with multiline (m) flag — preserved, unlike g which is stripped ── + console.log('\nRound 106: grepFile (multiline m flag — preserved in regex, unlike g which is stripped):'); + if (test('grepFile preserves multiline (m) flag and anchors work on split lines', () => { + const tmpDir = fs.mkdtempSync(path.join(utils.getTempDir(), 'r106-grep-multiline-')); + const testFile = path.join(tmpDir, 'test.txt'); + try { + fs.writeFileSync(testFile, 'hello\nworld hello\nhello world'); + // With m flag + anchors: ^hello$ should match only exact "hello" line + const mResults = utils.grepFile(testFile, /^hello$/m); + assert.strictEqual(mResults.length, 1, + 'With m flag, ^hello$ should match only line 1 (exact "hello")'); + assert.strictEqual(mResults[0].lineNumber, 1); + // Without m flag: same behavior since grepFile splits lines individually + const noMResults = utils.grepFile(testFile, /^hello$/); + assert.strictEqual(noMResults.length, 1, + 'Without m flag, same result — grepFile splits lines so anchors are per-line already'); + assert.strictEqual(mResults.length, noMResults.length, + 'm flag is preserved but irrelevant — line splitting makes anchors per-line already'); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + })) passed++; else failed++; + // Summary console.log('\n=== Test Results ==='); console.log(`Passed: ${passed}`);