Team Ai
Modelpublic

Felipe97/llama-cpp-compiled

sourceHugging Faceupdated 21d agoView on Hugging Face
0likes1.2kdownloads
branching.test.ts96 linesDownload Raw Back to unit
1// Sibling-info correctness for buildSiblingInfoMap, including the memoized2// leaf resolution. A wrong leaf id here breaks branch navigation, so the3// deep-chain and multi-branch cases below pin the resolution down.4 5import { MessageRole, MessageType } from '$lib/enums';6import type { DatabaseMessage } from '$lib/types/database';7import { buildSiblingInfoMap, findLeafNode } from '$lib/utils/branching';8import { describe, expect, it } from 'vitest';9 10function msg(id: string, parent: string | null, children: string[] = []): DatabaseMessage {11	return {12		children,13		content: '',14		convId: 'c1',15		id,16		parent,17		role: MessageRole.USER,18		timestamp: 0,19		type: MessageType.TEXT20	} as DatabaseMessage;21}22 23/** root -> m1 -> ... -> m depth, each node with a single child. */24function linearChain(depth: number): DatabaseMessage[] {25	const messages = [msg('m0', null, ['m1'])];26 27	for (let i = 1; i <= depth; i++) {28		messages.push(msg(`m${i}`, `m${i - 1}`, i < depth ? [`m${i + 1}`] : []));29	}30 31	return messages;32}33 34describe('buildSiblingInfoMap', () => {35	it('resolves the deepest leaf for every node of a long single chain', () => {36		const messages = linearChain(50);37		const map = buildSiblingInfoMap(messages);38		const leafId = messages[messages.length - 1].id;39 40		// every non-root message of the chain is an only child, and its41		// navigation target is the chain's deepest leaf42		for (const m of messages.slice(1)) {43			const info = map.get(m.id);44 45			expect(info?.totalSiblings).toBe(1);46			expect(info?.siblingIds).toEqual([leafId]);47		}48	});49 50	it('reports sibling position and leaf targets on a branched tree', () => {51		// m0 -> m1, m4 ; m1 -> m2 ; m2 -> m3, m6 ; m4 -> m552		const root = msg('m0', null, ['m1', 'm4']);53		const m1 = msg('m1', 'm0', ['m2']);54		const m2 = msg('m2', 'm1', ['m3', 'm6']);55		const m3 = msg('m3', 'm2');56		const m4 = msg('m4', 'm0', ['m5']);57		const m5 = msg('m5', 'm4');58		const m6 = msg('m6', 'm2');59		const map = buildSiblingInfoMap([root, m1, m2, m3, m4, m5, m6]);60 61		// m1 and m4 share the root as parent; their nav targets are the62		// leaves of their subtrees ( m6 for the first branch, m5 for the second )63		expect(map.get(m1.id)).toMatchObject({64			currentIndex: 0,65			siblingIds: [m6.id, m5.id],66			totalSiblings: 267		});68		expect(map.get(m4.id)).toMatchObject({69			currentIndex: 1,70			siblingIds: [m6.id, m5.id],71			totalSiblings: 272		});73 74		// m3 and m6 are siblings under m2; both are leaves75		expect(map.get(m3.id)?.siblingIds).toEqual([m3.id, m6.id]);76		expect(map.get(m6.id)?.currentIndex).toBe(1);77 78		// the root has no parent and reports itself79		expect(map.get(root.id)).toMatchObject({80			currentIndex: 0,81			siblingIds: [root.id],82			totalSiblings: 183		});84	});85 86	it('agrees with findLeafNode for arbitrary nodes', () => {87		const messages = linearChain(20);88		const leafId = messages[messages.length - 1].id;89 90		// every node of the chain resolves to the deepest leaf91		for (const m of messages) {92			expect(findLeafNode(messages, m.id), `leaf of ${m.id}`).toBe(leafId);93		}94	});95});96