Files
feuerwerk/tests/editor/asset-menu.test.ts
T
adminandClaude Opus 5 3b039384c4
game-maker / suite (push) Failing after 10m23s
A search that ignores what a thing is called is no search, so the name wins (#43)
Typing "variable" into the node palette landed on `Run behavior`, because the
filter weighed label, type and description alike and then sorted by category.
`searchRank` in `src/ui/search.ts` now ranks a match: exact label or type, then
prefix, then label, then type, and only last a hit that lives in the
description alone. Category and alphabet order within a rank. The searchable
`Menu` uses the same function, so searching means the same thing everywhere.

The `+` menu grew to fifteen entries in declaration order. It is built in two
alphabetical groups now -- the types that go into a scene, then the ones that
stay in the library -- with a separator between them, the split `isPlaceableType`
already draws. `ASSET_TYPES` itself stays untouched: it is also the
serialisation and check order. A search flattens the groups and drops the lines.

Popups were capped at fixed heights (320 menu, 260 palette, 340 pickers) while
the canvas had room to spare. `Popup.roomFor()` measures its own chrome and
takes the window height minus a tenth at each end. Placement clamps
asymmetrically: the bottom margin is enforced, the top is only a budget, so a
menu anchored near the top stays at its button instead of being pushed off it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:21:20 +02:00

37 lines
1.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import {
ASSET_TYPE_LABELS,
ASSET_TYPES,
type AssetType,
isPlaceableType,
} from '../../src/core/model/AssetTypes';
import { assetMenuGroups } from '../../src/editor/panels/assetMenu';
const labels = (types: AssetType[]) => types.map((type) => ASSET_TYPE_LABELS[type]);
describe('assetMenuGroups', () => {
it('offers every type exactly once', () => {
const flat = assetMenuGroups().flat();
expect([...flat].sort()).toEqual([...ASSET_TYPES].sort());
});
it('splits into placeable first, library second (#43)', () => {
const [placeable, library] = assetMenuGroups();
expect(placeable!.every(isPlaceableType)).toBe(true);
expect(library!.some(isPlaceableType)).toBe(false);
});
it('sorts each group by its label, not by declaration order', () => {
for (const group of assetMenuGroups()) {
expect(labels(group)).toEqual([...labels(group)].sort());
}
// Declaration order starts with Scene, which is not placeable and no longer leads the menu.
expect(assetMenuGroups()[0]![0]).not.toBe('scene');
});
it('leaves ASSET_TYPES alone – it is also the serialisation order', () => {
assetMenuGroups();
expect(ASSET_TYPES[0]).toBe('scene');
});
});