import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:fintracker_app/core/theme/app_theme.dart'; import 'package:fintracker_app/core/widgets/service_mark.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; Future _render(WidgetTester tester, double size) async { final key = GlobalKey(); tester.view.physicalSize = Size(size, size); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: Center( child: RepaintBoundary( key: key, child: ServiceMark(size: size), ), ), ), ); final boundary = key.currentContext!.findRenderObject()! as RenderRepaintBoundary; return (await tester.runAsync(() async { final image = await boundary.toImage(); return image.toByteData(format: ui.ImageByteFormat.rawRgba); }))!; } Color _at(ByteData data, int size, int x, int y) { final i = (y * size + x) * 4; return Color.fromARGB( data.getUint8(i + 3), data.getUint8(i), data.getUint8(i + 1), data.getUint8(i + 2), ); } void main() { testWidgets( 'a gradient disc with three white bars, and nothing outside the disc', (tester) async { const size = 256; final data = await _render(tester, size.toDouble()); // scale of the 512 design grid int px(num v) => (v * size / 512).round(); expect( _at(data, size, 2, 2).a, 0, reason: 'the corner is outside the disc', ); // the tallest bar (x 316..380, y 131..381): white in its middle expect(_at(data, size, px(348), px(256)), const Color(0xFFFFFFFF)); // between two bars the disc shows through, and it is coloured, not white final gap = _at(data, size, px(210), px(300)); expect(gap.a, 1); expect(gap.b, greaterThan(gap.r), reason: 'blue-violet, not grey'); // the gradient runs from the accent (top left) toward violet (bottom right) final start = _at(data, size, px(90), px(90)); final end = _at(data, size, px(430), px(430)); expect(end.r, greaterThan(start.r)); expect(start.b * 255, greaterThan(200)); expect( (start.g - end.g) * 255, greaterThan(40), reason: 'the green channel falls off toward violet', ); }, ); test('the near end of the gradient is the app accent', () { expect(AppTheme.seed, const Color(0xFF14AFFF)); expect(ServiceMark.violet, isNot(AppTheme.seed)); }); }