Skip to content

Commit

Permalink
test: Use color checks that tolerate floating-point errors
Browse files Browse the repository at this point in the history
Done to follow a draft migration guide:
  https://github.com/flutter/website/blob/997c893ccec5fb15dd085a4d23fe8c43870c631b/src/content/release/breaking-changes/wide-gamut-framework.md
for the proposed breaking change that raised
  flutter/flutter#155113

Some other work was needed outside what's described in that draft;
see:
  flutter/flutter#155113 (comment)
  flutter/flutter#155113 (comment)
  • Loading branch information
chrisbobbe committed Sep 17, 2024
1 parent 16c7d7c commit 3c87386
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 48 deletions.
43 changes: 25 additions & 18 deletions test/widgets/channel_colors_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'package:checks/checks.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_checks/flutter_checks.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:zulip/widgets/channel_colors.dart';

import 'channel_colors_checks.dart';
import 'colors_checks.dart';

void main() {
group('ChannelColorSwatches', () {
Expand All @@ -12,12 +14,12 @@ void main() {

const base1 = 0xff76ce90;
final swatch1 = instance.forBaseColor(base1);
check(swatch1).equals(ChannelColorSwatch.light(base1));
check(swatch1).isSameColorSwatchAs(ChannelColorSwatch.light(base1));
check(instance.forBaseColor(base1)).identicalTo(swatch1);

const base2 = 0xfffae589;
final swatch2 = instance.forBaseColor(base2);
check(swatch2).equals(ChannelColorSwatch.light(base2));
check(swatch2).isSameColorSwatchAs(ChannelColorSwatch.light(base2));
check(instance.forBaseColor(base2)).identicalTo(swatch2);
check(instance.forBaseColor(base1)).identicalTo(swatch1);
});
Expand All @@ -28,12 +30,12 @@ void main() {

const base1 = 0xff76ce90;
final swatch1 = instance.forBaseColor(base1);
check(swatch1).equals(ChannelColorSwatch.dark(base1));
check(swatch1).isSameColorSwatchAs(ChannelColorSwatch.dark(base1));
check(instance.forBaseColor(base1)).identicalTo(swatch1);

const base2 = 0xfffae589;
final swatch2 = instance.forBaseColor(base2);
check(swatch2).equals(ChannelColorSwatch.dark(base2));
check(swatch2).isSameColorSwatchAs(ChannelColorSwatch.dark(base2));
check(instance.forBaseColor(base2)).identicalTo(swatch2);
check(instance.forBaseColor(base1)).identicalTo(swatch1);
});
Expand All @@ -53,13 +55,13 @@ void main() {

const base1 = 0xff76ce90;
final swatch1 = instance.forBaseColor(base1);
check(swatch1).equals(ChannelColorSwatch.lerp(
check(swatch1).isSameColorSwatchAs(ChannelColorSwatch.lerp(
ChannelColorSwatch.light(base1), ChannelColorSwatch.dark(base1), 0.4)!);
check(instance.forBaseColor(base1)).identicalTo(swatch1);

const base2 = 0xfffae589;
final swatch2 = instance.forBaseColor(base2);
check(swatch2).equals(ChannelColorSwatch.lerp(
check(swatch2).isSameColorSwatchAs(ChannelColorSwatch.lerp(
ChannelColorSwatch.light(base2), ChannelColorSwatch.dark(base2), 0.4)!);
check(instance.forBaseColor(base2)).identicalTo(swatch2);
check(instance.forBaseColor(base1)).identicalTo(swatch1);
Expand All @@ -70,12 +72,14 @@ void main() {
group('ChannelColorSwatch', () {
group('light', () {
test('base', () {
check(ChannelColorSwatch.light(0xffffffff)).base.equals(const Color(0xffffffff));
check(ChannelColorSwatch.light(0xffffffff))
.base.isSameColorAs(const Color(0xffffffff));
});

test('unreadCountBadgeBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.light(base)).unreadCountBadgeBackground.equals(expected);
check(ChannelColorSwatch.light(base))
.unreadCountBadgeBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS and EXTREME_COLORS
Expand Down Expand Up @@ -137,7 +141,8 @@ void main() {

test('iconOnPlainBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.light(base)).iconOnPlainBackground.equals(expected);
check(ChannelColorSwatch.light(base))
.iconOnPlainBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS
Expand Down Expand Up @@ -178,7 +183,8 @@ void main() {

test('iconOnBarBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.light(base)).iconOnBarBackground.equals(expected);
check(ChannelColorSwatch.light(base))
.iconOnBarBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS
Expand Down Expand Up @@ -219,7 +225,8 @@ void main() {

test('barBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.light(base)).barBackground.equals(expected);
check(ChannelColorSwatch.light(base))
.barBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS
Expand Down Expand Up @@ -262,13 +269,13 @@ void main() {
group('dark', () {
test('base', () {
check(ChannelColorSwatch.dark(0xffffffff))
.base.equals(const Color(0xffffffff));
.base.isSameColorAs(const Color(0xffffffff));
});

test('unreadCountBadgeBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.dark(base))
.unreadCountBadgeBackground.equals(expected);
.unreadCountBadgeBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS and EXTREME_COLORS
Expand Down Expand Up @@ -331,7 +338,7 @@ void main() {
test('iconOnPlainBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.dark(base))
.iconOnPlainBackground.equals(expected);
.iconOnPlainBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS
Expand Down Expand Up @@ -373,7 +380,7 @@ void main() {
test('iconOnBarBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.dark(base))
.iconOnBarBackground.equals(expected);
.iconOnBarBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS
Expand Down Expand Up @@ -415,7 +422,7 @@ void main() {
test('barBackground', () {
void runCheck(int base, Color expected) {
check(ChannelColorSwatch.dark(base))
.barBackground.equals(expected);
.barBackground.isSameColorAs(expected);
}

// Check against everything in ZULIP_ASSIGNMENT_COLORS
Expand Down Expand Up @@ -473,7 +480,7 @@ void main() {
ChannelColorVariant.barBackground => (check(result).barBackground,
Color.lerp(swatchA.barBackground, swatchB.barBackground, t)!),
};
subject.equals(expected);
subject.isSameColorAs(expected);
}
}
});
Expand All @@ -484,7 +491,7 @@ void main() {
final swatch = ChannelColorSwatch.light(0xff76ce90);
check(ChannelColorSwatch.lerp(swatch, swatch, 0.5)).isNotNull()
..identicalTo(swatch)
..base.equals(const Color(0xff76ce90));
..base.isSameColorAs(const Color(0xff76ce90));
});
});
}
11 changes: 11 additions & 0 deletions test/widgets/colors_checks.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:checks/checks.dart';
import 'package:flutter_test/flutter_test.dart' as flutter_matcher;
import 'package:flutter/painting.dart';
import 'package:legacy_checks/legacy_checks.dart';

extension ColorSwatchChecks<T> on Subject<ColorSwatch<T>> {
/// package:checks-style wrapper for [flutter_matcher.isSameColorSwatchAs].
void isSameColorSwatchAs(ColorSwatch<T> colorSwatch) {
legacyMatcher(flutter_matcher.isSameColorSwatchAs(colorSwatch));
}
}
3 changes: 2 additions & 1 deletion test/widgets/compose_box_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:convert';

import 'package:checks/checks.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter_checks/flutter_checks.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -258,7 +259,7 @@ void main() {
final expectedForegroundColor = expected
? colorScheme.onSurface.withValues(alpha: 0.38)
: colorScheme.onPrimary;
check(sendButtonWidget.color).equals(expectedForegroundColor);
check(sendButtonWidget.color).isNotNull().isSameColorAs(expectedForegroundColor);
}

group('attach from media library', () {
Expand Down
3 changes: 2 additions & 1 deletion test/widgets/content_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_checks/flutter_checks.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:zulip/api/core.dart';
Expand Down Expand Up @@ -880,7 +881,7 @@ void main() {
final textColor = mergedStyleOfSubstring(textSpan, renderedTextRegexp)!.color;
check(textColor).isNotNull();

check(icon).color.equals(textColor!);
check(icon).color.isNotNull().isSameColorAs(textColor!);
});
}

Expand Down
19 changes: 13 additions & 6 deletions test/widgets/emoji_reaction_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:checks/checks.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_checks/flutter_checks.dart';

import 'package:flutter_test/flutter_test.dart';
import 'package:zulip/api/model/events.dart';
Expand Down Expand Up @@ -238,20 +239,26 @@ void main() {
return material.color;
}

check(backgroundColor('smile')).equals(EmojiReactionTheme.light().bgSelected);
check(backgroundColor('tada')).equals(EmojiReactionTheme.light().bgUnselected);
check(backgroundColor('smile')).isNotNull()
.isSameColorAs(EmojiReactionTheme.light().bgSelected);
check(backgroundColor('tada')).isNotNull()
.isSameColorAs(EmojiReactionTheme.light().bgUnselected);

tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
await tester.pump();

await tester.pump(kThemeAnimationDuration * 0.4);
final expectedLerped = EmojiReactionTheme.light().lerp(EmojiReactionTheme.dark(), 0.4);
check(backgroundColor('smile')).equals(expectedLerped.bgSelected);
check(backgroundColor('tada')).equals(expectedLerped.bgUnselected);
check(backgroundColor('smile')).isNotNull()
.isSameColorAs(expectedLerped.bgSelected);
check(backgroundColor('tada')).isNotNull()
.isSameColorAs(expectedLerped.bgUnselected);

await tester.pump(kThemeAnimationDuration * 0.6);
check(backgroundColor('smile')).equals(EmojiReactionTheme.dark().bgSelected);
check(backgroundColor('tada')).equals(EmojiReactionTheme.dark().bgUnselected);
check(backgroundColor('smile')).isNotNull()
.isSameColorAs(EmojiReactionTheme.dark().bgSelected);
check(backgroundColor('tada')).isNotNull()
.isSameColorAs(EmojiReactionTheme.dark().bgUnselected);
});

// TODO more tests:
Expand Down
17 changes: 9 additions & 8 deletions test/widgets/inbox_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:checks/checks.dart';
import 'package:flutter/material.dart';
import 'package:flutter_checks/flutter_checks.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:zulip/api/model/events.dart';
import 'package:zulip/api/model/model.dart';
Expand Down Expand Up @@ -332,7 +333,7 @@ void main() {
final icon = findHeaderCollapseIcon(tester, headerRow!);
check(icon).icon.equals(ZulipIcons.arrow_down);
check(allDmsHeaderBackgroundColor(tester))
.isNotNull().equals(const HSLColor.fromAHSL(1, 46, 0.35, 0.93).toColor());
.isNotNull().isSameColorAs(const HSLColor.fromAHSL(1, 46, 0.35, 0.93).toColor());
check(tester.widgetList(findSectionContent)).isNotEmpty();
}

Expand All @@ -350,7 +351,7 @@ void main() {
final icon = findHeaderCollapseIcon(tester, headerRow!);
check(icon).icon.equals(ZulipIcons.arrow_right);
check(allDmsHeaderBackgroundColor(tester))
.isNotNull().equals(Colors.white);
.isNotNull().isSameColorAs(Colors.white);
check(tester.widgetList(findSectionContent)).isEmpty();
}

Expand Down Expand Up @@ -425,10 +426,10 @@ void main() {
final collapseIcon = findHeaderCollapseIcon(tester, headerRow!);
check(collapseIcon).icon.equals(ZulipIcons.arrow_down);
final streamIcon = findStreamHeaderIcon(tester, streamId);
check(streamIcon).color.equals(
check(streamIcon).color.isNotNull().isSameColorAs(
ChannelColorSwatch.light(subscription.color).iconOnBarBackground);
check(streamHeaderBackgroundColor(tester, streamId))
.isNotNull().equals(ChannelColorSwatch.light(subscription.color).barBackground);
.isNotNull().isSameColorAs(ChannelColorSwatch.light(subscription.color).barBackground);
check(tester.widgetList(findSectionContent)).isNotEmpty();
}

Expand All @@ -448,10 +449,10 @@ void main() {
final collapseIcon = findHeaderCollapseIcon(tester, headerRow!);
check(collapseIcon).icon.equals(ZulipIcons.arrow_right);
final streamIcon = findStreamHeaderIcon(tester, streamId);
check(streamIcon).color.equals(
check(streamIcon).color.isNotNull().isSameColorAs(
ChannelColorSwatch.light(subscription.color).iconOnPlainBackground);
check(streamHeaderBackgroundColor(tester, streamId))
.isNotNull().equals(Colors.white);
.isNotNull().isSameColorAs(Colors.white);
check(tester.widgetList(findSectionContent)).isEmpty();
}

Expand Down Expand Up @@ -482,15 +483,15 @@ void main() {
checkAppearsUncollapsed(tester, stream.streamId, find.text('specific topic'));

check(streamHeaderBackgroundColor(tester, 1))
.equals(ChannelColorSwatch.light(initialColor).barBackground);
.isNotNull().isSameColorAs(ChannelColorSwatch.light(initialColor).barBackground);

final newColor = Colors.orange.argbInt;
store.handleEvent(SubscriptionUpdateEvent(id: 1, streamId: 1,
property: SubscriptionProperty.color, value: newColor));
await tester.pump();

check(streamHeaderBackgroundColor(tester, 1))
.equals(ChannelColorSwatch.light(newColor).barBackground);
.isNotNull().isSameColorAs(ChannelColorSwatch.light(newColor).barBackground);
});

testWidgets('collapse stream section when partially offscreen: '
Expand Down
13 changes: 7 additions & 6 deletions test/widgets/message_list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:checks/checks.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_checks/flutter_checks.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:zulip/api/model/events.dart';
Expand Down Expand Up @@ -158,17 +159,17 @@ void main() {
return widget.color;
}

check(backgroundColor()).equals(MessageListTheme.light().streamMessageBgDefault);
check(backgroundColor()).isSameColorAs(MessageListTheme.light().streamMessageBgDefault);

tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
await tester.pump();

await tester.pump(kThemeAnimationDuration * 0.4);
final expectedLerped = MessageListTheme.light().lerp(MessageListTheme.dark(), 0.4);
check(backgroundColor()).equals(expectedLerped.streamMessageBgDefault);
check(backgroundColor()).isSameColorAs(expectedLerped.streamMessageBgDefault);

await tester.pump(kThemeAnimationDuration * 0.6);
check(backgroundColor()).equals(MessageListTheme.dark().streamMessageBgDefault);
check(backgroundColor()).isSameColorAs(MessageListTheme.dark().streamMessageBgDefault);
});

group('fetch older messages on scroll', () {
Expand Down Expand Up @@ -765,7 +766,7 @@ void main() {
find.descendant(
of: find.byType(StreamMessageRecipientHeader),
matching: find.byType(ColoredBox),
))).color.equals(swatch.barBackground);
))).color.isNotNull().isSameColorAs(swatch.barBackground);
});

testWidgets('color of stream icon', (tester) async {
Expand All @@ -777,7 +778,7 @@ void main() {
subscriptions: [subscription]);
await tester.pump();
check(tester.widget<Icon>(find.byIcon(ZulipIcons.globe)))
.color.equals(swatch.iconOnBarBackground);
.color.isNotNull().isSameColorAs(swatch.iconOnBarBackground);
});

testWidgets('normal streams show hash icon', (tester) async {
Expand Down Expand Up @@ -893,7 +894,7 @@ void main() {
zulipLocalizations.messageListGroupYouAndOthers(
zulipLocalizations.unknownUserName))).text;
final icon = tester.widget<Icon>(find.byIcon(ZulipIcons.user));
check(textSpan).style.isNotNull().color.equals(icon.color);
check(textSpan).style.isNotNull().color.isNotNull().isSameColorAs(icon.color!);
});
});

Expand Down
5 changes: 3 additions & 2 deletions test/widgets/subscription_list_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:checks/checks.dart';
import 'package:flutter/material.dart';
import 'package:flutter_checks/flutter_checks.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:zulip/api/model/initial_snapshot.dart';
import 'package:zulip/api/model/model.dart';
Expand Down Expand Up @@ -240,9 +241,9 @@ void main() {
], unreadMsgs: unreadMsgs);
check(getItemCount()).equals(1);
check(tester.widget<Icon>(find.byIcon(iconDataForStream(stream))).color)
.equals(swatch.iconOnPlainBackground);
.isNotNull().isSameColorAs(swatch.iconOnPlainBackground);
check(tester.widget<UnreadCountBadge>(find.byType(UnreadCountBadge)).backgroundColor)
.equals(swatch);
.isNotNull().isSameColorAs(swatch);
});

testWidgets('muted streams are displayed as faded', (tester) async {
Expand Down
Loading

0 comments on commit 3c87386

Please sign in to comment.