Allow new methods to be added to ui.Image for tests#65876
Allow new methods to be added to ui.Image for tests#65876dnfield merged 14 commits intoflutter:masterfrom
Conversation
jonahwilliams
left a comment
There was a problem hiding this comment.
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.
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.
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.
(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.
... for the rest of the test suite (maybe?)
|
(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.
Why can the use of this FakeImage not be replaced with the new test image stuff?
| void dispose() { } | ||
|
|
||
| @override | ||
| dynamic noSuchMethod(Invocation invocation) { |
| @override | ||
| String toString() => '[$width\u00D7$height]'; | ||
|
|
||
| @override |
There was a problem hiding this comment.
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.
should this link to [setUpAll] / [setUp] as an appropriate place to call this?
| } | ||
|
|
||
| if (kIsWeb) { | ||
| return await _webCreateTestImage( |
There was a problem hiding this comment.
These are not added to the cache?
There was a problem hiding this comment.
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.
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.
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.
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.
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 |
| bool cache = true, | ||
| }) => TestAsyncUtils.guard(() async { | ||
| assert(width != null && width > 0); | ||
| assert(height != null && height > 0); |
There was a problem hiding this comment.
nit: probably also assert(cache != null);
|
|
||
| final int cacheKey = hashValues(width, height); | ||
| if (cache && _cache.containsKey(cacheKey)) { | ||
| return _cache[hashValues(width,height)]; |
There was a problem hiding this comment.
Actually, just use cacheKey here instead of recomputing it?
|
This pull request is not suitable for automatic merging in its current state.
|
|
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.