From 531156214e82c65fa269e088a05530cc300a9879 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Jul 2026 04:41:36 +0000 Subject: [PATCH] test: cover untested public API in smoke.mjs (journey + knownThemes) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four exported symbols had no smoke-test coverage: - `monthsOfMovement` — not imported or exercised at all; new check verifies it returns the five "ground" months in calendar order with correct themes. - `movementOf(arc, number)` — only the object-argument path was tested; new check exercises the number path (the branch that calls `monthByNumber` internally) with August and September. - `mirrorOf` reverse lookup — both January and December carry an explicit `mirrors` field in the real arc, so the reverse-lookup branch (`arc.months.find(m => m.mirrors === number)`) was dead in every existing test. New check builds a minimal synthetic arc where only one side declares the link, forcing the reverse path. - `mirrorOf` null return — added an assertion that months with no mirror partner (May, July) return null. - `Personalizer.knownThemes()` — public method, zero coverage; new check verifies it unions declared interests with implicit affinity built from reading history. 19 → 24 checks, all green. Build unchanged. --- scripts/smoke.mjs | 50 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/scripts/smoke.mjs b/scripts/smoke.mjs index 02f90be..0a6c293 100644 --- a/scripts/smoke.mjs +++ b/scripts/smoke.mjs @@ -11,7 +11,7 @@ import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { Personalizer, collectThemes, normalizeTheme } from '../src/personalize.js'; import { SearchIndex, tokenize, snippet } from '../src/search.js'; -import { asMovements, monthByNumber, movementOf, mirrorOf, currentMonth, neighbors } from '../src/journey.js'; +import { asMovements, monthByNumber, movementOf, mirrorOf, monthsOfMovement, currentMonth, neighbors } from '../src/journey.js'; const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); const { articles } = JSON.parse( @@ -154,4 +154,52 @@ check('search matches an author name', () => { assert.ok(hits[0].matched.includes('nirodbaran')); }); +console.log('journey.js (more)'); + +check('monthsOfMovement returns the right months in calendar order', () => { + const groundMonths = monthsOfMovement(arc, 'ground'); + assert.deepEqual( + groundMonths.map((m) => m.number), + [1, 2, 3, 4, 5], + ); + assert.deepEqual( + groundMonths.map((m) => m.theme), + ['Gratitude', 'Aspiration', 'Peace and Progress', 'Renewal', 'Discernment'], + ); +}); + +check('movementOf accepts a month number directly, not only an object', () => { + assert.equal(movementOf(arc, 8).id, 'presence'); + assert.equal(movementOf(arc, 9).id, 'forward'); +}); + +check('mirrorOf resolves the reverse direction when only one side declares the link', () => { + const minimal = { + months: [ + { number: 1, name: 'January', mirrors: 12 }, + { number: 12, name: 'December' }, // no mirrors field — reverse lookup required + ], + movements: [], + }; + assert.equal(mirrorOf(minimal, 12).number, 1); + assert.equal(mirrorOf(minimal, 1).number, 12); // forward direction still works +}); + +check('mirrorOf returns null for a month that has no mirror partner', () => { + assert.equal(mirrorOf(arc, 5), null); // May mirrors nobody + assert.equal(mirrorOf(arc, 7), null); // July mirrors nobody +}); + +console.log('personalize.js (knownThemes)'); + +check('knownThemes returns the union of declared interests and implicit affinity', () => { + const p = new Personalizer({ storage: null }).setInterests(['Sadhana']); + const vedanta = articles.find((a) => a.themes.includes('Vedanta')); + p.recordRead(vedanta); + const known = p.knownThemes(); + assert.ok(known.has('sadhana'), 'declared interest should appear'); + assert.ok(known.has('vedanta'), 'theme from reading history should appear'); + assert.ok(!known.has('nonexistent'), 'unseen theme should not appear'); +}); + console.log(`\n${passed} checks passed.`);