Also, I had a question about flutter_test matchers and our style guide
says that when I have a question I should update the docs so I did
that and then got a bit carried away.
This splits the frame pipeline into two, beginFrame and drawFrame.
As part of making this change I added some debugging hooks that helped
debug the issues that came up:
* I added debugPrintScheduleFrameStacks which prints a stack whenever
a frame is actually scheduled, so you can see why frames are being
scheduled.
* I added some toString output to EditableText and RawKeyboardListener.
* I added a scheduler_tester.dart library for scheduler library tests.
* I changed the test framework to flush microtasks before pumping.
* Some asserts that had the old string literal form were replaced by
asserts with messages.
I also fixed a few subtle bugs that this uncovered:
* setState() now calls `ensureVisualUpdate`, rather than
`scheduleFrame`. This means that calling it from an
AnimationController callback does not actually schedule an extra
redundant frame as it used to.
* I corrected some documentation.
This patch introduces the notion of a keyboard token, which generalizes the
logic in EditableText for distinguishing between gaining focus by default and
gaining focus because of an explicit use action.
Fixes#7985
* Manually fix every use of Point.x and Point.y
Some of these were moved to dx/dy, but not all.
* Manually convert uses of the old gradient API
* Remove old reference to Point.
* Mechanical changes
I applied the following at the root of the Flutter repository:
git ls-files -z | xargs -0 sed -i 's/\bPoint[.]origin\b/Offset.zero/g'
git ls-files -z | xargs -0 sed -i 's/\bPoint[.]lerp\b/Offset.lerp/g'
git ls-files -z | xargs -0 sed -i 's/\bnew Point\b/new Offset/g'
git ls-files -z | xargs -0 sed -i 's/\bconst Point\b/const Offset/g'
git ls-files -z | xargs -0 sed -i 's/\bstatic Point /static Offset /g'
git ls-files -z | xargs -0 sed -i 's/\bfinal Point /final Offset /g'
git ls-files -z | xargs -0 sed -i 's/^\( *\)Point /\1Offset /g'
git ls-files -z | xargs -0 sed -i 's/ui[.]Point\b/ui.Offset/g'
git ls-files -z | xargs -0 sed -i 's/(Point\b/(Offset/g'
git ls-files -z | xargs -0 sed -i 's/\([[{,]\) Point\b/\1 Offset/g'
git ls-files -z | xargs -0 sed -i 's/@required Point\b/@required Offset/g'
git ls-files -z | xargs -0 sed -i 's/<Point>/<Offset>/g'
git ls-files -z | xargs -0 sed -i 's/[.]toOffset()//g'
git ls-files -z | xargs -0 sed -i 's/[.]toPoint()//g'
git ls-files -z | xargs -0 sed -i 's/\bshow Point, /show /g'
git ls-files -z | xargs -0 sed -i 's/\bshow Point;/show Offset;/g'
* Mechanical changes - dartdocs
I applied the following at the root of the Flutter repository:
git ls-files -z | xargs -0 sed -i 's/\ba \[Point\]/an [Offset]/g'
git ls-files -z | xargs -0 sed -i 's/\[Point\]/[Offset]/g'
* Further improvements and a test
* Fix minor errors from rebasing...
* Roll engine
* Fix tests to use Ahem, and helpful changes around that
- Fix fonts that had metric-specific behaviours.
- LiveTestWidgetsFlutterBinding.allowAllFrames has been renamed
to LiveTestWidgetsFlutterBinding.framePolicy.
- LiveTestWidgetsFlutterBinding now defaults to using a frame policy
that pumps slightly more frames, to animate the pointer crosshairs.
- Added "flutter run --use-test-fonts" to enable Ahem on devices.
- Changed how idle() works to be more effective in live mode.
- Display the test name in live mode (unless ahem fonts are enabled).
- Added a toString to TextSelectionPoint.
- Style nit fixes.
* Roll engine to get Ahem changes.
* Update tests for dartdoc changes.
* Fix flutter_tools tests
Rename State.config to State.widget
Rename State.didUpdateConfig to State.didUpdateWidget
Renamed all State subclasses' local variables named config to something else
Breaking change: removed deprecated methods of PlatformMessages, leaving only binary messaging there. All other use of platform communication now goes through PlatformMessageChannel and PlatformMethodChannels. Retained use of String and JSON codecs for now.
Companion engine PR: flutter/engine#3482
* Bump to test `0.12.20`.
Some test `0.12.20` highlights:
* introduces `expectLater()` that returns a `Future` that completes when the matcher has finished running
* deprecates the `verbose` parameter to `expect()` and the `formatFailure()` (to be removed in `0.13.0`)
Otherwise:
* to keep up w/ the deprecation of `verbose`, removes `widget_tester` API to pass `verbose` flag (alternatively we could suppress the warning for now)
* Update stack manipulation.
* Fix framecount.
* Add find.descendant API to support find descendants of an element by passing the current element and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
* Add find.descendant API to support find descendants of an element by passing the current element finder and the finder of descendant.
- output single-line JSON because iOS 9.x cannot output more than one line
- move the workaround for #7433 into LiveTestWidgetsFlutterBinding so that it works in all cases (e.g. animation_bench.dart on iOS)
Also, make hasOneLineDescription more discerning.
Also, add a test for hasOneLineDescription.
Also, add a test for GravitySimulation, to test the toString.
```dart
expect(x, moreOrLessEquals(0.0));
```
...for those cases where `x` might be 1e-11 or whatever.
Also, be more resilient when dumping the tree from inside the test framework.
Also, add an assert that helped me debug something the other day.
We were trying to update the tooltip overlay entry, but that cannot work
because the overlay entry might have already built. Instead, we keep the
old value.
Fixes#7151
* Remove the workaround that pinned args to v0.13.6
This reverts most of the changes in commit 6331b6c8b5
* throw exception if exit code is not an integer
* rework command infrastructure to throw ToolExit when non-zero exitCode
* convert commands to return Future<Null>
* cleanup remaining commands to use throwToolExit for non-zero exit code
* remove isUnusual exception message
* add type annotations for updated args package
Add an option to provide a custom description to predicate
finders. Without a custom description we default to printing the
predicate function's signature, which is not all that useful.
Use this new option in the driver extension to print the text of the
sought after tooltip.
This requires all AnimationController objects to be given a
TickerProvider, a class that can create the Ticker.
It also provides some nice mixins for people who want to have their
State provide a TickerProvider. And a schedulerTickerProvider for those
cases where you just want to see your battery burn.
Also, we now enforce destruction order for elements.
Switch our pubspec.yamls to using SDK sources so that we can have consistent
source types when we depend on these packages from external packages using SDK
sources.
* Update tools to use `analyzer` from vended Dart SDK.
* updates `flutter_tools` and `flutter_test` to use the SDK-vended `analyzer` package
* tweaks dependency tracking logic to only record the SDK-vended `analyzer` so as not to crash on spurious conflicts (due to transitive dependencies)
* Review fixes.
Previously, pumpWidget() would do a partial pump (it didn't trigger
Ticker callbacks or post-frame callbacks), and pump() would do a full
pump. This patch brings them closer together. It also makes runApp run a
full actual frame, rather than skipping the transient callback part of
the frame logic. Having "half-frames" in the system was confusing and
could lead to bugs where code expecting to run before the next layout
pass didn't because a "half-frame" ran first.
Also, make Tickers start ticking in the frame that they were started in,
if they were started during a frame. This means we no longer spin a
frame for t=0, we jump straight to the first actual frame.
Other changes in this patch:
* rename WidgetsBinding._runApp to WidgetsBinding.attachRootWidget, so
that tests can use it to more accurately mock out runApp.
* allow loadStructuredData to return synchronously.
* make handleBeginFrame handle not being given a time stamp.
* make DataPipeImageProvider.loadAsync protected (rather than private),
and document it. There wasn't really a reason for it to be private.
* fix ImageConfiguration.toString.
* introduce debugPrintBuildScope and debugPrintScheduleBuildForStacks,
which can help debug problems with widgets getting marked as dirty but
not cleaned.
* make debugPrintRebuildDirtyWidgets say "Building" the first time and
"Rebuilding" the second, to make it clearer when a widget is first
created. This makes debugging widget lifecycle issues much easier.
* make debugDumpApp more resilient.
* debugPrintStack now takes a label that is printed before the stack.
* improve the banner shown for debugPrintBeginFrameBanner.
* various and sundry documentation fixes
This issue got fixed by a recent check-in, but I had a test specifically
for this incarnation so we should probably keep it just in case.
Closes https://github.com/flutter/flutter/issues/5630
Previously, if a StatefulWidget was marked dirty, then removed from the
build, then reinserted using the exact same widget under a widget under
a LayoutBuilder, it wouldn't rebuild.
This fixes that.
It also introduces an assert that's supposed to catch SizeObserver-like
behaviour. Rather than make this patch even bigger, I papered over two
pre-existing bugs which this assert uncovered (and fixed the other
problems it found):
https://github.com/flutter/flutter/issues/5751https://github.com/flutter/flutter/issues/5749
We should fix those before 1.0 though.
Changes in this patch:
- iOS now uses a different scrollDrag constant than Android.
- ScrollConfigurationDelegate now knows about target platforms.
- ScrollBehaviors now know about target platforms.
- RawInputLine now has to be told what platform it's targetting.
- PageableList now has a concept of target platform.
- make debugPrintStack filter its stack.
- move debugPrintStack to `assertions.dart`.
- add support for limiting the number of frames to debugPrintStack.
- make defaultTargetPlatform default to android in test environments.
- remove OverscrollStyle and MaterialApp's overscrollStyle argument. You
can now control the overscroll style using Theme.platform.
- the default scroll configuration is now private to avoid people
relying on the defaultTargetPlatform getter in their subclasses (since
they really should use Theme.of(context).platform).
- fix some typos I noticed in some tests.
- added a test for flinging scrollables, that checks that the behavior
differs on the two target platforms.
- made flingFrom and fling in the test API pump the frames.
- added more docs to the test API.
- made the TestAsyncUtils.guard() method report uncaught errors to help
debug errors when using that API.
We now have 100% coverage of animation.dart and animation_controller.dart.
Also, add some basic tools for working with lcov files. These tools need much
more polish.
* brings in analyzer version (`0.27.4-alpha.14`) corresponding to current Dart SDK (`1.18.0-dev.2.0`).
* updates analysis to use prefered API for embedder URI resolution
* adds trampolines to `State` and `StatelessWidget` to allow for warning-free within-library @protected access (needed since we closed off access to @protected closures from outside subclasses).
* turns off cache dependency tracking for analysis (in DDC this amounted to a 10% speed improvement).
Prep to get us ready to pull in a new dev SDK and bump our analyzer DEP.
* updates `crypto` (required by fresh analyzer)
* fixes newly flagged dead code warnings
* fixes switches that fall through and don't return
Don't suggest filing an issue when we can definitively say that the
assertion in question was not thrown from within the flutter package.
Fixes https://github.com/flutter/flutter/issues/3812.
Put the stack trace first after the message, with more details below the
stack trace, since the stack is often very useful and the stacks are no
longer stupidly long.
Better document the 'rescheduling' feature, and improve the error
handling asserts when it is misused.
Fixes https://github.com/flutter/flutter/issues/3888.
Improve the wording around the stack dump for exceptions during
callbacks.
Improve the color and font size of messages in live tests.
Fixes https://github.com/flutter/flutter/issues/4018.
* Add a "build" phase to EnginePhase for completeness.
* Ignore events from the device during test execution.
* More dartdocs
* Slightly more helpful messages about Timers in verifyInvariants.
* Add widgetList, elementList, stateList, renderObjectList.
* Send test events asynchronously for consistency with other APIs.
* Fix a test that was depending on test events being synchronous (or
rather, scheduled in a microtask that came before the microtask for
the completer of the future that the tap() function returned).
This makes it possible to substitute 'flutter run' for 'flutter test'
and actually watch a test run on a device.
For any test that depends on flutter_test:
1. Remove any import of 'package:test/test.dart'.
2. Replace `testWidgets('...', (WidgetTester tester) {`
with `testWidgets('...', (WidgetTester tester) async {`
3. Add an "await" in front of calls to any of the following:
* tap()
* tapAt()
* fling()
* flingFrom()
* scroll()
* scrollAt()
* pump()
* pumpWidget()
4. Replace any calls to `tester.flushMicrotasks()` with calls to
`await tester.idle()`.
There's a guarding API that you can use, if you have particularly
complicated tests, to get better error messages. Search for
TestAsyncUtils.
Introduces a new Dart analysis wrapper that works directly with the analyzer API (in favor of shelling out to a separate process).
Some consequences:
* we no longer need to fear parts (simplifying our dart file gathering)
* we can filter by error code (when needed), rather than by error strings
* no more IO scraping
* no need to generate `main()` or to run with `--package-warnings`
* we now specify an analyzer (and linter) version in the pubspec (we’ll want to make sure this doesn’t diverge too far from the analyzer shipped with the SDK but it does give us some room to play with experimental builds)
* no more (re)scanning of error source files (and so no more source cache)
* should generally be a bit simpler and easier to maintain
* runs a bit faster :)
This test hangs occationally on the bots and the bots aren't smart enough to
recover, which means the whole project gets blocked.
Filed #3735 about the hang.
* Refactor widget test framework
Instead of:
```dart
test("Card Collection smoke test", () {
testWidgets((WidgetTester tester) {
```
...you now say:
```dart
testWidgets("Card Collection smoke test", (WidgetTester tester) {
```
Instead of:
```dart
expect(tester, hasWidget(find.text('hello')));
```
...you now say:
```dart
expect(find.text('hello'), findsOneWidget);
```
Instead of the previous API (exists, widgets, widget, stateOf,
elementOf, etc), you now have the following comprehensive API. All these
are functions that take a Finder, except the all* properties.
* `any()` - true if anything matches, c.f. `Iterable.any`
* `allWidgets` - all the widgets in the tree
* `widget()` - the one and only widget that matches the finder
* `firstWidget()` - the first widget that matches the finder
* `allElements` - all the elements in the tree
* `element()` - the one and only element that matches the finder
* `firstElement()` - the first element that matches the finder
* `allStates` - all the `State`s in the tree
* `state()` - the one and only state that matches the finder
* `firstState()` - the first state that matches the finder
* `allRenderObjects` - all the render objects in the tree
* `renderObject()` - the one and only render object that matches the finder
* `firstRenderObject()` - the first render object that matches the finder
There's also `layers' which returns the list of current layers.
`tap`, `fling`, getCenter, getSize, etc, take Finders, like the APIs
above, and expect there to only be one matching widget.
The finders are:
* `find.text(String text)`
* `find.widgetWithText(Type widgetType, String text)`
* `find.byKey(Key key)`
* `find.byType(Type type)`
* `find.byElementType(Type type)`
* `find.byConfig(Widget config)`
* `find.byWidgetPredicate(WidgetPredicate predicate)`
* `find.byElementPredicate(ElementPredicate predicate)`
The matchers (for `expect`) are:
* `findsNothing`
* `findsWidgets`
* `findsOneWidget`
* `findsNWidgets(n)`
* `isOnStage`
* `isOffStage`
* `isInCard`
* `isNotInCard`
Benchmarks now use benchmarkWidgets instead of testWidgets.
Also, for those of you using mockers, `serviceMocker` now automatically
handles the binding initialization.
This patch also:
* changes how tests are run so that we can more easily swap the logic
out for a "real" mode instead of FakeAsync.
* introduces CachingIterable.
* changes how flutter_driver interacts with the widget tree to use the
aforementioned new API rather than ElementTreeTester, which is gone.
* removes ElementTreeTester.
* changes the semantics of a test for scrollables because we couldn't
convince ourselves that the old semantics made sense; it only worked
before because flushing the microtasks after every event was broken.
* fixes the flushing of microtasks after every event.
* Reindent the tests
* Fix review comments
Wait until the end of the microtask to tell gesture recognizers that
they've won in the gesture arena. This lets recognizers dispose reject
themselves at arbitrary times without triggering gestures in awkward
call stacks.
Fixes#3183
This reorders some classes so that this file makes more sense, and adds
a bunch of docs. It also makes the following changes:
* Move allElements from Instrumentation to TestWidgets. (Instrumentation
is going away.)
* Remove findElements.
* Rename byElement to byElementPredicate
* Rename byPredicate to byWidgetPredicate
* Implement _WidgetPredicateFinder so that byWidgetPredicate has good
messages
* Fix one use of byElementPredicate to use byWidgetPredicate.
Previously the widgets layer only provided a concrete binding, which
makes it awkward to extend it compared to other bindings. This moves
widgets to the same style as the other layers.
In a subsequent patch I'll use this to make the tests layer saner.
Moves TestGesture into test_pointer.dart and makes it more
self-contained.
This is part of a general refactoring of flutter_test.
Depends on https://github.com/flutter/flutter/pull/3459
Also a bit of code cleanup.
The key part of this patch is the addition in `_endScroll` to reset
`_simulation`. It seems like this was the one place where it's possible
for us to end the animation but not reset our state. Since we assert
that are state is coherent, we were hitting asserts when a fling
finished and then you interacted with the widget again.
...by adding tests to our examples that don't import flutter_test, which
pins the relevant dependencies.
Also, provide more information when complaining about leaked transient
callbacks in tests.
Also, make tests display full information when they have an exception,
by bypassing the throttling we have for Android logging in tests.
Also, make the word wrapping not wrap stack traces if they happen to
be included in exception output.
Also, fix a leaked transient callback in the checkbox code.
- Create a FlutterErrorDetails struct-like class that describes an
exception along with more details that aren't in the exception, like
where it was caught and what was going on when it was caught.
- Provide a FlutterError static API for handling these objects:
- FlutterError.onError which is called whenever Flutter catches an
error.
- FlutterError.reportError() which handles an error.
- FlutterError.dumpErrorToConsole() which is the default behavior
for onError.
- Removes all the existing exception handler callbacks.
- Replaces all the existing places that described exceptions using
debugPrint with calls to FlutterError.reportError().
- Extend lockState() to also catch exceptions, so that we catch
exceptions that happen during finalizers.
- Make the test framework catch errors and treat them as failures.
- Provide a mechanism to override this behavior in the test framework.
- Make the tests that used to depend on the exception handler
callbacks use this new mechanism.
- Make pump() also support the phase argument.
- Improve some tests using these new features.
Fixes#2356, #2988, #2985, #2220.
Adds BuildOwner to manage the dirty list and build processing for
widgets/elements, and adds a widget unit test to make sure separation
is enforced.
Fixes#2723
After running a widget test, we now clear out the widget tree and check that we
didn't leak any timers or animations.
Also, fix several bugs that this addtional check revealed.
Fixes#2481
Also:
- add operator==/hashCode/toString to ViewportDimensions
- add toString to BindingBase
- add toString and debugFillDescription to ScrollBehavior
- fix a bug in the RawGestureDetectorState's replaceGestureRecognizers
- rename MixedViewport's onExtentsUpdate to onExtentChanged
- replace ExtentsUpdateCallback with ValueChanged<double>
- remove a microtask for dispatching scroll start, since it
did not appear to have any purpose
- added dartdocs to Instrumentation until I understood it
- made all event dispatch in Instrumentation drain microtasks
Each layer is supposed to reexport the parts of the previous layer
that are part of its API.
- In painting.dart, export from dart:ui all the Canvas-related APIs
that make sense to be used at higher levels, e.g. PaintingStyle.
- Delete painting/shadows.dart. It was dead code.
- In rendering/object.dart, export all of painting.dart.
- In widgets/basic.dart, export all of painting.dart and
animation.dart. Some classes in animation/ are renamed to make this
less disruptive and confusing to the namespace.
- Split out Stocks back into an import model rather than a part model,
so that it's easier to manage its dependencies on a per-file basis.
- Move Ticker to scheduler library.
- Remove as many redundant imports as possible now.
- Some minor nit picking cleanup in various files.
I had to add a setLocale method to WidgetTester and
split the code in FlutterBinding which handled locale
changes to allow me to dispatch a locale change w/o actually
changing what the c++ code reports as the locale.
Also added the test to Travis.
@abarth @jason-simmons
Instead of PointerInputEvent having a "type" field, we now have a
different class for each pointer type.
This has ripple effects throughout the system.
I also did code cleanup in affected files while I was there.
Also:
- minor code reindents in places.
- reset the widget tree between tests.
- once you generate a route, don't let its builder change
(previously it would keep changing as the routes table changed).
- revert the stocks app toolbar-fading-on-forward-transition thing.
The names are probably less familiar, but more consistent:
- FrameCallback: a callback that is relative to the frame and wants the
frame offset (a duration) as argument.
- addXFrameCallback: adds the given callback to the internal lists/maps.
- scheduleXFrameCallback (currently only X = ""): add the callback, but
also trigger a new frame.
- handleX: the method that is invoked when the event-loop or the frame
calls into the scheduler.
- ensureXYZ: ensure that the callback happens.
Unfortunately there is the ambiguity between a "callback": it can be a
closure, or the action of doing a callback, so we end up with:
ensureBeginFrameCallback, and ensureEventLoopCallback, where
"callback" means the action of being called back.
We use a number of non-public APIs in the test package, which makes our
dependency quite fragile. This patch pins a specific, known-good version. We
should update to the lastest version in a follow-up patch.