import { test, expect } from 'vitest'; import { emptyMarks, isEmptyMarks, marksEqual, mergeMarks, normalizeMarks } from './readerMarks.js'; const hl = (over = {}) => ({ id: 'h1', book: 'JHN', chapter: 3, verse: 16, startOffset: 4, endOffset: 20, color: '#fef08a', ...over }); test('normalizeMarks tolerates junk', () => { expect(normalizeMarks(null)).toEqual(emptyMarks()); expect(normalizeMarks({ bookmarks: [], highlights: 'x' })).toEqual(emptyMarks()); expect(normalizeMarks({ bookmarks: { a: '#fff' }, highlights: [hl(), null, { nope: 1 }] }).highlights).toEqual([hl()]); }); test('isEmptyMarks', () => { expect(isEmptyMarks(emptyMarks())).toBe(true); expect(isEmptyMarks({ bookmarks: { 'JHN-3-16': '#fff' }, highlights: [] })).toBe(false); }); test('mergeMarks keeps everything from both devices; the server wins a colour clash', () => { const local = { bookmarks: { 'JHN-3-16': '#111111', 'GEN-1-1': '#222222' }, highlights: [hl({ id: 'L' })] }; const server = { bookmarks: { 'JHN-3-16': '#999999', 'ROM-8-1': '#333333' }, highlights: [hl({ id: 'S', verse: 17 })] }; const merged = mergeMarks(local, server); expect(merged.bookmarks).toEqual({ 'JHN-3-16': '#999999', 'GEN-1-1': '#222222', 'ROM-8-1': '#333333' }); expect(merged.highlights.map((h) => h.id).sort()).toEqual(['L', 'S']); }); test('mergeMarks does not duplicate a highlight both devices made on the same words', () => { const merged = mergeMarks({ bookmarks: {}, highlights: [hl({ id: 'local-id' })] }, { bookmarks: {}, highlights: [hl({ id: 'server-id' })] }); expect(merged.highlights).toHaveLength(1); expect(merged.highlights[0].id).toBe('server-id'); }); test('marksEqual compares by value, not by reference or order', () => { const a = { bookmarks: { x: '#1', y: '#2' }, highlights: [hl({ id: '1' }), hl({ id: '2', verse: 2 })] }; const b = { bookmarks: { y: '#2', x: '#1' }, highlights: [hl({ id: '2', verse: 2 }), hl({ id: '1' })] }; expect(marksEqual(a, b)).toBe(true); expect(marksEqual(a, { ...b, bookmarks: { ...b.bookmarks, x: '#9' } })).toBe(false); expect(marksEqual(a, { ...b, highlights: [hl({ id: '1' })] })).toBe(false); expect(marksEqual(a, { ...b, highlights: [hl({ id: '1', color: '#000000' }), hl({ id: '2', verse: 2 })] })).toBe(false); });