Pixi only fills `detail` on the `click` event it synthesises; on `pointerdown` it is always 0, so every `e.detail === 2` branch was dead code. Asset rows, hierarchy folding and select-all in text fields never responded to a double-click. A shared click counter in src/ui/clicks.ts replaces the three readings of `e.detail`. A finished double-click ends the run, so two in a row count 2 and 2 rather than 3 and 4. The harness could only send `clickCount: 1`, which is why no test caught this: every "activate" check went through Enter. It can send real double-clicks now, and five checks drive the three paths separately.
61 lines
2.4 KiB
JavaScript
61 lines
2.4 KiB
JavaScript
import { same } from '../lib/harness.mjs';
|
||
|
||
/**
|
||
* Hierarchy folding. A freshly opened scene is fully collapsed, so only its top-level objects
|
||
* are listed (o4/oc1 hang under o1, oc2 under o2). The chevron folds a row open and shut
|
||
* without touching the selection, and selecting a nested object unfolds the way down to it.
|
||
*/
|
||
export async function hierarchy(t) {
|
||
const { check, sleep, evaluate, json, click, doubleClick, select, state, shot } = t;
|
||
const rowIds = () => json('__gm.hierarchyOrder()');
|
||
const rows = async () => JSON.stringify(await rowIds());
|
||
const selectionBefore = (await state()).selection;
|
||
|
||
check(
|
||
'hierarchy starts collapsed – only top-level objects are listed',
|
||
same(await rowIds(), ['o1', 'o2', 'o3', 'o5']),
|
||
await rows(),
|
||
);
|
||
check('a leaf row offers no chevron', (await evaluate(`__gm.hierarchyChevron('o3')`)) === null);
|
||
const chevron = await json(`__gm.hierarchyChevron('o2')`);
|
||
await click(chevron.x, chevron.y);
|
||
check(
|
||
'clicking the chevron unfolds the row, leaving the selection alone',
|
||
same(await rowIds(), ['o1', 'o2', 'oc2', 'o3', 'o5']) && same((await state()).selection, selectionBefore),
|
||
await rows(),
|
||
);
|
||
await shot('01a-hierarchy-unfolded');
|
||
await click(chevron.x, chevron.y);
|
||
check(
|
||
'clicking it again folds the subtree away',
|
||
same(await rowIds(), ['o1', 'o2', 'o3', 'o5']),
|
||
await rows(),
|
||
);
|
||
// The row itself folds on a double-click, the same as its chevron. Pixi leaves `detail` at 0 on
|
||
// a press, so this needs a real double-click from the harness, not two `click()` calls.
|
||
const row = await json(`__gm.hierarchyRow('o2')`);
|
||
await doubleClick(row.x, row.y);
|
||
check(
|
||
'double-clicking the row unfolds it as well',
|
||
same(await rowIds(), ['o1', 'o2', 'oc2', 'o3', 'o5']),
|
||
await rows(),
|
||
);
|
||
await doubleClick(row.x, row.y);
|
||
check(
|
||
'double-clicking it again folds the subtree away',
|
||
same(await rowIds(), ['o1', 'o2', 'o3', 'o5']),
|
||
await rows(),
|
||
);
|
||
|
||
await select({ kind: 'object', holderId: 'scene1', objectId: 'oc1' });
|
||
await sleep(150);
|
||
check(
|
||
'selecting a nested object unfolds its ancestors',
|
||
same(await rowIds(), ['o1', 'o4', 'oc1', 'o2', 'o3', 'o5']),
|
||
await rows(),
|
||
);
|
||
await evaluate('__gm.state.select(null); __gm.hierarchyCollapseAll()');
|
||
await sleep(150);
|
||
check('Collapse all folds everything back', same(await rowIds(), ['o1', 'o2', 'o3', 'o5']), await rows());
|
||
}
|