From a64a294b29f97edfbdada669a1e8e4735911ce9e Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Fri, 13 Feb 2026 16:02:18 -0800 Subject: [PATCH] test: add 3 edge-case tests for looksLikePath heuristic, falsy title coercion, and checkbox regex (Round 102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getSessionStats with Unix nonexistent .tmp path triggers looksLikePath heuristic → readFile returns null → zeroed stats via null content path - setAlias with title=0 silently converts to null (0 || null === null) - parseSessionMetadata skips [x] checked items in In Progress section (regex only matches unchecked [ ] checkboxes) Total tests: 866 --- tests/lib/session-aliases.test.js | 17 +++++++++++++ tests/lib/session-manager.test.js | 41 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/tests/lib/session-aliases.test.js b/tests/lib/session-aliases.test.js index fb84b888..72ee69c9 100644 --- a/tests/lib/session-aliases.test.js +++ b/tests/lib/session-aliases.test.js @@ -1310,6 +1310,23 @@ function runTests() { 'Alias should no longer exist after removal'); })) passed++; else failed++; + // ── Round 102: setAlias with title=0 (falsy number coercion) ── + console.log('\nRound 102: setAlias (title=0 — falsy coercion silently converts to null):'); + if (test('setAlias with title=0 stores null (0 || null === null due to JavaScript falsy coercion)', () => { + // session-aliases.js line 221: `title: title || null` — the value 0 is falsy + // in JavaScript, so `0 || null` evaluates to `null`. This means numeric + // titles like 0 are silently discarded. + resetAliases(); + const result = aliases.setAlias('zero-title', '/sessions/test', 0); + assert.strictEqual(result.success, true, + 'setAlias should succeed (0 is valid as a truthy check bypass)'); + assert.strictEqual(result.title, null, + 'Title should be null because 0 || null === null (falsy coercion)'); + const resolved = aliases.resolveAlias('zero-title'); + assert.strictEqual(resolved.title, null, + 'Persisted title should be null after round-trip through saveAliases/loadAliases'); + })) passed++; else failed++; + // Summary console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`); process.exit(failed > 0 ? 1 : 0); diff --git a/tests/lib/session-manager.test.js b/tests/lib/session-manager.test.js index 891be80a..2dc5141a 100644 --- a/tests/lib/session-manager.test.js +++ b/tests/lib/session-manager.test.js @@ -1648,6 +1648,47 @@ src/main.ts 'null path should cause fs.appendFileSync to throw TypeError, caught by try/catch'); })) passed++; else failed++; + // ── Round 102: getSessionStats with Unix nonexistent .tmp path (looksLikePath heuristic) ── + console.log('\nRound 102: getSessionStats (Unix nonexistent .tmp path — looksLikePath → null content):'); + if (test('getSessionStats returns zeroed stats when Unix path looks like file but does not exist', () => { + // session-manager.js lines 163-166: looksLikePath heuristic checks typeof string, + // no newlines, endsWith('.tmp'), startsWith('/'). A nonexistent Unix path triggers + // the file-read branch → readFile returns null → parseSessionMetadata(null) returns + // default empty metadata → lineCount: null ? ... : 0 === 0. + const stats = sessionManager.getSessionStats('/nonexistent/deep/path/session.tmp'); + assert.strictEqual(stats.totalItems, 0, + 'No items from nonexistent file (parseSessionMetadata(null) returns empty arrays)'); + assert.strictEqual(stats.lineCount, 0, + 'lineCount: 0 because content is null (ternary guard at line 177)'); + assert.strictEqual(stats.hasNotes, false, + 'No notes section in null content'); + assert.strictEqual(stats.hasContext, false, + 'No context section in null content'); + })) passed++; else failed++; + + // ── Round 102: parseSessionMetadata with [x] checked items in In Progress section ── + console.log('\nRound 102: parseSessionMetadata ([x] items in In Progress — regex skips checked):'); + if (test('parseSessionMetadata skips [x] checked items in In Progress section (regex only matches [ ])', () => { + // session-manager.js line 130: progressSection regex uses `- \[ \]\s*(.+)` which + // only matches unchecked checkboxes. Checked items `- [x]` in the In Progress + // section are silently ignored — they don't match the regex pattern. + const content = `# Session + +### In Progress +- [x] Already finished but placed here by mistake +- [ ] Actually in progress +- [x] Another misplaced completed item +- [ ] Second active task +`; + const meta = sessionManager.parseSessionMetadata(content); + assert.strictEqual(meta.inProgress.length, 2, + 'Only unchecked [ ] items should be captured (2 of 4)'); + assert.strictEqual(meta.inProgress[0], 'Actually in progress', + 'First unchecked item'); + assert.strictEqual(meta.inProgress[1], 'Second active task', + 'Second unchecked item'); + })) passed++; else failed++; + // Summary console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`); process.exit(failed > 0 ? 1 : 0);