/**
* A row lighting up where an asset is listed, without being selected (#221, Unity's ping). The row
* itself needs text measurement, which Node lacks – e2e 28l-ii looks at it in the browser.
*/
import { describe, expect, it } from 'vitest';
import { EditorState } from '../../src/editor/state';
import { type ListItem, PING_MS, pingAlpha, sameListItem } from '../../src/ui/widgets/ListView';
describe('pingAlpha', () => {
it('holds full for the first fifth, then fades to nothing at PING_MS', () => {
const full = pingAlpha(0);
expect(full).toBeGreaterThan(0);
expect(pingAlpha(PING_MS / 5)).toBe(full);
expect(pingAlpha(PING_MS * 0.6)).toBeCloseTo(full / 2);
expect(pingAlpha(PING_MS * 0.9)).toBeLessThan(pingAlpha(PING_MS * 0.6));
expect(pingAlpha(PING_MS)).toBe(0);
expect(pingAlpha(-1)).toBe(0);
});
});
describe('sameListItem (#347)', () => {
it('keeps a row only while everything it draws is the same', () => {
const row: ListItem = { id: 'a', label: 'Crate', hint: '2', depth: 1, icon: '', marks: [''] };
expect(sameListItem(row, { ...row, marks: [''] })).toBe(true);
expect(
sameListItem({ id: 'a', label: 'Crate' }, { id: 'a', label: 'Crate', depth: 0, overridden: false }),
).toBe(true);
const changes: Partial[] = [
{ id: 'b' },
{ label: 'Box' },
{ hint: '3' },
{ depth: 2 },
{ expanded: true },
{ overridden: true },
{ icon: '' },
{ iconAtEnd: true },
{ heading: true },
{ marks: [] },
{ marks: [''] },
];
for (const change of changes) expect(sameListItem(row, { ...row, ...change })).toBe(false);
});
});
describe('EditorState.pingAsset', () => {
it('names the asset and tells the listeners, but leaves the selection alone', () => {
const state = new EditorState();
state.select({ kind: 'asset', assetId: 'sprite' });
const heard: string[] = [];
state.on('ping', () => heard.push(state.pingedAssetId ?? ''));
state.on('selection', () => heard.push('selection'));
state.on('open', () => heard.push('open'));
state.pingAsset('texture');
expect(heard).toEqual(['texture']);
expect(state.selection).toEqual({ kind: 'asset', assetId: 'sprite' });
});
});