Commit 7ac2bfb

derdilla <derdilla06@gmail.com>
2023-07-15 18:33:05
move analysis functions from blood_pressure.dart to blood_pressure_analyzer.dart
1 parent 4a5eb30
lib/model/blood_pressure.dart
@@ -88,81 +88,10 @@ class BloodPressureModel extends ChangeNotifier {
     return UnmodifiableListView(_convert(await _database.query('bloodPressureModel', columns: ['*'])));
   }
 
-  Future<int> get count async {
-    return (await _database.rawQuery('SELECT COUNT(*) FROM bloodPressureModel'))[0]['COUNT(*)'] as int? ?? -1;
-  }
-
-  Future<DateTime> get firstDay async {
-    return DateTime.fromMillisecondsSinceEpoch(
-        (await _database.rawQuery('SELECT timestamp FROM bloodPressureModel ORDER BY timestamp ASC LIMIT 1'))[0]
-                ['timestamp'] as int? ??
-            -1);
-  }
-
-  Future<DateTime> get lastDay async {
-    return DateTime.fromMillisecondsSinceEpoch(
-        (await _database.rawQuery('SELECT timestamp FROM bloodPressureModel ORDER BY timestamp DESC LIMIT 1'))[0]
-                ['timestamp'] as int? ??
-            -1);
-  }
-
-  Future<int> get avgDia async {
-    var res = _toInt((await _database.rawQuery('SELECT AVG(diastolic) as dia FROM bloodPressureModel'))[0]['dia']);
-    return res ?? -1;
-  }
-
-  Future<int> get avgSys async {
-    var res = _toInt((await _database.rawQuery('SELECT AVG(systolic) as sys FROM bloodPressureModel'))[0]['sys']);
-    return res ?? -1;
-  }
-
-  Future<int> get avgPul async {
-    var res = _toInt((await _database.rawQuery('SELECT AVG(pulse) as pul FROM bloodPressureModel'))[0]['pul']);
-    return res ?? -1;
-  }
-
-  Future<int> get maxDia async {
-    var res = (await _database.rawQuery('SELECT MAX(diastolic) as dia FROM bloodPressureModel'))[0]['dia'];
-    return (res as int?) ?? -1;
-  }
-
-  Future<int> get maxSys async {
-    var res = (await _database.rawQuery('SELECT MAX(systolic) as sys FROM bloodPressureModel'))[0]['sys'];
-    return (res as int?) ?? -1;
-  }
-
-  Future<int> get maxPul async {
-    var res = (await _database.rawQuery('SELECT MAX(pulse) as pul FROM bloodPressureModel'))[0]['pul'];
-    return (res as int?) ?? -1;
-  }
-
-  Future<int> get minDia async {
-    var res = (await _database.rawQuery('SELECT MIN(diastolic) as dia FROM bloodPressureModel'))[0]['dia'];
-    return (res as int?) ?? -1;
-  }
-
-  Future<int> get minSys async {
-    var res = (await _database.rawQuery('SELECT MIN(systolic) as sys FROM bloodPressureModel'))[0]['sys'];
-    return (res as int?) ?? -1;
-  }
-
-  Future<int> get minPul async {
-    var res = (await _database.rawQuery('SELECT MIN(pulse) as pul FROM bloodPressureModel'))[0]['pul'];
-    return (res as int?) ?? -1;
-  }
-
   void close() {
     _database.close();
   }
 
-  int? _toInt(Object? v) {
-    try {
-      return (v as int?);
-    } catch (e) {
-      return (v as double?)?.toInt();
-    }
-  }
-
   List<BloodPressureRecord> _convert(List<Map<String, Object?>> dbResult) {
     List<BloodPressureRecord> records = [];
     for (var e in dbResult) {
lib/model/blood_pressure_analyzer.dart
@@ -1,17 +1,53 @@
+import 'dart:math';
+
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:collection/collection.dart';
 
 class BloodPressureAnalyser {
-  final BloodPressureModel _model;
+  final List<BloodPressureRecord> _records;
+
+  BloodPressureAnalyser(this._records);
+
+  int get count => _records.length;
+
+  int get avgDia => _nonNullDia.reduce((a, b) => a + b) ~/ _nonNullDia.length;
+
+  int get avgPul => _nonNullPul.reduce((a, b) => a + b) ~/ _nonNullPul.length;
+
+  int get avgSys => _nonNullSys.reduce((a, b) => a + b) ~/ _nonNullSys.length;
+
+  int get maxDia => _nonNullDia.reduce(max);
+
+  int get maxPul => _nonNullPul.reduce(max);
+
+  int get maxSys => _nonNullSys.reduce(max);
+
+  int get minDia => _nonNullDia.reduce(min);
+
+  int get minPul => _nonNullPul.reduce(min);
+
+  int get minSys => _nonNullSys.reduce(min);
+
+  DateTime get firstDay {
+    _records.sort((a, b) => a.creationTime.compareTo(b.creationTime));
+    return _records.first.creationTime;
+  }
+
+  DateTime get lastDay {
+    _records.sort((a, b) => a.creationTime.compareTo(b.creationTime));
+    return _records.last.creationTime;
+  }
 
-  BloodPressureAnalyser(this._model);
+  Iterable<int> get _nonNullDia => _records.where((e) => e.diastolic!=null).map<int>((e) => e.diastolic!);
+  Iterable<int> get _nonNullSys => _records.where((e) => e.systolic!=null).map<int>((e) => e.systolic!);
+  Iterable<int> get _nonNullPul => _records.where((e) => e.pulse!=null).map<int>((e) => e.pulse!);
 
-  Future<int> get measurementsPerDay async {
-    final c = await _model.count;
+  int get measurementsPerDay {
+    final c = count;
     if (c <= 1) return -1;
 
-    final firstDay = await _model.firstDay;
-    final lastDay = await _model.lastDay;
+    final firstDay = this.firstDay;
+    final lastDay = this.lastDay;
 
     if (firstDay.millisecondsSinceEpoch == -1 || lastDay.millisecondsSinceEpoch == -1) {
       return -1;
@@ -25,7 +61,7 @@ class BloodPressureAnalyser {
 
   /// outer list is type (0 -> diastolic, 1 -> systolic, 2 -> pulse)
   /// inner list index is hour of day ([0] -> 00:00-00:59; [1] -> ...)
-  Future<List<List<int>>> get allAvgsRelativeToDaytime async {
+  List<List<int>> get allAvgsRelativeToDaytime {
     // setup vars
     List<List<int>> allDiaValuesRelativeToTime = [];
     List<List<int>> allSysValuesRelativeToTime = [];
@@ -37,7 +73,7 @@ class BloodPressureAnalyser {
     }
 
     // sort all data
-    final dbRes = await _model.all;
+    final dbRes = _records;
     for (var e in dbRes) {
       DateTime ts = DateTime.fromMillisecondsSinceEpoch(e.creationTime.millisecondsSinceEpoch);
       if (e.diastolic != null) allDiaValuesRelativeToTime[ts.hour].add(e.diastolic!);
@@ -46,13 +82,13 @@ class BloodPressureAnalyser {
     }
     for (int i = 0; i < 24; i++) {
       if (allDiaValuesRelativeToTime[i].isEmpty) {
-        allDiaValuesRelativeToTime[i].add(await _model.avgDia);
+        allDiaValuesRelativeToTime[i].add(avgDia);
       }
       if (allSysValuesRelativeToTime[i].isEmpty) {
-        allSysValuesRelativeToTime[i].add(await _model.avgSys);
+        allSysValuesRelativeToTime[i].add(avgSys);
       }
       if (allPulValuesRelativeToTime[i].isEmpty) {
-        allPulValuesRelativeToTime[i].add(await _model.avgPul);
+        allPulValuesRelativeToTime[i].add(avgPul);
       }
     }
 
lib/model/ram_only_implementations.dart
@@ -1,5 +1,4 @@
 import 'dart:collection';
-import 'dart:math';
 
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/export_import.dart';
@@ -35,52 +34,6 @@ class RamBloodPressureModel extends ChangeNotifier implements BloodPressureModel
   @override
   Future<UnmodifiableListView<BloodPressureRecord>> get all async => UnmodifiableListView(_records);
 
-  @override
-  Future<int> get count async => _records.length;
-
-  @override
-  Future<int> get avgDia async => _nonNullDia.reduce((a, b) => a + b) ~/ _nonNullDia.length;
-
-  @override
-  Future<int> get avgPul async => _nonNullPul.reduce((a, b) => a + b) ~/ _nonNullPul.length;
-
-  @override
-  Future<int> get avgSys async => _nonNullSys.reduce((a, b) => a + b) ~/ _nonNullSys.length;
-
-  @override
-  Future<int> get maxDia async => _nonNullDia.reduce(max);
-
-  @override
-  Future<int> get maxPul async => _nonNullPul.reduce(max);
-
-  @override
-  Future<int> get maxSys async => _nonNullSys.reduce(max);
-
-  @override
-  Future<int> get minDia async => _nonNullDia.reduce(min);
-
-  @override
-  Future<int> get minPul async => _nonNullPul.reduce(min);
-
-  @override
-  Future<int> get minSys async => _nonNullSys.reduce(min);
-
-  @override
-  Future<DateTime> get firstDay async {
-    _records.sort((a, b) => a.creationTime.compareTo(b.creationTime));
-    return _records.first.creationTime;
-  }
-
-  @override
-  Future<DateTime> get lastDay async {
-    _records.sort((a, b) => a.creationTime.compareTo(b.creationTime));
-    return _records.last.creationTime;
-  }
-
-  Iterable<int> get _nonNullDia => _records.where((e) => e.diastolic!=null).map<int>((e) => e.diastolic!);
-  Iterable<int> get _nonNullSys => _records.where((e) => e.systolic!=null).map<int>((e) => e.systolic!);
-  Iterable<int> get _nonNullPul => _records.where((e) => e.pulse!=null).map<int>((e) => e.pulse!);
-
   @override
   void close() {}
 }
lib/screens/subsettings/export_import_screen.dart
@@ -1,5 +1,6 @@
 import 'package:blood_pressure_app/components/settings_widgets.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/blood_pressure_analyzer.dart';
 import 'package:blood_pressure_app/model/export_import.dart';
 import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:flutter/material.dart';
@@ -129,7 +130,9 @@ class ExportDataRangeSettings extends StatelessWidget {
             disabled: !settings.exportLimitDataRange || settings.exportFormat == ExportFormat.db,
             onPressed: (context) async {
               var model = Provider.of<BloodPressureModel>(context, listen: false);
-              var newRange = await showDateRangePicker(context: context, firstDate: await model.firstDay, lastDate: await model.lastDay);
+              var analyzer = BloodPressureAnalyser(await model.all);
+              if(!context.mounted) return;
+              var newRange = await showDateRangePicker(context: context, firstDate: analyzer.firstDay, lastDate: analyzer.lastDay);
               if (newRange == null && context.mounted) {
                 ScaffoldMessenger.of(context)
                     .showSnackBar(SnackBar(content: Text(AppLocalizations.of(context)!.errNoRangeForExport)));
lib/screens/statistics.dart
@@ -1,3 +1,5 @@
+import 'dart:collection';
+
 import 'package:blood_pressure_app/components/consistent_future_builder.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/blood_pressure_analyzer.dart';
@@ -7,6 +9,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:provider/provider.dart';
 
+// TODO: rewrite to be smaller is possible
 class StatisticsPage extends StatelessWidget {
   const StatisticsPage({super.key});
 
@@ -19,120 +22,125 @@ class StatisticsPage extends StatelessWidget {
       ),
       body: SingleChildScrollView(child: Consumer<BloodPressureModel>(
         builder: (context, model, child) {
-          return Consumer<Settings>(builder: (context, settings, child) {
-            return Column(
-              children: [
-                Statistic(
-                    key: const Key('measurementCount'),
-                    caption: Text(AppLocalizations.of(context)!.measurementCount), child: futureInt(model.count)),
-                // special measurements
-                StatisticsRow(
-                  caption1: Text(
-                    AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.sysLong),
-                    style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
-                  ),
-                  child1: futureInt(model.avgSys),
-                  caption2: Text(
-                    AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.diaLong),
-                    style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
-                  ),
-                  child2: futureInt(model.avgDia),
-                  caption3: Text(
-                    AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.pulLong),
-                    style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
-                  ),
-                  child3: futureInt(model.avgPul),
-                ),
-                Statistic(
-                    caption: Text(AppLocalizations.of(context)!.measurementsPerDay),
-                    child: futureInt(BloodPressureAnalyser(model).measurementsPerDay)),
-                StatisticsRow(
-                  caption1: Text(
-                    AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.sysLong),
-                    style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
-                  ),
-                  child1: futureInt(model.minSys),
-                  caption2: Text(
-                    AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.diaLong),
-                    style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
-                  ),
-                  child2: futureInt(model.minDia),
-                  caption3: Text(
-                    AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.pulLong),
-                    style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
-                  ),
-                  child3: futureInt(model.minPul),
-                ),
-                StatisticsRow(
-                  caption2: Text(
-                    AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.diaLong),
-                    style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
-                  ),
-                  child2: futureInt(model.maxDia),
-                  caption1: Text(
-                    AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.sysLong),
-                    style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
-                  ),
-                  child1: futureInt(model.maxSys),
-                  caption3: Text(
-                    AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.pulLong),
-                    style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
-                  ),
-                  child3: futureInt(model.maxPul),
-                ),
-                // Time-Resolved Metrics
-                Statistic(
-                  caption: Text(AppLocalizations.of(context)!.timeResolvedMetrics),
-                  child: ConsistentFutureBuilder<List<List<int>>>(
-                      future: BloodPressureAnalyser(model).allAvgsRelativeToDaytime,
-                      onData: (context, data) {
-                        const opacity = 0.5;
-                        return SizedBox(
-                          width: 500,
-                          height: 500,
-                          child: RadarChart(
-                            RadarChartData(
-                              radarShape: RadarShape.circle,
-                              radarBorderData: const BorderSide(color: Colors.transparent),
-                              gridBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
-                              tickBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
-                              ticksTextStyle: const TextStyle(color: Colors.transparent),
-                              tickCount: 5,
-                              titleTextStyle: const TextStyle(fontSize: 25),
-                              getTitle: (pos, value) {
-                                if (pos % 2 == 0) {
-                                  return RadarChartTitle(text: '$pos', positionPercentageOffset: 0.05);
-                                }
-                                return const RadarChartTitle(text: '');
-                              },
-                              dataSets: [
-                                RadarDataSet(
-                                    dataEntries: intListToRadarEntry(data[0]),
-                                    borderColor: settings.diaColor,
-                                    fillColor: settings.diaColor.withOpacity(opacity),
-                                    entryRadius: 0,
-                                    borderWidth: settings.graphLineThickness),
-                                RadarDataSet(
-                                    dataEntries: intListToRadarEntry(data[1]),
-                                    borderColor: settings.sysColor,
-                                    fillColor: settings.sysColor.withOpacity(opacity),
-                                    entryRadius: 0,
-                                    borderWidth: settings.graphLineThickness),
-                                RadarDataSet(
-                                    dataEntries: intListToRadarEntry(data[2]),
-                                    borderColor: settings.pulColor,
-                                    fillColor: settings.pulColor.withOpacity(opacity),
-                                    entryRadius: 0,
-                                    borderWidth: settings.graphLineThickness),
-                              ],
+          return ConsistentFutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
+              future: model.all, 
+              onData: (context, data) {
+                return Consumer<Settings>(builder: (context, settings, child) {
+                  final analyzer = BloodPressureAnalyser(data);
+                  return Column(
+                    children: [
+                      Statistic(
+                          key: const Key('measurementCount'),
+                          caption: Text(AppLocalizations.of(context)!.measurementCount), child: displayInt(analyzer.count)),
+                      // special measurements
+                      StatisticsRow(
+                        caption1: Text(
+                          AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.sysLong),
+                          style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
+                        ),
+                        child1: displayInt(analyzer.avgSys),
+                        caption2: Text(
+                          AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.diaLong),
+                          style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
+                        ),
+                        child2: displayInt(analyzer.avgDia),
+                        caption3: Text(
+                          AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.pulLong),
+                          style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+                        ),
+                        child3: displayInt(analyzer.avgPul),
+                      ),
+                      Statistic(
+                          caption: Text(AppLocalizations.of(context)!.measurementsPerDay),
+                          child: displayInt(analyzer.measurementsPerDay)),
+                      StatisticsRow(
+                        caption1: Text(
+                          AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.sysLong),
+                          style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
+                        ),
+                        child1: displayInt(analyzer.minSys),
+                        caption2: Text(
+                          AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.diaLong),
+                          style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
+                        ),
+                        child2: displayInt(analyzer.minDia),
+                        caption3: Text(
+                          AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.pulLong),
+                          style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+                        ),
+                        child3: displayInt(analyzer.minPul),
+                      ),
+                      StatisticsRow(
+                        caption2: Text(
+                          AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.diaLong),
+                          style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
+                        ),
+                        child2: displayInt(analyzer.maxDia),
+                        caption1: Text(
+                          AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.sysLong),
+                          style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
+                        ),
+                        child1: displayInt(analyzer.maxSys),
+                        caption3: Text(
+                          AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.pulLong),
+                          style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+                        ),
+                        child3: displayInt(analyzer.maxPul),
+                      ),
+                      // Time-Resolved Metrics
+                      Statistic(
+                        caption: Text(AppLocalizations.of(context)!.timeResolvedMetrics),
+                        child: (() {
+                          final data = analyzer.allAvgsRelativeToDaytime;
+                          const opacity = 0.5;
+                          return SizedBox(
+                            width: 500,
+                            height: 500,
+                            child: RadarChart(
+                              RadarChartData(
+                                radarShape: RadarShape.circle,
+                                radarBorderData: const BorderSide(color: Colors.transparent),
+                                gridBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
+                                tickBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
+                                ticksTextStyle: const TextStyle(color: Colors.transparent),
+                                tickCount: 5,
+                                titleTextStyle: const TextStyle(fontSize: 25),
+                                getTitle: (pos, value) {
+                                  if (pos % 2 == 0) {
+                                    return RadarChartTitle(text: '$pos', positionPercentageOffset: 0.05);
+                                  }
+                                  return const RadarChartTitle(text: '');
+                                },
+                                dataSets: [
+                                  RadarDataSet(
+                                      dataEntries: intListToRadarEntry(data[0]),
+                                      borderColor: settings.diaColor,
+                                      fillColor: settings.diaColor.withOpacity(opacity),
+                                      entryRadius: 0,
+                                      borderWidth: settings.graphLineThickness),
+                                  RadarDataSet(
+                                      dataEntries: intListToRadarEntry(data[1]),
+                                      borderColor: settings.sysColor,
+                                      fillColor: settings.sysColor.withOpacity(opacity),
+                                      entryRadius: 0,
+                                      borderWidth: settings.graphLineThickness),
+                                  RadarDataSet(
+                                      dataEntries: intListToRadarEntry(data[2]),
+                                      borderColor: settings.pulColor,
+                                      fillColor: settings.pulColor.withOpacity(opacity),
+                                      entryRadius: 0,
+                                      borderWidth: settings.graphLineThickness),
+                                ],
+                              ),
                             ),
-                          ),
-                        );
-                      }),
-                ),
-              ],
-            );
-          });
+                          );
+                        })(),
+                      ),
+                    ],
+                  );
+                });
+              }
+          );
         },
       )),
     );
@@ -257,14 +265,9 @@ class StatisticsRow extends StatelessWidget {
   }
 }
 
-Widget futureInt(Future<int> value) {
-  return ConsistentFutureBuilder<int>(
-      future: value,
-      onData: (context, data) {
-        if (data < 0) {
-          return const Text('-');
-        }
-        return Text(data.toString());
-      }
-  );
+Widget displayInt(int value) {
+  if (value < 0) {
+    return const Text('-');
+  }
+  return Text(value.toString());
 }
test/model/analyzer_test.dart
@@ -0,0 +1,65 @@
+
+import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/blood_pressure_analyzer.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+  group('BloodPressureAnalyser', () {
+    test('should return averages', () async {
+      var m = BloodPressureAnalyser([
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 122, 87, 65, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, '')
+      ]);
+
+      expect(m.avgSys, 111);
+      expect(m.avgDia, 73);
+      expect(m.avgPul, 66);
+    });
+
+    test('should return max', () async {
+      var a = BloodPressureAnalyser([
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 123, 87, 65, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(4), 111, 73, 73, '')
+      ]);
+
+      expect(a.maxSys, 123);
+      expect(a.maxDia, 87);
+      expect(a.maxPul, 73);
+    });
+
+    test('should return min', () async {
+      var a = BloodPressureAnalyser([
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 123, 87, 65, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(4), 100, 60, 62, '')
+      ]);
+
+      expect(a.minSys, 100);
+      expect(a.minDia, 60);
+      expect(a.minPul, 62);
+    });
+
+    test('should know count', () async {
+      var m = BloodPressureAnalyser([
+        for (int i = 1; i < 101; i++)
+          BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(i), 0, 0, 0, '')
+      ]);
+      expect(m.count, 100);
+    });
+
+    test('should determine special days', () async {
+      var m = BloodPressureAnalyser([BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(100), 0, 0, 0, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(-2200), 0, 0, 0, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(9000000), 0, 0, 0, ''),
+        BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3124159), 0, 0, 0, ''),
+      ]);
+      
+      expect((m.firstDay), DateTime.fromMillisecondsSinceEpoch(-2200));
+      expect((m.lastDay), DateTime.fromMillisecondsSinceEpoch(9000000));
+    });
+  });
+}
\ No newline at end of file
test/model/bood_pressure_test.dart
@@ -95,66 +95,6 @@ void main() {
       expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(0), DateTime.now())).length, 0);
       expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(0), DateTime.now())).length, 0);
     });
-
-    test('should return averages', () async {
-      var m = await BloodPressureModel.create(dbPath: '/tmp/bp_test/should_avg');
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 122, 87, 65, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''));
-
-      expect(await m.avgSys, 111); // 111 // gets 116
-      expect(await m.avgDia, 73); // 73.3333...
-      expect(await m.avgPul, 66); // 66.6666...
-    });
-
-    test('should return max', () async {
-      var m = await BloodPressureModel.create(dbPath: '/tmp/bp_test/should_max');
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 123, 87, 65, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(4), 111, 73, 73, ''));
-
-      expect(await m.maxSys, 123);
-      expect(await m.maxDia, 87);
-      expect(await m.maxPul, 73);
-    });
-
-    test('should return min', () async {
-      var m = await BloodPressureModel.create(dbPath: '/tmp/bp_test/should_min');
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 123, 87, 65, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(4), 100, 60, 62, ''));
-
-      expect(await m.minSys, 100);
-      expect(await m.minDia, 60);
-      expect(await m.minPul, 62);
-    });
-
-    test('should know count', () async {
-      var m = await BloodPressureModel.create(dbPath: '/tmp/bp_test/should_count');
-
-      for (int i = 1; i < 101; i++) {
-        await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(i), 0, 0, 0, ''));
-      }
-
-      expect(await m.count, 100);
-    });
-
-    test('should determine special days', () async {
-      var m = await BloodPressureModel.create(dbPath: '/tmp/bp_test/should_special_days');
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(100), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(-2200), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(9000000), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3124159), 0, 0, 0, ''));
-
-      expect((await m.firstDay), DateTime.fromMillisecondsSinceEpoch(-2200));
-      expect((await m.lastDay), DateTime.fromMillisecondsSinceEpoch(9000000));
-    });
   });
 
   group("RamBloodPressureModel should behave like BloodPressureModel", () {
@@ -200,65 +140,5 @@ void main() {
 
       m.add(r);
     });
-
-    test('should return averages', () async {
-      var m = RamBloodPressureModel();
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 122, 87, 65, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''));
-
-      expect(await m.avgSys, 111); // 111 // gets 116
-      expect(await m.avgDia, 73); // 73.3333...
-      expect(await m.avgPul, 66); // 66.6666...
-    });
-
-    test('should return max', () async {
-      var m = RamBloodPressureModel();
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 123, 87, 65, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(4), 111, 73, 73, ''));
-
-      expect(await m.maxSys, 123);
-      expect(await m.maxDia, 87);
-      expect(await m.maxPul, 73);
-    });
-
-    test('should return min', () async {
-      var m = RamBloodPressureModel();
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 123, 87, 65, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 100, 60, 62, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3), 111, 73, 73, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(4), 100, 60, 62, ''));
-
-      expect(await m.minSys, 100);
-      expect(await m.minDia, 60);
-      expect(await m.minPul, 62);
-    });
-
-    test('should know count', () async {
-      var m = RamBloodPressureModel();
-
-      for (int i = 1; i < 101; i++) {
-        await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(i), 0, 0, 0, ''));
-      }
-
-      expect(await m.count, 100);
-    });
-
-    test('should determine special days', () async {
-      var m = RamBloodPressureModel();
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(100), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(-2200), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(9000000), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(3124159), 0, 0, 0, ''));
-
-      expect((await m.firstDay), DateTime.fromMillisecondsSinceEpoch(-2200));
-      expect((await m.lastDay), DateTime.fromMillisecondsSinceEpoch(9000000));
-    });
   });
 }