import 'package:flutter_test/flutter_test.dart'; import 'package:halkyon_ui/halkyon_ui.dart'; import 'package:material_ui/material_ui.dart'; void main() { group('The tone at the top', () { for (final brightness in Brightness.values) { final scheme = appTheme(brightness).colorScheme; for (final background in [scheme.surface, scheme.surfaceContainerLow]) { test('keeps the text readable on every palette colour, ' '${brightness.name}, $background', () { for (final color in PaletteColor.values) { final top = TopGradient.topTone( scheme, color.background, background, ); expect( TopGradient.contrast(top, scheme.onSurface), greaterThanOrEqualTo(TopGradient.minContrast), reason: color.name, ); } }); } } test("the frame around the tabs keeps the rail's labels readable on " 'every palette colour, top and foot', () { for (final brightness in Brightness.values) { final scheme = appTheme(brightness).colorScheme; for (final color in PaletteColor.values) { for (final tone in TopGradient.frame( scheme, color.background, ).colors) { expect( TopGradient.contrast(tone, scheme.onSurfaceVariant), greaterThanOrEqualTo(TopGradient.minContrast), reason: '${brightness.name} ${color.name}', ); } } } }); test('is a deep shade of cobalt in dark mode, a tint in light mode', () { final dark = appTheme(Brightness.dark).colorScheme; final light = appTheme(Brightness.light).colorScheme; expect( TopGradient.topTone(dark, Brand.primary, dark.surface), Color.lerp( const Color(0xFF000000), Brand.primary, TopGradient.darkShade, ), ); expect( TopGradient.topTone(light, Brand.primary, light.surface), Color.lerp(light.surface, Brand.primary, TopGradient.lightMix), ); }); test('half as strong inside the panel', () { final dark = appTheme(Brightness.dark).colorScheme; final full = Color.lerp( const Color(0xFF000000), Brand.primary, TopGradient.darkShade, )!; expect( TopGradient.topTone( dark, Brand.primary, dark.surface, share: TopGradient.panelShare, ), Color.lerp(dark.surface, full, TopGradient.panelShare), ); }); test('mixes in less where the full share would be unreadable', () { final dark = appTheme(Brightness.dark).colorScheme; // Light text can't sit on a shade of white at 42 %. const white = Color(0xFFFFFFFF); final top = TopGradient.topTone(dark, white, dark.surface); expect( top, isNot( Color.lerp(const Color(0xFF000000), white, TopGradient.darkShade), ), ); expect( TopGradient.contrast(top, dark.onSurface), greaterThanOrEqualTo(TopGradient.minContrast), ); }); }); testWidgets('fades from the tone into the background below the status bar', ( tester, ) async { await tester.pumpWidget( MaterialApp( theme: appTheme(Brightness.dark), home: MediaQuery( data: const MediaQueryData(padding: EdgeInsets.only(top: 24)), child: Builder( builder: (context) => TopGradient( color: Brand.primary, background: Theme.of(context).colorScheme.surface, extent: 100, child: const SizedBox.expand(), ), ), ), ), ); final box = tester.widget( find.descendant( of: find.byType(TopGradient), matching: find.byType(DecoratedBox), ), ); final gradient = (box.decoration as BoxDecoration).gradient! as LinearGradient; final scheme = appTheme(Brightness.dark).colorScheme; expect(gradient.colors, [ TopGradient.topTone(scheme, Brand.primary, scheme.surface), scheme.surface, ]); expect(tester.getSize(find.byWidget(box)).height, 124); }); }