Skip to content

Add WidgetTester.runAsync() - #17029

Merged
tvolkert merged 8 commits into
flutter:masterfrom
tvolkert:runasync
Apr 28, 2018
Merged

tvolkert merged 8 commits into
flutter:masterfrom
tvolkert:runasync

Conversation

@tvolkert

Copy link
Copy Markdown
Contributor

This will allow callers to run real async code within a widget test.

#16859

@tvolkert
tvolkert requested a review from Hixie April 26, 2018 23:15

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this presumably wants a guard?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess the assert serves that purpose. we should add a message to it to make that clearer.

This will allow callers to run real async code within a widget test.

#16859
return new Future<Null>.value(testBodyResult);

return new Future<Null>.microtask(() async {
while (_pendingAsyncTasks != null) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to flush microtasks at least once even when it's null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh i see, you do that in the async barrier.

Yeah, that makes sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh i see, you do that in the async barrier.

I thought so too, which is why I didn't put it in here. But your first instinct was right - we do need it, because the work done in runAsync() may have just completed, meaning _pendingAsyncTasks will be null, yet the microtask queue is still backed up.

@Hixie

Hixie commented Apr 27, 2018

Copy link
Copy Markdown
Contributor

approach sgtm

///
/// If [callback] completes with an error, the error will be caught by the
/// Flutter framework and made available via [takeException], and the future
/// returned by this method will complete will `null`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many wills

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

throw new test_package.TestFailure(
'runAsync() was called, then before its future completed, it\n'
'was called again. You must wait for the first returned future\n'
'to complete before calling runAsync() again.'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't normally break lines for FlutterErrors (see https://master-docs-flutter-io.firebaseapp.com/flutter/foundation/FlutterError/message.html for the conventions), but I don't know what the conventions are for TestFailure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return Zone.root.run(() {
_pendingAsyncTasks = new Completer<void>();
return callback().then<T>((T value) {
return value;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this .then seems... trivial? Is it actually needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's totally not needed, but I thought it improved readability. I'm not married to it though - lemme know if you want me to remove it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a huge fan of it, without any commentary, it would make me wonder why it's there and whether I'm missing something.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'd just remove it. If there's a worry about code clarity, add a comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it before merging.


@override
Future<T> runAsync<T>(Future<T> callback()) async {
try {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should also prevent reentrancy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - will do

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// If [callback] completes with an error, the error will be caught by the
/// Flutter framework and made available via [takeException], and the future
/// returned by this method will complete will `null`.
Future<T> runAsync<T>(Future<T> callback());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should document that, for sanity, reentrancy isn't allowed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@cbracken cbracken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed comments! LGTM

@tvolkert
tvolkert merged commit 8860627 into flutter:master Apr 28, 2018
@tvolkert
tvolkert deleted the runasync branch April 28, 2018 22:14
DaveShuckerow pushed a commit to DaveShuckerow/flutter that referenced this pull request May 14, 2018
This will allow callers to run real async code within a widget test.

flutter#16859
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants