Describe a tree before building it, so a failing seed can be reduced
The oracle grew its trees from a seed and the shrinker grew its own, with every scenario written out on each side. So a failure the oracle found could not be handed to the shrinker: there was no tree to pass it, only a seed, and a seed cannot be made smaller. The shrinker could only grow its own trees and hope to meet the same shape, which it does not -- 20,000 of its trees never reproduced what the oracle's seed 18 shows at depth 6. `iris::random` now answers with a `Plan`: `plan(seed, depth, &edits)` draws one out of the random stream and `build(rsc, &plan)` makes the widgets, where `grow` did both at once. Every draw happens in the order it always has, so a seed still means the tree it meant -- checked by running the oracle at 1000 seeds of depth 6 before and after and getting the same three failures with the same boxes. `Plan::smaller` reduces one, `Plan::edited` applies an `Edits` to a tree that already exists, and `tests/scenario/` holds the fifteen cases both rigs now run over the same trees. A span keeps the order it holds its children in apart from the children themselves, so detaching, attaching and reordering leave the widgets made in the same order and two builds still line up index for index. `Tree::detached` is gone: `Spanned::spares` is everything made for a span that it does not hold, which is what both of those were. `tests/cases/plan.rs` pins the three properties the rest rests on: editing a plan is growing one with those edits, every simplification is smaller than what it came from, and reducing ends. The second caught this change's own defect, where dropping a side of a `Branch` duplicated another and grew the tree by four widgets. What it found, on its first run: `SHRINK_SEED=18 SHRINK_DEPTH=6 SHRINK_CASE=repaint-some` reduces 277 widgets to 5. A scroll inside a scroll, the inner one owning a movable region, and only the text at the bottom marked for redraw -- and the span lands 24px out, which is exactly the sized child's height. `git bisect` names `95fb4f9`, where `Masked` began reporting its box rather than its inner's size, so what the outer scroll is told its content measures now depends on whether the inner subtree was redrawn this frame. `tests/cases/unsettled.rs` has it written out, ignored until it is fixed. Checked: fmt, clippy over all targets with -D warnings, the workspace tests (79 + 11 + 15, one ignored for the defect above), and the 100-seed oracle over all fifteen cases at depth 4. The shrinker at 400 seeds of depth 5 now fails, which it did not before running the oracle's trees and cases: seeds 2 and 288 on region-node and 174 and 175 on repaint-some are unreduced leads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4febabfd2e
commit
98d4e98a29
7 files changed
+1469
-1290
No files matched your search
@@ -16,6 +16,8 @@ mod drift;
|
||||
mod idempotence;
|
||||
#[path = "cases/layout.rs"]
|
||||
mod layout;
|
||||
#[path = "cases/plan.rs"]
|
||||
mod plan;
|
||||
#[path = "cases/pointer.rs"]
|
||||
mod pointer;
|
||||
#[path = "cases/pointer_routing.rs"]
|
||||
|
||||
Reference in new issue
Block a user