import { describe, expect, it } from 'vitest'; import type { TTSMod, TTSObject } from '@tts/shared'; import { markParent, traverseMod } from './traverse.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'), bag('b', [card('c'), bag('d', [card('e')])]), card('f'), ], }; describe('markParent', () => { it('sets Parent on direct children', () => { const root = bag('b', [card('c')]); markParent(root); expect(root.ContainedObjects![0]!.Parent).toBe(root); }); it('sets Parent recursively', () => { const root = bag('b', [bag('d', [card('e')])]); markParent(root); const d = root.ContainedObjects![0]!; expect(d.Parent).toBe(root); expect(d.ContainedObjects![0]!.Parent).toBe(d); }); it('leaves leaf objects untouched', () => { const leaf = card('a'); markParent(leaf); expect(leaf.Parent).toBeUndefined(); }); }); describe('traverseMod', () => { it('yields every object including containers, in order', () => { const guids = [...traverseMod(mod)].map((o) => o.GUID); expect(guids).toEqual(['a', 'b', 'c', 'd', 'e', 'f']); }); it('descends into nested bags', () => { const guids = [...traverseMod(mod)].map((o) => o.GUID); expect(guids).toContain('e'); }); it('descends into any object with ContainedObjects', () => { const custom = { Name: 'Custom_Model', GUID: 'x', Description: '', ContainedObjects: [card('y')] }; const guids = [...traverseMod(custom)].map((o) => o.GUID); expect(guids).toEqual(['x', 'y']); }); it('accepts a single object', () => { const guids = [...traverseMod(bag('b', [card('c')]))].map((o) => o.GUID); expect(guids).toEqual(['b', 'c']); }); });