111 lines
3.1 KiB
TypeScript
111 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { applyOffsets } from './search';
|
|
|
|
describe('applyOffsets', () => {
|
|
it('returns single plain segment when offsets is empty', () => {
|
|
expect(applyOffsets('Hallo Welt', [])).toEqual([{ text: 'Hallo Welt', highlight: false }]);
|
|
});
|
|
|
|
it('highlights a single term at the start', () => {
|
|
expect(applyOffsets('Brief an Anna', [{ start: 0, length: 5 }])).toEqual([
|
|
{ text: 'Brief', highlight: true },
|
|
{ text: ' an Anna', highlight: false }
|
|
]);
|
|
});
|
|
|
|
it('highlights a term in the middle', () => {
|
|
expect(applyOffsets('Der Brief von Anna', [{ start: 4, length: 5 }])).toEqual([
|
|
{ text: 'Der ', highlight: false },
|
|
{ text: 'Brief', highlight: true },
|
|
{ text: ' von Anna', highlight: false }
|
|
]);
|
|
});
|
|
|
|
it('highlights a term at the end', () => {
|
|
expect(applyOffsets('Brief an Anna', [{ start: 9, length: 4 }])).toEqual([
|
|
{ text: 'Brief an ', highlight: false },
|
|
{ text: 'Anna', highlight: true }
|
|
]);
|
|
});
|
|
|
|
it('handles two non-overlapping offsets in order', () => {
|
|
expect(
|
|
applyOffsets('Anna und Brief', [
|
|
{ start: 0, length: 4 },
|
|
{ start: 9, length: 5 }
|
|
])
|
|
).toEqual([
|
|
{ text: 'Anna', highlight: true },
|
|
{ text: ' und ', highlight: false },
|
|
{ text: 'Brief', highlight: true }
|
|
]);
|
|
});
|
|
|
|
it('merges overlapping offsets into the longest span', () => {
|
|
// [0,7) and [3,9) overlap → merged [0,max(7,9)) = [0,9) = "Hello wor"
|
|
expect(
|
|
applyOffsets('Hello world', [
|
|
{ start: 0, length: 7 },
|
|
{ start: 3, length: 6 }
|
|
])
|
|
).toEqual([
|
|
{ text: 'Hello wor', highlight: true },
|
|
{ text: 'ld', highlight: false }
|
|
]);
|
|
});
|
|
|
|
it('merges adjacent (touching) offsets', () => {
|
|
// [0,3) and [3,6) are adjacent → merged [0,6)
|
|
expect(
|
|
applyOffsets('Hallo Welt', [
|
|
{ start: 0, length: 3 },
|
|
{ start: 3, length: 3 }
|
|
])
|
|
).toEqual([
|
|
{ text: 'Hallo ', highlight: true },
|
|
{ text: 'Welt', highlight: false }
|
|
]);
|
|
});
|
|
|
|
it('clamps offset that extends beyond text length', () => {
|
|
expect(applyOffsets('Hi', [{ start: 0, length: 100 }])).toEqual([
|
|
{ text: 'Hi', highlight: true }
|
|
]);
|
|
});
|
|
|
|
it('ignores a completely out-of-bounds offset', () => {
|
|
expect(applyOffsets('Hi', [{ start: 10, length: 5 }])).toEqual([
|
|
{ text: 'Hi', highlight: false }
|
|
]);
|
|
});
|
|
|
|
it('sorts unsorted offsets correctly', () => {
|
|
// Offsets provided in reverse order: second term first
|
|
expect(
|
|
applyOffsets('Anna und Brief', [
|
|
{ start: 9, length: 5 },
|
|
{ start: 0, length: 4 }
|
|
])
|
|
).toEqual([
|
|
{ text: 'Anna', highlight: true },
|
|
{ text: ' und ', highlight: false },
|
|
{ text: 'Brief', highlight: true }
|
|
]);
|
|
});
|
|
|
|
it('clamps negative start to 0 and highlights from the beginning', () => {
|
|
// start = -2, length = 5 → effective range [-2, 3) → clamped to [0, 3)
|
|
expect(applyOffsets('Hello', [{ start: -2, length: 5 }])).toEqual([
|
|
{ text: 'Hel', highlight: true },
|
|
{ text: 'lo', highlight: false }
|
|
]);
|
|
});
|
|
|
|
it('ignores offset whose end is also negative', () => {
|
|
// start = -5, length = 2 → end = -3, completely before text
|
|
expect(applyOffsets('Hi', [{ start: -5, length: 2 }])).toEqual([
|
|
{ text: 'Hi', highlight: false }
|
|
]);
|
|
});
|
|
});
|