/** * Destroy with "keep children": only the object goes, its children move up to its parent and come * out of the node as a list – the nearest level only. Its behaviors go with it. */ import { describe, expect, it } from 'vitest'; import { CreateAssetCommand } from '../../src/core/commands/assetCommands'; import { graphEditor, makeBehavior, makeSpriteScene, place, startWorld, type SceneFixture } from '../helpers'; function sprite(f: SceneFixture, name: string): string { const command = new CreateAssetCommand('sprite', name); f.stack.execute(command); return command.asset.id; } /** Shelf › Crate › (Lid › Nail, Label, Breaker); the breaker destroys its owner on start and logs the list. */ function scene(keepChildren: boolean) { const f = makeSpriteScene('Crate'); const shelf = place(f, sprite(f, 'Shelf'), { x: 0, y: 0 }); const crate = place(f, f.spriteId, { x: 40, y: 0 }, shelf); const lid = place(f, sprite(f, 'Lid'), { x: 40, y: 10 }, crate); const nail = place(f, sprite(f, 'Nail'), { x: 40, y: 20 }, lid); place(f, sprite(f, 'Label'), { x: 40, y: -10 }, crate); const behavior = makeBehavior(f, 'Breaker'); const edit = graphEditor(f, behavior); const start = edit.addNode('OnStart'); const owner = edit.addNode('Owner'); const destroy = edit.addNode('Destroy', { keepChildren }); const log = edit.addNode('Log'); edit.wire([ [start, 'exec', destroy, 'exec'], [owner, 'object', destroy, 'object'], [destroy, 'exec', log, 'exec'], [destroy, 'children', log, 'message'], ]); const breaker = place(f, behavior.id, { x: 40, y: 0 }, crate); const run = startWorld(f, { behaviors: true }); run.frame(); return { world: run.world, shelf, crate, lid, nail, breaker }; } describe('Destroy with keep children', () => { it('removes only the object and answers its children, now below its parent', () => { const { world, shelf, crate, lid, nail, breaker } = scene(true); expect(world.findByObjectId(crate)).toBeUndefined(); expect(world.findByObjectId(breaker)).toBeUndefined(); expect(world.findByObjectId(lid)?.parent).toBe(world.findByObjectId(shelf)); expect(world.findByObjectId(nail)?.parent).toBe(world.findByObjectId(lid)); // Both children of the crate, the nail stays below the lid. expect(world.log).toEqual(['Lid, Label']); }); it('still takes everything below along without it, and answers no children', () => { const { world, shelf, lid, nail } = scene(false); expect(world.findByObjectId(lid)).toBeUndefined(); expect(world.findByObjectId(nail)).toBeUndefined(); expect(world.findByObjectId(shelf)).toBeDefined(); expect(world.log).toEqual(['']); }); });