import { describe, expect, it } from 'vitest'; import { CreateAssetCommand } from '../../src/core/commands/assetCommands'; import { CreateContainerCommand } from '../../src/core/commands/containerCommands'; import type { ContainerAsset } from '../../src/core/model/Asset'; import { placementRejection } from '../../src/core/model/placement'; import { findAsset, findObjectHolder, findScene } from '../../src/core/model/Project'; import { makeSpriteScene, place } from '../helpers'; describe('placementRejection', () => { it('lets a sprite into a scene', () => { const f = makeSpriteScene(); const scene = findScene(f.project, f.sceneId)!; const sprite = findAsset(f.project, f.spriteId)!; expect(placementRejection(f.project, scene, sprite)).toBe(''); }); it('refuses a scene: a scene is not something a scene can hold', () => { const f = makeSpriteScene(); const scene = findScene(f.project, f.sceneId)!; expect(placementRejection(f.project, scene, scene)).toMatch(/cannot be placed/); }); it('refuses a container that would end up inside itself', () => { const f = makeSpriteScene(); const a = place(f, f.spriteId, { x: 0, y: 0 }); const create = new CreateContainerCommand(f.sceneId, [a]); f.stack.execute(create); const container = findAsset(f.project, create.assetId) as ContainerAsset; const template = findObjectHolder(f.project, create.assetId)!; expect(placementRejection(f.project, template, container)).toMatch(/nests forever/); // The same container in a scene is fine – only its own template nests. expect(placementRejection(f.project, findScene(f.project, f.sceneId)!, container)).toBe(''); }); it('refuses a container whose template already reaches the target, however deeply', () => { const f = makeSpriteScene(); const inner = new CreateContainerCommand(f.sceneId, [place(f, f.spriteId, { x: 0, y: 0 })]); f.stack.execute(inner); // An outer container built from the object that holds the inner one. const outer = new CreateContainerCommand(f.sceneId, [inner.objectId]); f.stack.execute(outer); const outerAsset = findAsset(f.project, outer.assetId) as ContainerAsset; const innerTemplate = findObjectHolder(f.project, inner.assetId)!; expect(placementRejection(f.project, innerTemplate, outerAsset)).toMatch(/nests forever/); }); it('does not care what an asset is called: a fresh sprite is placeable', () => { const f = makeSpriteScene(); const created = new CreateAssetCommand('text', 'Label'); f.stack.execute(created); const scene = findScene(f.project, f.sceneId)!; expect(placementRejection(f.project, scene, created.asset)).toBe(''); }); });