main
  1import 'package:blood_pressure_app/features/statistics/value_graph.dart';
  2import 'package:blood_pressure_app/model/horizontal_graph_line.dart';
  3import 'package:blood_pressure_app/model/storage/storage.dart';
  4import 'package:collection/collection.dart';
  5import 'package:flutter/material.dart';
  6import 'package:blood_pressure_app/l10n/app_localizations.dart';
  7import 'package:flutter_test/flutter_test.dart';
  8import 'package:health_data_store/health_data_store.dart';
  9import 'package:provider/provider.dart';
 10
 11import '../../model/analyzer_test.dart';
 12import '../../util.dart';
 13import '../measurement_list/measurement_list_entry_test.dart';
 14
 15void main() {
 16  test('Creates correct sys series', () {
 17    final records = [
 18      mockRecord(time: DateTime(2000), sys: 123),
 19      mockRecord(time: DateTime(2001), sys: 120),
 20      // ignore: avoid_redundant_argument_values
 21      mockRecord(time: DateTime(2002), sys: null),
 22      mockRecord(time: DateTime(2003), sys: 123),
 23      mockRecord(time: DateTime(2004), sys: 200),
 24    ];
 25    assert(records.isSorted((a, b) => a.time.compareTo(b.time)));
 26
 27    final graph = records.sysGraph();
 28    expect(graph, hasLength(4));
 29    expect(graph.isSorted((a, b) => a.$1.compareTo(b.$1)), isTrue);
 30    expect(graph.elementAt(0).$2, 123);
 31    expect(graph.elementAt(1).$2, 120);
 32    expect(graph.elementAt(2).$2, 123);
 33    expect(graph.elementAt(3).$2, 200);
 34  });
 35  test('Creates correct dia series', () {
 36    final records = [
 37      mockRecord(time: DateTime(2000), dia: 123),
 38      mockRecord(time: DateTime(2001), dia: 120),
 39      // ignore: avoid_redundant_argument_values
 40      mockRecord(time: DateTime(2002), dia: null),
 41      mockRecord(time: DateTime(2003), dia: 123),
 42      mockRecord(time: DateTime(2004), dia: 200),
 43    ];
 44    assert(records.isSorted((a, b) => a.time.compareTo(b.time)));
 45
 46    final graph = records.diaGraph();
 47    expect(graph, hasLength(4));
 48    expect(graph.isSorted((a, b) => a.$1.compareTo(b.$1)), isTrue);
 49    expect(graph.elementAt(0).$2, 123);
 50    expect(graph.elementAt(1).$2, 120);
 51    expect(graph.elementAt(2).$2, 123);
 52    expect(graph.elementAt(3).$2, 200);
 53  });
 54  test('Creates correct pul series', () {
 55    final records = [
 56      mockRecord(time: DateTime(2000), pul: 123),
 57      mockRecord(time: DateTime(2001), pul: 120),
 58      // ignore: avoid_redundant_argument_values
 59      mockRecord(time: DateTime(2002), pul: null),
 60      mockRecord(time: DateTime(2003), pul: 123),
 61      mockRecord(time: DateTime(2004), pul: 200),
 62    ];
 63    assert(records.isSorted((a, b) => a.time.compareTo(b.time)));
 64
 65    final graph = records.pulGraph();
 66    expect(graph, hasLength(4));
 67    expect(graph.isSorted((a, b) => a.$1.compareTo(b.$1)), isTrue);
 68    expect(graph.elementAt(0).$2, 123.0);
 69    expect(graph.elementAt(1).$2, 120.0);
 70    expect(graph.elementAt(2).$2, 123.0);
 71    expect(graph.elementAt(3).$2, 200.0);
 72  });
 73  testWidgets('BloodPressureValueGraph shows when there are not enough values', (tester) async {
 74    await tester.pumpWidget(_buildGraph([], [], []));
 75    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 76    expect(find.text(localizations.errNotEnoughDataToGraph), findsOneWidget);
 77  });
 78  testWidgets('[gold] graph with all extras is rendered correctly', (tester) async {
 79    await tester.pumpWidget(_buildGraph([
 80      mockRecord(time: DateTime(2005), sys: 123, dia: 80, pul: 50),
 81      mockRecord(time: DateTime(2003), sys: 110, dia: 73, pul: 130),
 82      mockRecord(time: DateTime(2003, 5), sys: 140, dia: 74, pul: 64),
 83      mockRecord(time: DateTime(2007), sys: 132, dia: 100, pul: 75),
 84    ], [
 85      (DateTime(2005), Colors.purple),
 86      (DateTime(2005, 3), Colors.tealAccent),
 87      (DateTime(2007), Colors.yellow),
 88    ], [
 89      mockIntake(mockMedicine(color: Colors.blueGrey), time: DateTime(2005).millisecondsSinceEpoch),
 90      mockIntake(mockMedicine(color: Colors.indigoAccent), time: DateTime(2004).millisecondsSinceEpoch),
 91    ],
 92    settings: Settings(
 93      drawRegressionLines: true,
 94      graphLineThickness: 3.2,
 95      diaWarn: 75,
 96      needlePinBarWidth: 7.0,
 97      horizontalGraphLines: [
 98        HorizontalGraphLine(Colors.lightBlue, 113),
 99        HorizontalGraphLine(Colors.amber, 45),
100      ]
101    )));
102    await tester.pumpAndSettle();
103    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
104    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
105
106    await expectLater(find.byType(BloodPressureValueGraph), myMatchesGoldenFile('full_graph-years.png'));
107  }, tags: 'gold');
108
109  testWidgets('BloodPressureValueGraph is fine with enough values in sys category', (tester) async {
110    await tester.pumpWidget(_buildGraph([
111      mockRecord(time: DateTime(2005), sys: 123),
112      mockRecord(time: DateTime(2003), sys: 110),
113    ], [], []));
114    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
115    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
116  });
117  testWidgets('BloodPressureValueGraph is fine with enough values in dia category', (tester) async {
118    await tester.pumpWidget(_buildGraph([
119      mockRecord(time: DateTime(2005), dia: 123),
120      mockRecord(time: DateTime(2003), dia: 110),
121    ], [], []));
122    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
123    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
124  });
125  testWidgets('BloodPressureValueGraph is fine with enough values in pul category', (tester) async {
126    await tester.pumpWidget(_buildGraph([
127      mockRecord(time: DateTime(2005), pul: 123),
128      mockRecord(time: DateTime(2003), pul: 110),
129    ], [], []));
130    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
131    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
132  });
133
134  testWidgets('[gold] graph renders area at start correctly', (tester) async {
135    await tester.pumpWidget(_buildGraph([
136        mockRecord(time: DateTime(2003), sys: 170, dia: 100, pul: 50),
137        mockRecord(time: DateTime(2005), sys: 110, dia: 70, pul: 50),
138      ], [], [],
139      settings: Settings(
140        diaWarn: 75,
141        sysWarn: 120,
142      ),
143    ));
144    await tester.pumpAndSettle();
145    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
146    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
147
148    await expectLater(find.byType(BloodPressureValueGraph), myMatchesGoldenFile('value-graph-start-warn.png'));
149  }, tags: 'gold');
150  testWidgets('[gold] graph renders area at end correctly', (tester) async {
151    await tester.pumpWidget(_buildGraph([
152      mockRecord(time: DateTime(2005), sys: 170, dia: 100, pul: 50),
153      mockRecord(time: DateTime(2003), sys: 110, dia: 70, pul: 50),
154    ], [], [],
155      settings: Settings(
156        diaWarn: 75,
157        sysWarn: 120,
158      ),
159    ));
160    await tester.pumpAndSettle();
161    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
162    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
163
164    await expectLater(find.byType(BloodPressureValueGraph), myMatchesGoldenFile('value-graph-end-warn.png'));
165  }, tags: 'gold');
166  testWidgets('[gold] warn area not drawn above graph', (tester) async {
167    await tester.pumpWidget(_buildGraph([
168      mockRecord(time: DateTime(2005), sys: 103, dia: null, pul: null),
169      mockRecord(time: DateTime(2003), sys: 89, dia: null, pul: null),
170    ], [], [],
171      settings: Settings(sysWarn: 120),
172    ));
173    await tester.pumpAndSettle();
174    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
175    expect(find.text(localizations.errNotEnoughDataToGraph), findsNothing);
176
177    await expectLater(find.byType(BloodPressureValueGraph), myMatchesGoldenFile('value-graph-warn-not-above.png'));
178  }, tags: 'gold');
179}
180
181Widget _buildGraph(
182  List<BloodPressureRecord> data,
183  List<(DateTime, Color)> colors,
184  List<MedicineIntake> intakes, {
185  Settings? settings,
186}) => materialApp(ChangeNotifierProvider<Settings>.value(
187  value: settings ?? Settings(),
188  child: SizedBox(
189    width: 500,
190    height: 300,
191    child: BloodPressureValueGraph(
192      records: data,
193      colors: colors.map((e) => Note(time: e.$1, color: e.$2.toARGB32())).toList(),
194      intakes: intakes,
195    ),
196  ),
197));