/** The label of a reference row as a link to the asset it names (#221). */ import type { FederatedPointerEvent } from 'pixi.js'; import { describe, expect, it } from 'vitest'; import { CreateAssetCommand } from '../../src/core/commands/assetCommands'; import type { PropertyValue } from '../../src/core/model/Properties'; import type { PropertyDef } from '../../src/core/properties/PropertySchema'; import { createFieldRow, type FieldContext, type FieldRow, READ_ONLY, } from '../../src/editor/inspector/fieldFactory'; import type { Label } from '../../src/ui'; import { makeProject } from '../helpers'; const SHADER: PropertyDef = { key: 'shader', label: 'Shader', kind: 'asset', default: '', assetTypes: ['shader'], }; interface Built { row: FieldRow; label: Label; press(button?: number): void; followed: string[]; shaderId: string; } /** * Builds the row, runs the checks and destroys it before returning: widgets repaint in a microtask, * and text cannot be measured without a document. The value `'shader'` stands for the shader's id. */ function withRow(value: PropertyValue, follows: boolean, checks: (b: Built) => void): void { const fixture = makeProject(); const shader = new CreateAssetCommand('shader', 'Glow'); fixture.stack.execute(shader); const followed: string[] = []; const ctx: FieldContext = { project: () => fixture.project, ...(follows ? { followReference: (assetId: string) => void followed.push(assetId) } : {}), }; const row = createFieldRow(ctx, SHADER, value === 'shader' ? shader.asset.id : value, READ_ONLY); const label = row.row.children[0] as Label; const press = (button = 0) => label.emit('pointerdown', { button } as FederatedPointerEvent); try { checks({ row, label, press, followed, shaderId: shader.asset.id }); } finally { row.row.destroy({ children: true }); } } describe('a reference row label', () => { it('is a link while the row names an asset, and a press follows it', () => { withRow('shader', true, (b) => { expect(b.label.underlined).toBe(true); expect(b.label.eventMode).toBe('static'); b.press(); expect(b.followed).toEqual([b.shaderId]); }); }); it('follows nothing on another button', () => { withRow('shader', true, (b) => { b.press(2); expect(b.followed).toEqual([]); }); }); it('is plain text while the row names nothing, and becomes a link once it does', () => { withRow('', true, (b) => { expect(b.label.underlined).toBe(false); expect(b.label.eventMode).toBe('none'); b.row.setValue(b.shaderId); expect(b.label.underlined).toBe(true); b.row.setValue('gone'); expect(b.label.underlined).toBe(false); }); }); it('stays plain text where nobody can follow it', () => { withRow('shader', false, (b) => { expect(b.label.underlined).toBe(false); expect(b.label.eventMode).toBe('none'); }); }); });