Files
fin-tracker/app/test/service_mark_test.dart
T
Dmitry 62d36aa3e8 feat(app): новый визуальный язык, верхняя навигация, портфели, создание счетов и ручные события
Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
2026-09-19 22:14:21 +03:00

83 lines
2.6 KiB
Dart

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<ByteData> _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));
});
}