Keep edited list values when an item is deleted (#235)
The list tab read the list once when it built its rows. Editing a value does not rebuild the rows, so the delete button later filtered that old copy and wrote it back. Every edit since the last rebuild was lost. Adding an item only triggered it, because adding rebuilds the rows and that state became the old copy. - ListAccess.value in src/editor/list/slot.ts is now read on every access instead of once when the access is built. - The kind switch of a row and the struct field buttons (field type, rename, remove field, + Field) read the item when clicked, not when the row was built. They had the same stale copy. - New test hook __gm.list.removeAt(i) clicks the delete button of one row, because the tab shows many buttons with the same label. Not covered by a test of their own: the struct field buttons and the kind switch after an edit. The cause is the same, the fix is in code. Tests: - ./check.sh: 2435 tests, CHECK EXIT 0. - Unit test in tests/editor/list-slot.test.ts keeps one access, edits a value, adds and edits an item, deletes another. All edits stay. It fails without the fix. - e2e 21b-ii with real clicks: set row 2 to 66, delete row 0, expect ["11","66"], two undos take both back. e2e 21: 52 checks passed. - Counter probe: with the old snapshot the check fails with ["11","44"], the reported bug. - Check total in README is now 1400 (+2), counted, not measured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1d18862ed6
commit
085e6c8cce
6 files changed
+64
-9
No files matched your search
@@ -57,6 +57,30 @@ export async function listTab(t) {
|
||||
info = await json('__gm.list.info()');
|
||||
check('undo takes just that item back', JSON.stringify(info.items) === '["30","11","44"]', info.items[1]);
|
||||
|
||||
// 21b-ii. An item edit does not rebuild the rows, so a delete clicked after it must build on the
|
||||
// edited list – with the one the rows were built from, the edit came back undone (#235).
|
||||
const edited = await json('__gm.list.fieldAt(2)');
|
||||
await click(edited.x, edited.y);
|
||||
await typeText('66');
|
||||
await press('Enter');
|
||||
const removeFirst = await json('__gm.list.removeAt(0)');
|
||||
await click(removeFirst.x, removeFirst.y);
|
||||
await sleep(200);
|
||||
info = await json('__gm.list.info()');
|
||||
check(
|
||||
'deleting a row keeps an edit made to another row before',
|
||||
JSON.stringify(info.items) === '["11","66"]',
|
||||
JSON.stringify(info.items),
|
||||
);
|
||||
await undo();
|
||||
await undo();
|
||||
info = await json('__gm.list.info()');
|
||||
check(
|
||||
'and two undos take delete and edit back',
|
||||
JSON.stringify(info.items) === '["30","11","44"]',
|
||||
info.items,
|
||||
);
|
||||
|
||||
// 21c. A short list opened after a long one. Its rows leave the content height pinned to the
|
||||
// viewport, so a layout skipped on "same size" would stack them all at the top.
|
||||
await mutate(`
|
||||
|
||||
Reference in new issue
Block a user