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
+49 -70
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
// `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
// written for one renderer cannot stop reaching it unnoticed. A value that
// lands on some views and not others is one entry per outcome.
// written for one renderer cannot stop reaching it unnoticed. A value driven
// onto every restorable view is written with everyRestorableView() below.
//
// `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
@@ -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
// `!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 = [
{
field: "wallets",
@@ -312,32 +329,14 @@ const CONTRACT = [
routes: true,
// Comes back from the floor as null, which hasValidAddress() reads as
// nothing selected: the popup falls back to Home on the five views
// that need an address, and lands on the other six.
hostileRestore: [
{
value: "length",
views: [
"address",
"address-token",
"receive",
"transaction",
"confirm-tx",
],
restored: false,
},
{
value: "length",
views: [
"main",
"settings",
"settings-addtoken",
"wait-tx",
"success-tx",
"error-tx",
],
restored: true,
},
],
// that need an address, and lands on every other one.
hostileRestore: everyRestorableView("length", [
"address",
"address-token",
"receive",
"transaction",
"confirm-tx",
]),
},
{
field: "selectedAddress",
@@ -469,44 +468,25 @@ const CONTRACT = [
},
// A record that passes EVERY branch's gate at once, driven onto
// every restorable view: a branch a view does not read must stay
// one it does not read. The six views with no viewData branch
// render it, and must survive the fields every branch left behind;
// on the five that have one, the guard refuses it.
{
value: {
// one it does not read. The five views with a viewData branch
// refuse it; every other one renders it, and must survive the
// fields every branch left behind.
...everyRestorableView(
{
hash: "0x1",
message: "boom",
tx: { hash: "0x1" },
pendingTx: { amount: "1" },
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",
"transaction",
"wait-tx",
"success-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
// 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
// reported as bootHealth() reports it, so a boot expected to fall back is still
// held to putting something on screen.
// let a sweep pass by never running the renderer it is aimed at.
async function restoredHealth(profile, view) {
const env = await bootPopup(profile);
return {
errors: env.pageErrors,
blank: env.visibleViews().length === 0,
restored: env.visibleViews().includes(view),
};
}
const RESTORED = { ...HEALTHY, restored: true };
const RESTORED = { errors: [], restored: true };
describe("the base profile the sweep corrupts", () => {
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
// 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
// to health and to where its entry says it lands, on its view or back on Home,
// so a value written for one renderer cannot stop reaching it and still pass.
// and a selectedWallet the floor turns into nothing selected. Each boot must
// throw nothing and show exactly the view its entry says it lands on: its own,
// or Home, so a value written for one renderer cannot stop reaching it and
// still pass.
describe("a restore-only hostile value onto", () => {
for (const row of CONTRACT) {
for (const entry of row.hostileRestore || []) {
@@ -987,14 +965,15 @@ describe("a restore-only hostile value onto", () => {
test(`${view}: ${row.field} = ${JSON.stringify(
entry.value,
)}`, async () => {
await expect(
restoredHealth(
restoringOnto(view, { [row.field]: entry.value }),
view,
),
).resolves.toEqual({
...HEALTHY,
restored: entry.restored,
const env = await bootPopup(
restoringOnto(view, { [row.field]: entry.value }),
);
expect({
errors: env.pageErrors,
visible: env.visibleViews(),
}).toEqual({
errors: [],
visible: [entry.restored ? view : "main"],
});
});
}