-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Allow new methods to be added to ui.Image for tests #65876
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
jonahwilliams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative would be to add the new methods with an override and an ignore for the override warning.
At any rate, it would be nice to have a bug tracking the removal
|
Do we really want to remove these? If we remove them, we cause extra pain/work every time we add a method or member to an interface that is explicitly documented as something that you should not extend or implement :\ I understand why we implement it here (for testing purposes only), but even then using the implemented case in a test can cause a unintended test failure if the fake image actually gets to the C++ side of a test. |
|
I actually think a better alternative would be to add something to It should be fairly trivial to use something like |
jonahwilliams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it depends on the various use cases here. We have the kTransparentImage pattern too but that might not be general enough? If there isn't actually any mocking going on maybe
|
I didn't check all of them, but the once I looked at looked all the same. Should we maybe only have one TestImage implementation under flutter/test somewhere and reuse that across these tests? Adding something to flutter_test (or maybe even have that as a private method within flutter/test) to generate a test image also sounds reasonable to me. |
|
Updated this to completely do away with the TestImage fakes, and just use real images. |
|
|
||
| final Map<int, ui.Image> _cache = <int, ui.Image>{}; | ||
|
|
||
| /// Asynchronously creates an arbitrarily sized test image. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instead of "arbitrarily sized test image" -> "arbitrarily sized image for testing", since it is just a regular image.
I dunno if async is necessarily important here, since that is implied by the return type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Cleaned up a little of the rest of the doc too, and saved a file I had fixed but forogtten to save :)
|
|
||
| /// Creates an arbitrarily sized image for testing. | ||
| /// | ||
| /// If the [cache] parameter is set to true, the image will be cached. This |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... for the rest of the test suite (maybe?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
(fixed up the analysis error for real this time) |
|
Added a work around for web (see #49244) |
| int get width => 10; | ||
|
|
||
| @override | ||
| dynamic noSuchMethod(Invocation invocation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can the use of this FakeImage not be replaced with the new test image stuff?
| void dispose() { } | ||
|
|
||
| @override | ||
| dynamic noSuchMethod(Invocation invocation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here and below.
| @override | ||
| String toString() => '[$width\u00D7$height]'; | ||
|
|
||
| @override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored all of these, thanks for catching.
| /// | ||
| /// This method requires real async work, and will not work properly in the | ||
| /// [FakeAsync] zones set up by [testWidgets]. Typically, it should be invoked | ||
| /// as a setup step before [testWidgets] are run. If needed, it can be invoked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this link to [setUpAll] / [setUp] as an appropriate place to call this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added links.
| } | ||
|
|
||
| if (kIsWeb) { | ||
| return await _webCreateTestImage( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are not added to the cache?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, it happens within the method. Maybe for symmetry, pull the caching code out and place it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored this a bit to clean it up.
| /// Creates an arbitrarily sized image for testing. | ||
| /// | ||
| /// If the [cache] parameter is set to true, the image will be cached for the | ||
| /// rest of this suite. This should be avoided for images that are used only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was slightly confused by this telling me to avoid it and the fact that it defaults to true. Maybe add a sentence describing why you usually want caching?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need the caching at all? Does re-creating the image really cost that much in terms of testing performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thought is that we're going from what is a very fast operation (constructing a fake implementation) to what is now a measurably slower and more memory intensive operation, particularly if the image tested is large.
Most of our test cases use a 10x10 image, completely arbitrarily. Some of them use as big as 200x300. If our CI machines are running slowly, caching that 200x300 could save us something on the order of seconds.
Updated the docs here to explain that.
|
Looks like its still unhappy on the web? |
|
Web is still unhappy because |
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| bool cache = true, | ||
| }) => TestAsyncUtils.guard(() async { | ||
| assert(width != null && width > 0); | ||
| assert(height != null && height > 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: probably also assert(cache != null);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
|
||
| final int cacheKey = hashValues(width, height); | ||
| if (cache && _cache.containsKey(cacheKey)) { | ||
| return _cache[hashValues(width,height)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: space after ,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, just use cacheKey here instead of recomputing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whups, done.
|
This pull request is not suitable for automatic merging in its current state.
|
jonahwilliams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
I think.. I think I got it this time guys. I think it's going to work. I even ran it locally and everything. |
|
Tree is green, landing this before it's too late. |
flutter/engine#21057 is going to add some new methods to ui.Image.
Our tests shouldn't break for that.