Commit 5daf379
Changed files (5)
lib
model
blood_pressure
test
lib/model/blood_pressure/medicine/medicine.dart
@@ -23,10 +23,10 @@ class Medicine {
String toJson() => jsonEncode(toMap());
factory Medicine.fromMap(Map<String, dynamic> map) => Medicine(
- map['id'],
- designation: map['designation'],
- color: Color(map['color']),
- defaultDosis: map['defaultDosis']
+ map['id'],
+ designation: map['designation'],
+ color: Color(map['color']),
+ defaultDosis: map['defaultDosis']
);
factory Medicine.fromJson(String json) => Medicine.fromMap(jsonDecode(json));
lib/model/blood_pressure/medicine/medicine_intake.dart
@@ -10,6 +10,22 @@ class MedicineIntake implements Comparable<Object> {
required this.timestamp
});
+ /// Serialize the object to a deserializable string.
+ ///
+ /// The string consists of the id of the medicine, the unix timestamp and the
+ /// dosis. These values are seperated by a null byte
+ String serialize() =>
+ '${medicine.id}\x00${timestamp.millisecondsSinceEpoch}\x00$dosis';
+
+ factory MedicineIntake.deserialize(String string, List<Medicine> availableMeds) {
+ final elements = string.split('\x00');
+ return MedicineIntake(
+ medicine: availableMeds.firstWhere((e) => e.id == int.parse(elements[0])),
+ timestamp: DateTime.fromMillisecondsSinceEpoch(int.parse(elements[1])),
+ dosis: double.parse(elements[2]),
+ );
+ }
+
/// Kind of medicine taken.
final Medicine medicine;
@@ -41,4 +57,9 @@ class MedicineIntake implements Comparable<Object> {
return dosis.compareTo(other.dosis);
}
+
+ @override
+ String toString() {
+ return 'MedicineIntake{medicine: $medicine, dosis: $dosis, timestamp: $timestamp}';
+ }
}
\ No newline at end of file
test/model/medicine/intake_history_test.dart
@@ -1,10 +1,8 @@
import 'package:blood_pressure_app/model/blood_pressure/medicine/intake_history.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
-import 'medicine_test.dart';
+import 'medicine_intake_test.dart';
void main() {
group('IntakeHistory', () {
@@ -152,18 +150,4 @@ void main() {
expect(found.length, 0);
});
});
-}
-
-/// Create a mock intake.
-///
-/// [timeMs] creates the intake timestamp through [DateTime.fromMillisecondsSinceEpoch].
-/// When is null [DateTime.now] is used.
-MedicineIntake mockIntake({
- double dosis = 0,
- int? timeMs,
- Medicine? medicine
-}) => MedicineIntake(
- medicine: medicine ?? mockMedicine(),
- dosis: dosis,
- timestamp: timeMs == null ? DateTime.now() : DateTime.fromMillisecondsSinceEpoch(timeMs)
-);
\ No newline at end of file
+}
\ No newline at end of file
test/model/medicine/medicine_intake_test.dart
@@ -0,0 +1,63 @@
+import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine.dart';
+import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'medicine_test.dart';
+
+void main() {
+ group('MedicineIntake', () {
+ test('should determine equality', () {
+ const med = Medicine(1, designation: 'designation', color: Colors.red, defaultDosis: 123);
+ final int1 = MedicineIntake(medicine: med, dosis: 10, timestamp: DateTime.fromMillisecondsSinceEpoch(123));
+ final int2 = MedicineIntake(medicine: med, dosis: 10, timestamp: DateTime.fromMillisecondsSinceEpoch(123));
+ expect(int1, int2);
+ });
+ test('should determine inequality', () {
+ const med1 = Medicine(1, designation: 'designation', color: Colors.red, defaultDosis: 123);
+ const med2 = Medicine(2, designation: 'designation', color: Colors.red, defaultDosis: 123);
+ final int1 = MedicineIntake(medicine: med1, dosis: 10, timestamp: DateTime.fromMillisecondsSinceEpoch(123));
+ final int2 = MedicineIntake(medicine: med2, dosis: 10, timestamp: DateTime.fromMillisecondsSinceEpoch(123));
+ expect(int1, isNot(int2));
+ final int3 = MedicineIntake(medicine: med1, dosis: 11, timestamp: DateTime.fromMillisecondsSinceEpoch(123));
+ expect(int1, isNot(int3));
+ final int4 = MedicineIntake(medicine: med1, dosis: 10, timestamp: DateTime.fromMillisecondsSinceEpoch(124));
+ expect(int1, isNot(int4));
+ });
+ test('should deserialize serialized intake', () {
+ final intake = mockIntake(timeMs: 543210);
+ expect(MedicineIntake.deserialize(intake.serialize(), [intake.medicine]), intake);
+
+ final intake2 = mockIntake(
+ timeMs: 543211,
+ dosis: 1000231,
+ medicine: mockMedicine(designation: 'tst')
+ );
+ expect(MedicineIntake.deserialize(
+ intake2.serialize(),
+ [intake.medicine, intake2.medicine]),
+ intake2);
+ });
+ test('should fail to deserialize serialized intake without exising med', () {
+ final intake = mockIntake(medicine: mockMedicine(designation: 'tst'));
+ expect(() => MedicineIntake.deserialize(
+ intake.serialize(),
+ [mockMedicine()]),
+ throwsStateError);
+ });
+ });
+}
+
+/// Create a mock intake.
+///
+/// [timeMs] creates the intake timestamp through [DateTime.fromMillisecondsSinceEpoch].
+/// When is null [DateTime.now] is used.
+MedicineIntake mockIntake({
+ double dosis = 0,
+ int? timeMs,
+ Medicine? medicine
+}) => MedicineIntake(
+ medicine: medicine ?? mockMedicine(),
+ dosis: dosis,
+ timestamp: timeMs == null ? DateTime.now() : DateTime.fromMillisecondsSinceEpoch(timeMs)
+);
\ No newline at end of file
test/model/medicine/medicine_test.dart
@@ -17,7 +17,6 @@ void main() {
expect(med1, isNot(med3));
const med4 = Medicine(1, designation: 'designation', color: Colors.red, defaultDosis: 11);
expect(med1, isNot(med4));
-
});
test('should restore after encoded to map', () {
final med1 = mockMedicine();
@@ -52,6 +51,9 @@ void main() {
final List<Medicine> _meds = [];
+/// Creates mock intake.
+///
+/// Medicines with the same properties will keep the correct id.
Medicine mockMedicine({
Color color = Colors.black,
String designation = '',
@@ -60,5 +62,6 @@ Medicine mockMedicine({
final matchingMeds = _meds.where((med) => med.defaultDosis == defaultDosis && med.color == color && med.designation == designation);
if (matchingMeds.isNotEmpty) return matchingMeds.first;
final med = Medicine(_meds.length, designation: designation, color: color, defaultDosis: defaultDosis);
+ _meds.add(med);
return med;
}
\ No newline at end of file