/** Which asset a reference field points at – what "Open texture" and the inspector link open (#221). */ import { describe, expect, it } from 'vitest'; import { CreateAssetCommand, CreateTextureCommand } from '../../src/core/commands/assetCommands'; import { AddFrameCommand } from '../../src/core/commands/frameCommands'; import type { PixelArtAsset } from '../../src/core/model/Asset'; import { findAsset } from '../../src/core/model/Project'; import { type PropertyDef, schemaForAsset } from '../../src/core/properties/PropertySchema'; import { referencedAssetId, referencesOf } from '../../src/core/properties/references'; import { resolveAssetProps } from '../../src/core/properties/resolve'; import { SHADER_KEY } from '../../src/core/properties/shaders'; import { makeSpriteScene } from '../helpers'; const FILE = `${'ab'.repeat(32)}.png`; const TEXTURE: PropertyDef = { key: 'texture', label: 'Texture', kind: 'texture', default: '' }; const SHADER: PropertyDef = { key: SHADER_KEY, label: 'Shader', kind: 'asset', default: '', assetTypes: ['shader'], }; function setup() { const fixture = makeSpriteScene(); const texture = new CreateTextureCommand('Sheet', { file: FILE, width: 64, height: 32 }); fixture.stack.execute(texture); const frame = new AddFrameCommand(texture.asset.id, { x: 0, y: 0, w: 16, h: 16 }, 'Idle'); fixture.stack.execute(frame); const shader = new CreateAssetCommand('shader', 'Glow'); fixture.stack.execute(shader); const art = new CreateAssetCommand('pixelart', 'Art'); fixture.stack.execute(art); return { ...fixture, textureId: texture.asset.id, frameId: frame.frameId, shaderId: shader.asset.id, art: art.asset as PixelArtAsset, }; } describe('referencedAssetId', () => { it('is the asset a reference names', () => { const f = setup(); expect(referencedAssetId(f.project, TEXTURE, f.textureId)).toBe(f.textureId); expect(referencedAssetId(f.project, SHADER, f.shaderId)).toBe(f.shaderId); }); it('is the sheet for a frame of a texture or of pixel art', () => { const f = setup(); expect(referencedAssetId(f.project, TEXTURE, f.frameId)).toBe(f.textureId); f.art.frames.push({ id: 'second', cels: {} }); expect(referencedAssetId(f.project, TEXTURE, 'second')).toBe(f.art.id); }); it('is nothing for an empty or dangling reference', () => { const f = setup(); expect(referencedAssetId(f.project, TEXTURE, '')).toBeNull(); expect(referencedAssetId(f.project, SHADER, 'gone')).toBeNull(); }); it('only resolves frames in a texture field', () => { const f = setup(); expect(referencedAssetId(f.project, SHADER, f.frameId)).toBeNull(); }); it('is nothing for a field that names no asset, whatever it holds', () => { const f = setup(); const text: PropertyDef = { key: 'name', label: 'Name', kind: 'text', default: '' }; expect(referencedAssetId(f.project, text, f.textureId)).toBeNull(); }); }); describe('referencesOf', () => { it("lists a sprite asset's texture and shader in schema order, and nothing unset", () => { const f = setup(); const sprite = findAsset(f.project, f.spriteId)!; const refs = () => referencesOf(f.project, schemaForAsset(f.project, sprite), resolveAssetProps(f.project, sprite)); sprite.props.texture = ''; expect(refs()).toEqual([]); sprite.props[SHADER_KEY] = f.shaderId; sprite.props.texture = f.frameId; expect(refs()).toEqual([ { label: 'Texture', assetId: f.textureId }, { label: 'Shader', assetId: f.shaderId }, ]); }); });