/// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2024-2025 Tony Garnock-Jones import { describe, it, expect } from 'vitest'; import { getSortKey, setSortKey, findInsertionPoint } from '../src/sortedNodes'; describe('sorted nodes', () => { class FakeNode { text: string; childNodes: Array = []; dataset: { [key: string]: string } = {}; constructor(text: any) { this.text = '' + text; } insertBefore(k: Node, sib: ChildNode | null) { if (sib !== null) { for (let i = 0; i < this.childNodes.length; i++) { if (this.childNodes[i] === sib) { this.childNodes.splice(i, 0, k); return; } } } this.childNodes.push(k); } } function ins(n: Node, k: Node) { const sib = findInsertionPoint(n, getSortKey(k)!); n.insertBefore(k, sib); } function mk(i: any) { const n = new FakeNode(i) as unknown as Node; setSortKey(n, i); return n; } it('with integer keys', () => { const n = new FakeNode('parent') as unknown as Node; ins(n, mk(3)); ins(n, mk(1)); ins(n, mk(4)); ins(n, mk(1)); ins(n, mk(0)); ins(n, mk(5)); ins(n, mk(9)); ins(n, mk(2)); ins(n, mk(6)); expect(Array.from(n.childNodes).map(n => (n as unknown as FakeNode).text).join(',')).toBe( '0,1,1,2,3,4,5,6,9'); }); it('with negative integer keys', () => { const n = new FakeNode('parent') as unknown as Node; ins(n, mk(-3)); ins(n, mk(-1)); ins(n, mk(-4)); ins(n, mk(-1)); ins(n, mk(-0)); ins(n, mk(-5)); ins(n, mk(-9)); ins(n, mk(-2)); ins(n, mk(-6)); expect(Array.from(n.childNodes).map(n => (n as unknown as FakeNode).text).join(',')).toBe( '-9,-6,-5,-4,-3,-2,-1,-1,0'); }); it('with negative integer keys (ascending)', () => { const n = new FakeNode('parent') as unknown as Node; ins(n, mk(-0)); ins(n, mk(-1)); ins(n, mk(-2)); ins(n, mk(-3)); expect(Array.from(n.childNodes).map(n => (n as unknown as FakeNode).text).join(',')).toBe( '-3,-2,-1,0'); }); it('with string keys', () => { const n = new FakeNode('parent') as unknown as Node; ins(n, mk("c")); ins(n, mk("a")); ins(n, mk("d")); ins(n, mk("a")); ins(n, mk("e")); ins(n, mk("i")); ins(n, mk("b")); ins(n, mk("f")); expect(Array.from(n.childNodes).map(n => (n as unknown as FakeNode).text).join(',')).toBe( 'a,a,b,c,d,e,f,i'); }); it('with mixed keys', () => { const n = new FakeNode('parent') as unknown as Node; ins(n, mk("c")); ins(n, mk("a")); ins(n, mk(4)); ins(n, mk(1)); ins(n, mk(5)); ins(n, mk(9)); ins(n, mk("b")); ins(n, mk("f")); expect(Array.from(n.childNodes).map(n => (n as unknown as FakeNode).text).join(',')).toBe( '1,4,5,9,a,b,c,f'); }); it('with mixed keys (2)', () => { const n = new FakeNode('parent') as unknown as Node; ins(n, mk(3)); ins(n, mk(1)); ins(n, mk("d")); ins(n, mk("a")); ins(n, mk("e")); ins(n, mk("i")); ins(n, mk(2)); ins(n, mk(6)); expect(Array.from(n.childNodes).map(n => (n as unknown as FakeNode).text).join(',')).toBe( '1,2,3,6,a,d,e,i'); }); });