import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:rippr/src/ui/theme.dart'; /// V3-16's acceptance criterion is "contrast ratios meet WCAG AA for body text" -- /// asserted directly here rather than trusted from a palette chosen by eye. AA is 4.5:1 /// for normal text, 3:1 for large text (18pt, or 14pt bold and up -- the headline /// figures in `BigStat`). void main() { group('contrastRatio', () { test('black on white is the maximum possible ratio, 21:1', () { expect( contrastRatio(const Color(0xFF000000), const Color(0xFFFFFFFF)), closeTo(21.0, 0.01), ); }); test('a colour against itself is 1:1', () { const c = Color(0xFFFF5722); expect(contrastRatio(c, c), closeTo(1.0, 0.01)); }); test('is symmetric regardless of argument order', () { const a = Color(0xFF101418); const b = Color(0xFFF2F5F8); expect(contrastRatio(a, b), contrastRatio(b, a)); }); }); group('pocketed theme (WCAG AA)', () { final colors = ripprTheme().colorScheme; test('body text on the ground meets AA normal text (4.5:1)', () { expect(contrastRatio(colors.onSurface, ripprBackground), greaterThanOrEqualTo(4.5)); }); test('body text on a surface card meets AA normal text (4.5:1)', () { expect(contrastRatio(colors.onSurface, colors.surface), greaterThanOrEqualTo(4.5)); }); test('the primary accent on the ground meets AA large text (3:1)', () { // The accent is used for headline figures and buttons, not small body copy -- // held to the large-text threshold, matching how it's actually used on screen. expect(contrastRatio(colors.primary, ripprBackground), greaterThanOrEqualTo(3.0)); }); test('the instrument-blue tertiary on the ground meets AA large text (3:1)', () { expect(contrastRatio(colors.tertiary, ripprBackground), greaterThanOrEqualTo(3.0)); }); test('the instrument-blue tertiary on a surface card meets AA large text (3:1)', () { expect(contrastRatio(colors.tertiary, colors.surface), greaterThanOrEqualTo(3.0)); }); }); group('mounted theme (WCAG AA)', () { final colors = ripprMountedTheme().colorScheme; test('body text on the ground meets AA normal text (4.5:1)', () { expect( contrastRatio(colors.onSurface, ripprMountedBackground), greaterThanOrEqualTo(4.5), ); }); test('the primary accent on the ground meets AA large text (3:1) -- this is the ' 'theme sunlight legibility actually depends on', () { expect( contrastRatio(colors.primary, ripprMountedBackground), greaterThanOrEqualTo(3.0), ); }); test('the instrument-blue tertiary meets AA normal text on the ground ' '(darkened further than the pocketed theme specifically for this)', () { expect( contrastRatio(colors.tertiary, ripprMountedBackground), greaterThanOrEqualTo(4.5), ); }); }); }