import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import { attachableFromChunk, fetchPassageText, parsePassageRange } from './passageText.js'; const chapter = { chapter: { content: [1, 2, 3, 4, 5].map((n) => ({ type: 'verse', number: n, content: [`Verse ${n} text.`] })) } }; beforeEach(() => vi.stubGlobal('fetch', vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve(chapter) })))); afterEach(() => vi.unstubAllGlobals()); test('reads a verse, a range, or a whole chapter', () => { expect(parsePassageRange('Titus 1:5')).toMatchObject({ book: 'TIT', chapter: 1, start: 5, end: 5 }); expect(parsePassageRange('titus 1:5-9')).toMatchObject({ start: 5, end: 9 }); expect(parsePassageRange('1 Cor 13:4–7')).toMatchObject({ book: '1CO', chapter: 13, start: 4, end: 7 }); expect(parsePassageRange('John 3')).toMatchObject({ chapter: 3, start: null }); }); test('rejects things that are not passages, or backwards ranges', () => { expect(parsePassageRange('hello')).toBeNull(); expect(parsePassageRange('Titus 9:1')).toBeNull(); expect(parsePassageRange('Titus 1:9-5')).toBeNull(); }); test('fetches just the verses asked for, and names the passage', async () => { const got = await fetchPassageText('Titus 1:2-3'); expect(got).toEqual({ ref: 'Titus 1:2–3', text: 'Verse 2 text. Verse 3 text.', translation: 'BSB' }); }); test('says so when the verses are not there, or the passage is not understood', async () => { await expect(fetchPassageText('Titus 1:50')).rejects.toThrow(/weren’t found/); await expect(fetchPassageText('nonsense')).rejects.toThrow(/Type a passage/); }); test('offers a chunk\'s cross-references and studied words to attach', () => { const chunk = { crossReferences: ['John 1:1'], greekWords: [ { strongNumber: 'G1401', lexeme: 'δοῦλος', shortDefinition: 'a slave' }, { query: 'xyz', shortDefinition: 'No definition found.' }, ], }; expect(attachableFromChunk(chunk)).toEqual([ { key: 'x:John 1:1', type: 'xref', label: 'John 1:1' }, { key: 'w:G1401', type: 'word', label: 'δοῦλος (G1401)', detail: 'a slave' }, { key: 'w:xyz', type: 'word', label: 'xyz', detail: undefined }, ]); expect(attachableFromChunk(null)).toEqual([]); });