import test from 'node:test'; import assert from 'node:assert/strict'; const { parseIndex, searchIndex, resultsToHTML } = await import('../src/sphinx.js'); // A miniature docs.python.org: enough shape to exercise every lookup path // (single-number terms, title boosts, stemmed words, object anchors) without // a fixture file to drift out of date. const INDEX = { docnames: ['library/json', 'library/threading', 'tutorial/appendix'], titles: [ 'json - JSON encoder and decoder', 'threading - Thread-based parallelism', 'Appendix', ], terms: { json: 0, thread: [1, 2], socket: [2] }, titleterms: { json: [0], thread: [1] }, objects: { json: [[0, 3, 1, '', 'dumps']] }, objnames: { 3: ['py', 'function', 'Python function'] }, }; const BASE = 'https://docs.python.org/3/'; test('parseIndex unwraps Search.setIndex() and refuses anything else', () => { assert.equal(parseIndex('Search.setIndex({"a": 1})').a, 1); assert.throws(() => parseIndex('a block page'), /not a Sphinx search index/); assert.throws(() => parseIndex('Search.setIndex(undefined)'), /not a Sphinx search index/); }); test('a title hit outranks body hits, and one-doc terms stored as a bare number work', () => { const found = searchIndex(INDEX, 'thread'); assert.deepEqual(found.docs.map((d) => d.doc), [1, 2]); assert.equal(searchIndex(INDEX, 'json').docs[0].doc, 0); }); test('a word Sphinx stemmed away still matches through its stem', () => { // The index stores 'thread'; a query typed as English says 'threading'. const found = searchIndex(INDEX, 'threading'); assert.equal(found.docs[0].doc, 1); }); test('titles are flattened to text before they reach the results page', () => { const found = searchIndex(INDEX, 'json'); assert.equal(found.docs[0].title, 'json - JSON encoder and decoder'); }); test('a tag the title never closes is stripped, not left standing', () => { // 'json encoder