1 Commits
Author SHA1 Message Date
sneak 8009a46cc9 test: tighten two checks in the persisted-field harness (closes #379)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s
The polarity check now counts only `hostile` and `falsy` values, not a
`hostileRestore` value, which reaches only the views its entry names.
The stale index 5 moves into `hostile` for `selectedWallet` and
`selectedAddress`, as each field's one value still truthy after the
floor.

Each `hostileRestore` entry declares whether its boot lands on its view
or falls back to Home, and the test checks the one view on screen. A
value driven onto every restorable view lists only the views it falls
back on, so a view added later is driven by default.

The header and the README restate the remaining limits as built and say
which boots are held to where the popup lands.

Model: opus-5-5
2026-10-07 08:52:40 +00:00
+42 -63
View File
@@ -146,8 +146,8 @@ const sweptValues = (row) => [...row.hostile, ...(row.falsy || [])];
// particular branch's gate has let it past. Each of its entries names the // particular branch's gate has let it past. Each of its entries names the
// `views` it is driven onto and declares whether the boot lands on them // `views` it is driven onto and declares whether the boot lands on them
// (`restored: true`) or falls back to Home (`restored: false`), so a value // (`restored: true`) or falls back to Home (`restored: false`), so a value
// written for one renderer cannot stop reaching it unnoticed. A value that // written for one renderer cannot stop reaching it unnoticed. A value driven
// lands on some views and not others is one entry per outcome. // onto every restorable view is written with everyRestorableView() below.
// //
// `falsy` is the other POLARITY of a swept field, driven for the same reason. // `falsy` is the other POLARITY of a swept field, driven for the same reason.
// It is not a value src/ never writes — for three of these fields it is the // It is not a value src/ never writes — for three of these fields it is the
@@ -158,6 +158,23 @@ const sweptValues = (row) => [...row.hostile, ...(row.falsy || [])];
// falsy value stored under that field comes back TRUTHY from the floor, so no // falsy value stored under that field comes back TRUTHY from the floor, so no
// `!state.x` branch is reachable from a stored record at all. // `!state.x` branch is reachable from a stored record at all.
// The `hostileRestore` entries for a value driven onto every restorable view:
// it falls back to Home on the views listed in `fallsBackOn` and lands on every
// other one, so a view added to RESTORABLE_VIEWS is driven, and expected to
// land, without editing the row.
function everyRestorableView(value, fallsBackOn) {
return [
{ value, views: fallsBackOn, restored: false },
{
value,
views: [...RESTORABLE_VIEWS].filter(
(view) => !fallsBackOn.includes(view),
),
restored: true,
},
];
}
const CONTRACT = [ const CONTRACT = [
{ {
field: "wallets", field: "wallets",
@@ -312,32 +329,14 @@ const CONTRACT = [
routes: true, routes: true,
// Comes back from the floor as null, which hasValidAddress() reads as // Comes back from the floor as null, which hasValidAddress() reads as
// nothing selected: the popup falls back to Home on the five views // nothing selected: the popup falls back to Home on the five views
// that need an address, and lands on the other six. // that need an address, and lands on every other one.
hostileRestore: [ hostileRestore: everyRestorableView("length", [
{
value: "length",
views: [
"address", "address",
"address-token", "address-token",
"receive", "receive",
"transaction", "transaction",
"confirm-tx", "confirm-tx",
], ]),
restored: false,
},
{
value: "length",
views: [
"main",
"settings",
"settings-addtoken",
"wait-tx",
"success-tx",
"error-tx",
],
restored: true,
},
],
}, },
{ {
field: "selectedAddress", field: "selectedAddress",
@@ -469,44 +468,25 @@ const CONTRACT = [
}, },
// A record that passes EVERY branch's gate at once, driven onto // A record that passes EVERY branch's gate at once, driven onto
// every restorable view: a branch a view does not read must stay // every restorable view: a branch a view does not read must stay
// one it does not read. The six views with no viewData branch // one it does not read. The five views with a viewData branch
// render it, and must survive the fields every branch left behind; // refuse it; every other one renders it, and must survive the
// on the five that have one, the guard refuses it. // fields every branch left behind.
...everyRestorableView(
{ {
value: {
hash: "0x1", hash: "0x1",
message: "boom", message: "boom",
tx: { hash: "0x1" }, tx: { hash: "0x1" },
pendingTx: { amount: "1" }, pendingTx: { amount: "1" },
pendingWait: { hash: "0x1" }, pendingWait: { hash: "0x1" },
}, },
views: [ [
"main",
"address",
"address-token",
"receive",
"settings",
"settings-addtoken",
],
restored: true,
},
{
value: {
hash: "0x1",
message: "boom",
tx: { hash: "0x1" },
pendingTx: { amount: "1" },
pendingWait: { hash: "0x1" },
},
views: [
"confirm-tx", "confirm-tx",
"transaction", "transaction",
"wait-tx", "wait-tx",
"success-tx", "success-tx",
"error-tx", "error-tx",
], ],
restored: false, ),
},
], ],
}, },
{ {
@@ -810,19 +790,16 @@ function restoringOnto(view, extra) {
// A boot that RESTORED is healthy and landed on the view it stored, rather // A boot that RESTORED is healthy and landed on the view it stored, rather
// than falling back to Home — which a healthy boot also does, and which would // than falling back to Home — which a healthy boot also does, and which would
// let a sweep pass by never running the renderer it is aimed at. `blank` is // let a sweep pass by never running the renderer it is aimed at.
// reported as bootHealth() reports it, so a boot expected to fall back is still
// held to putting something on screen.
async function restoredHealth(profile, view) { async function restoredHealth(profile, view) {
const env = await bootPopup(profile); const env = await bootPopup(profile);
return { return {
errors: env.pageErrors, errors: env.pageErrors,
blank: env.visibleViews().length === 0,
restored: env.visibleViews().includes(view), restored: env.visibleViews().includes(view),
}; };
} }
const RESTORED = { ...HEALTHY, restored: true }; const RESTORED = { errors: [], restored: true };
describe("the base profile the sweep corrupts", () => { describe("the base profile the sweep corrupts", () => {
for (const view of RESTORABLE_VIEWS) { for (const view of RESTORABLE_VIEWS) {
@@ -977,9 +954,10 @@ describe("every field the router does not read, corrupted at once, onto", () =>
// The values that only mean something on the restore path: a viewData that // The values that only mean something on the restore path: a viewData that
// PASSES a branch's gate and then hands its renderer something dereferenced, // PASSES a branch's gate and then hands its renderer something dereferenced,
// and a selectedWallet the floor turns into nothing selected. Each boot is held // and a selectedWallet the floor turns into nothing selected. Each boot must
// to health and to where its entry says it lands, on its view or back on Home, // throw nothing and show exactly the view its entry says it lands on: its own,
// so a value written for one renderer cannot stop reaching it and still pass. // or Home, so a value written for one renderer cannot stop reaching it and
// still pass.
describe("a restore-only hostile value onto", () => { describe("a restore-only hostile value onto", () => {
for (const row of CONTRACT) { for (const row of CONTRACT) {
for (const entry of row.hostileRestore || []) { for (const entry of row.hostileRestore || []) {
@@ -987,14 +965,15 @@ describe("a restore-only hostile value onto", () => {
test(`${view}: ${row.field} = ${JSON.stringify( test(`${view}: ${row.field} = ${JSON.stringify(
entry.value, entry.value,
)}`, async () => { )}`, async () => {
await expect( const env = await bootPopup(
restoredHealth(
restoringOnto(view, { [row.field]: entry.value }), restoringOnto(view, { [row.field]: entry.value }),
view, );
), expect({
).resolves.toEqual({ errors: env.pageErrors,
...HEALTHY, visible: env.visibleViews(),
restored: entry.restored, }).toEqual({
errors: [],
visible: [entry.restored ? view : "main"],
}); });
}); });
} }