1 Commits
Author SHA1 Message Date
sneak fabee46f12 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 check that every swept field is driven both truthy and falsy now
counts only `hostile` and `falsy` values; a `hostileRestore` value
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 now names its views and declares whether
the boot lands on them or falls back to Home, and the test asserts it,
so an entry that stops reaching its renderer goes red.

The file's 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 07:58:54 +00:00
+70 -49
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 driven
// onto every restorable view is written with everyRestorableView() below.
// written for one renderer cannot stop reaching it unnoticed. A value that
// lands on some views and not others is one entry per outcome.
//
// `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,23 +158,6 @@ 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",
@@ -329,14 +312,32 @@ 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 every other one.
hostileRestore: everyRestorableView("length", [
"address",
"address-token",
"receive",
"transaction",
"confirm-tx",
]),
// 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,
},
],
},
{
field: "selectedAddress",
@@ -468,25 +469,44 @@ 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 five views with a viewData branch
// refuse it; every other one renders it, and must survive the
// fields every branch left behind.
...everyRestorableView(
{
// 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: {
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,
},
],
},
{
@@ -790,16 +810,19 @@ 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.
// 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.
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 = { errors: [], restored: true };
const RESTORED = { ...HEALTHY, restored: true };
describe("the base profile the sweep corrupts", () => {
for (const view of RESTORABLE_VIEWS) {
@@ -954,10 +977,9 @@ 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 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.
// 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.
describe("a restore-only hostile value onto", () => {
for (const row of CONTRACT) {
for (const entry of row.hostileRestore || []) {
@@ -965,15 +987,14 @@ describe("a restore-only hostile value onto", () => {
test(`${view}: ${row.field} = ${JSON.stringify(
entry.value,
)}`, async () => {
const env = await bootPopup(
restoringOnto(view, { [row.field]: entry.value }),
);
expect({
errors: env.pageErrors,
visible: env.visibleViews(),
}).toEqual({
errors: [],
visible: [entry.restored ? view : "main"],
await expect(
restoredHealth(
restoringOnto(view, { [row.field]: entry.value }),
view,
),
).resolves.toEqual({
...HEALTHY,
restored: entry.restored,
});
});
}