import { describe, expect, it } from 'vitest'; import type { TTSMod, TTSObject } from '@tts/shared'; import { buildTree, filterObjects, findObject, flattenObjects, } from './objects.js'; function card(guid: string, name = 'Card'): TTSObject { return { Name: name, GUID: guid, Description: '' }; } function bag(guid: string, contained: TTSObject[]): TTSObject { return { Name: 'Bag', GUID: guid, Description: '', ContainedObjects: contained }; } const mod: TTSMod = { GameMode: 'Tabletop', Date: '2024-01-01', ObjectStates: [ card('a', 'Deck'), bag('b', [card('c', 'Card'), card('d', 'Token')]), card('e', 'Deck'), ], }; describe('flattenObjects', () => { it('returns every object including containers and those inside them', () => { const guids = flattenObjects(mod).map((o) => o.GUID); expect(guids).toEqual(['a', 'b', 'c', 'd', 'e']); }); it('sets Parent links before returning', () => { const [a, b, c] = flattenObjects(mod); expect(a!.Parent).toBeUndefined(); expect(b!.Parent).toBeUndefined(); expect(c!.Parent!.GUID).toBe('b'); }); }); describe('filterObjects', () => { it('filters by predicate', () => { const decks = filterObjects(mod, (o) => o.Name === 'Deck'); expect(decks.map((o) => o.GUID)).toEqual(['a', 'e']); }); }); describe('findObject', () => { it('finds an object by GUID', () => { expect(findObject(mod, 'd')?.Name).toBe('Token'); }); it('returns undefined for a missing GUID', () => { expect(findObject(mod, 'zzz')).toBeUndefined(); }); }); describe('buildTree', () => { it('mirrors the containment hierarchy', () => { const tree = buildTree(mod); expect(tree.map((n) => n.object.GUID)).toEqual(['a', 'b', 'e']); expect(tree[1]!.children.map((n) => n.object.GUID)).toEqual(['c', 'd']); }); it('uses Nickname as the label when present', () => { const named = { ...card('n', 'Card'), Nickname: 'Ace of Spades', }; const tree = buildTree({ ...mod, ObjectStates: [named] }); expect(tree[0]!.label).toBe('Ace of Spades'); }); it('falls back to the class Name as the label', () => { const tree = buildTree(mod); expect(tree[0]!.label).toBe('Deck'); }); });