You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Zulip test needs to migrate color assertions #155113
This one is tricky because it looks like the difference in the floating point numbers is < 0.0001 which means it doesn't show up in the print statements. I'm not sure if there is a good remedy for that.
Please update the asserts or the customer test will be disabled in 72 hours (as per our SLA).
Thanks @chrisbobbe, sorry this popping up now. FWIW this is my last planned change to dart:ui Color for this feature.
I looked into queuing up this change for you but you are using package:checks which doesn't seem to support matchers. I'll let you figure out what you want to do about it. It seems like you have to make your own extension method to match the behavior of isSameColorAs
Can you link to the draft migration guide for this breaking change? That'll help us with migrating our code. The draft migration guide is part of step 3 in the breaking-change process, which comes before migrating clients in step 4.
(And of course the migration guide will be essential for helping the broader ecosystem of Flutter users migrate — which is the point of the breaking-change process and of the customer-tests system.)
BTW the 72-hour SLA is on being responsive, not on updating the tests.
For this change I think that won't be a major distinction in practice, because it sounds like the migration will be relatively simple. (It's Thursday afternoon now, though, so if there are some wrinkles it might go to early next week.)
But I wanted to clarify that point because when a migration gets complex, the difference is important: if the migration takes time because it's complex, then it takes time. The customer tests exist to provide feedback to us as the Flutter team about how our changes affect users of Flutter; if a migration is complex for one of the customer tests, then it'll probably be complex for many other Flutter users.
It's not going to say anything about migrating package:check. It does not say anything about the equality of Color changing. It may be worthwhile adding that now that we know that is possible to come up.
I posted a PR to spell out the equality changes more explicitly. It's kind of a grey area since the API doesn't change but the change in semantics can break tests so better to mention it: https://github.com/flutter/website/pull/11132/files
Here's an easy change, looks like package:checks has a isCloseTo, you could do something like this if you don't want to make your own extension method:
The isSameColorAs(…) matcher is helpful for checks on ordinary Colors. But for ColorSwatches, we'd lose a handy way to compare two swatches for equality in all the members / "related colors" that make up each swatch.
Before, you could do this:
// Compares all swatch members; see [ColorSwatch]'s `operator ==`.check(swatchA).equals(swatchB);
(The `operator ==` override on `ColorSwatch`)
@overridebooloperator==(Object other) {
if (identical(this, other)) {
returntrue;
}
if (other.runtimeType != runtimeType) {
returnfalse;
}
returnsuper== other
&& other isColorSwatch<T>
&&mapEquals<T, Color>(other._swatch, _swatch);
}
But now:
// Compares all members, but thrown off by floating-point differencescheck(swatchA).equals(swatchB);
// Possible because `ColorSwatch` extends `Color`,// and not sensitive to floating-point differences, but only looks at// each swatch's "primary" color, ignoring all its other members.check(swatchA).isSameColorAs(swatchB);
If there were a new Matcher for ColorSwatches that compared all the swatches' members using the logic of isSameColorAs (with a threshold), it would help us and other apps whose tests want to do that.
The isSameColorAs(…) matcher is helpful for checks on ordinary Colors. But for ColorSwatches, we'd lose a handy way to compare two swatches for equality in all the members / "related colors" that make up each swatch.
The equality problem's only going to arise if you are doing certain mathematical operations to calculate colors (like division). If you do something like this, it will still work:
const swatch =ColorSwatch<int>(0xff000000, {0, Color(0xff000000)});
final foo =Foo(swatch, swatchIndex:0);
check(foo.color).equals(Color(0xff000000));
We're only running into an issue here because we are lerping the swatches. That seems somewhat niche, I don't know what the framework's threshold is for adding a new matcher. I think a good way forward would be to add it to your code if you find it helpful then open a framework PR that adds it and see what the framework team says.
For what it's worth the ColorSwatch is somewhat in my sight for elimination. It hasn't been investigated deeply but there is a hope we can make Color sealed at some point which would make subclassing Color verboten. In general if the classes in dart:ui are sealed we'll have more freedom to change them since people will be treating them as black boxes instead of relying on certain implementations.
edit: Well I don't mean eliminate ColorSwatch, but change it from being a Color subclass. In that case having a matcher would still be helpful.
Making ColorSwatch no longer subclass Color sounds pretty reasonable to me — it always felt a bit odd that it's a subclass. That'll be a breaking change of its own, I'm sure, so there'll be some migration work needed to make that happen too.
Lerping swatches is pretty common: it's something that any modern app can be expected to do if it uses swatches in the first place. Users expect apps to offer a dark theme as well as a light theme, and to animate smoothly between them if they've chosen in system settings for the device to switch back and forth on a schedule. So for example MaterialApp uses AnimatedTheme to lerp between the app's dark and light themes, and therefore lerp all the colors in the themes. If the app has swatches of its own, they're probably different between the themes and so will also get lerped.
More generally I think it's pretty normal to do mathematical operations on colors. For example division by 255 is right there in the Color class now :-). It's also common to transform colors to a different coordinate system like LCH, blend or adjust them there, and transform back, in order to get nice visual effects.
So before we ship a breaking change that makes color computations happen in floating point, we should have a good answer for how people can continue to write reasonable tests for their color-manipulating code, across all Flutter's affected APIs. The isSameColorAs matcher provides a good answer for comparing Color itself, but ColorSwatch needs a solution too.
Fortunately I think that shouldn't be complicated to do.
The key thing is that ColorSwatch will need to gain a getter like debugEntries => _swatch.entries, and/or debugKeys => _swatch.keys. As things stand, it's not possible for code outside that file to enumerate the keys of the swatch in order to drive a comparison.
Then it becomes straightforward to write a matcher. Because ColorSwatch is part of Flutter, and because its data is going to be in floating-point terms so that inexact comparisons are necessary, I think the right home for that matcher is in flutter_test, just like we have for Color and Offset and a number of other types.
I think it's kind of moot because the only thing that matters is what Color it manifests as. By asserting that ColorSwatch.lerp does something is recreating tests that already exist in the framework.
I put up a PR for accessing the keys to a ColorSwatch: #155262.
Great, thanks.
As I said above, I think the right home for the matcher is in flutter_test. So there should be a flutter/flutter PR for that too, and then it'll be possible for Flutter users (including Zulip) to cleanly migrate.
#155272 adds a ColorSwatch matcher if you want to hook into that instead of writing your own. It doesn't recurse into ColorSwatch, which I don't think you're going to need.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.
Activity
gaaclarke commentedon Sep 12, 2024
I looked into queuing up this change for you but you are using
package:checkswhich doesn't seem to support matchers. I'll let you figure out what you want to do about it. It seems like you have to make your own extension method to match the behavior ofisSameColorAsgnprice commentedon Sep 12, 2024
Hi @gaaclarke, thanks for the note.
Before there's any talk of disabling anything, the way customer testing works is that the stage before that is the breaking-change process:
https://github.com/flutter/tests#if-a-test-is-broken
https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#handling-breaking-changes
Can you link to the draft migration guide for this breaking change? That'll help us with migrating our code. The draft migration guide is part of step 3 in the breaking-change process, which comes before migrating clients in step 4.
(And of course the migration guide will be essential for helping the broader ecosystem of Flutter users migrate — which is the point of the breaking-change process and of the customer-tests system.)
gnprice commentedon Sep 12, 2024
BTW the 72-hour SLA is on being responsive, not on updating the tests.
For this change I think that won't be a major distinction in practice, because it sounds like the migration will be relatively simple. (It's Thursday afternoon now, though, so if there are some wrinkles it might go to early next week.)
But I wanted to clarify that point because when a migration gets complex, the difference is important: if the migration takes time because it's complex, then it takes time. The customer tests exist to provide feedback to us as the Flutter team about how our changes affect users of Flutter; if a migration is complex for one of the customer tests, then it'll probably be complex for many other Flutter users.
gaaclarke commentedon Sep 12, 2024
Yes, sorry Greg I had talked with your team previously with this change so I thought you were all current. The breaking change guide has already been published. You'll find it here: https://github.com/flutter/website/blob/main/src/content/release/breaking-changes/wide-gamut-framework.md
It's not going to say anything about migrating
package:check. It does not say anything about the equality of Color changing. It may be worthwhile adding that now that we know that is possible to come up.gaaclarke commentedon Sep 12, 2024
I posted a PR to spell out the equality changes more explicitly. It's kind of a grey area since the API doesn't change but the change in semantics can break tests so better to mention it: https://github.com/flutter/website/pull/11132/files
gaaclarke commentedon Sep 12, 2024
Here's an easy change, looks like package:checks has a
isCloseTo, you could do something like this if you don't want to make your own extension method:gnprice commentedon Sep 12, 2024
Very helpful, thanks!
And I agree that added section about equality in the migration guide is a good idea.
chrisbobbe commentedon Sep 12, 2024
flutter_checksmakes it convenient to wrap and useMatchers fromflutter_testthat don't yet have counterparts inchecks, includingisSameColorAs(…):chrisbobbe commentedon Sep 12, 2024
The
isSameColorAs(…)matcher is helpful for checks on ordinaryColors. But forColorSwatches, we'd lose a handy way to compare two swatches for equality in all the members / "related colors" that make up each swatch.Before, you could do this:
(The `operator ==` override on `ColorSwatch`)
But now:
If there were a new
MatcherforColorSwatches that compared all the swatches' members using the logic ofisSameColorAs(with athreshold), it would help us and other apps whose tests want to do that.gaaclarke commentedon Sep 12, 2024
The equality problem's only going to arise if you are doing certain mathematical operations to calculate colors (like division). If you do something like this, it will still work:
We're only running into an issue here because we are lerping the swatches. That seems somewhat niche, I don't know what the framework's threshold is for adding a new matcher. I think a good way forward would be to add it to your code if you find it helpful then open a framework PR that adds it and see what the framework team says.
For what it's worth the ColorSwatch is somewhat in my sight for elimination. It hasn't been investigated deeply but there is a hope we can make Color sealed at some point which would make subclassing Color verboten. In general if the classes in dart:ui are sealed we'll have more freedom to change them since people will be treating them as black boxes instead of relying on certain implementations.
edit: Well I don't mean eliminate ColorSwatch, but change it from being a Color subclass. In that case having a matcher would still be helpful.
gnprice commentedon Sep 14, 2024
Making ColorSwatch no longer subclass Color sounds pretty reasonable to me — it always felt a bit odd that it's a subclass. That'll be a breaking change of its own, I'm sure, so there'll be some migration work needed to make that happen too.
Lerping swatches is pretty common: it's something that any modern app can be expected to do if it uses swatches in the first place. Users expect apps to offer a dark theme as well as a light theme, and to animate smoothly between them if they've chosen in system settings for the device to switch back and forth on a schedule. So for example
MaterialAppusesAnimatedThemeto lerp between the app's dark and light themes, and therefore lerp all the colors in the themes. If the app has swatches of its own, they're probably different between the themes and so will also get lerped.More generally I think it's pretty normal to do mathematical operations on colors. For example division by 255 is right there in the Color class now :-). It's also common to transform colors to a different coordinate system like LCH, blend or adjust them there, and transform back, in order to get nice visual effects.
So before we ship a breaking change that makes color computations happen in floating point, we should have a good answer for how people can continue to write reasonable tests for their color-manipulating code, across all Flutter's affected APIs. The
isSameColorAsmatcher provides a good answer for comparingColoritself, butColorSwatchneeds a solution too.Fortunately I think that shouldn't be complicated to do.
The key thing is that
ColorSwatchwill need to gain a getter likedebugEntries => _swatch.entries, and/ordebugKeys => _swatch.keys. As things stand, it's not possible for code outside that file to enumerate the keys of the swatch in order to drive a comparison.Then it becomes straightforward to write a matcher. Because
ColorSwatchis part of Flutter, and because its data is going to be in floating-point terms so that inexact comparisons are necessary, I think the right home for that matcher is influtter_test, just like we have for Color and Offset and a number of other types.gaaclarke commentedon Sep 16, 2024
gaaclarke commentedon Sep 16, 2024
I think it's kind of moot because the only thing that matters is what Color it manifests as. By asserting that ColorSwatch.lerp does something is recreating tests that already exist in the framework.
gaaclarke commentedon Sep 16, 2024
I put up a PR for accessing the keys to a ColorSwatch: #155262. It's not necessary for this. You'll have to pass in the list of keys in the matcher.
1 remaining item
gnprice commentedon Sep 16, 2024
Great, thanks.
As I said above, I think the right home for the matcher is in
flutter_test. So there should be a flutter/flutter PR for that too, and then it'll be possible for Flutter users (including Zulip) to cleanly migrate.Added .keys to ColorSwatch (#155262)
Adds ColorSwatch matcher (#155272)
gaaclarke commentedon Sep 17, 2024
#155272 adds a ColorSwatch matcher if you want to hook into that instead of writing your own. It doesn't recurse into ColorSwatch, which I don't think you're going to need.
gnprice commentedon Sep 18, 2024
Excellent, thanks for adding that!
@chrisbobbe now has a PR migrating our tests to use that matcher (and
isSameColorAs):so I expect that'll be complete soon.
test: Use color checks that tolerate floating-point errors
Update zulip to use Color{,Swatch} asserts that tolerate float errors
chrisbobbe commentedon Sep 18, 2024
The zulip-flutter PR has been merged, and I've just sent flutter/tests#409.
Update zulip to use Color{,Swatch} asserts that tolerate float errors (…
Reland: Update Color to do all calculations with floating point compo…
github-actions commentedon Oct 3, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.