Settle.upTo constructor
Pump while the app keeps asking for frames, stopping at the first frame
it does not — or when budget of the fake clock is spent, whichever
comes first. Running out is not a failure — it is recorded on the step —
unless strict, which makes it one after the step's real work has been
landed. See Settle.strict.
The budget is a ceiling, not a wait. Frames are the only thing this
loop follows, and work waiting on a timer schedules none: a screen whose
Future.delayed(Duration(seconds: 1)) has not completed looks exactly
like a screen that is finished, so the loop returns at the first quiet
frame — 100ms in — with the second still on the clock, and the tree is
disposed under it. That is pumpAndSettle's contract too, and a caller
that means to wait for a timer has to say so: Settle.elapse, or a
Settle.frames count that covers it.
Implementation
const factory Settle.upTo(Duration budget, {bool strict}) = _Budgeted;