main
1import 'package:health_data_store/src/database_manager.dart';
2import 'package:health_data_store/src/extensions/datetime_seconds.dart';
3import 'package:sqflite_common_ffi/sqflite_ffi.dart';
4import 'package:test/test.dart';
5
6/// Initialize sqflite for test.
7void sqfliteTestInit() {
8 // Initialize ffi implementation
9 sqfliteFfiInit();
10 // Set global factory
11 databaseFactory = databaseFactoryFfi;
12}
13
14void main() {
15 sqfliteTestInit();
16 test('should initialize without issues', () async {
17 final db = await mockDBManager();
18 addTearDown(db.close);
19 expect(db.db.isOpen, isTrue);
20 });
21 test('should close', () async {
22 final db = await mockDBManager();
23 expect(db.db.isOpen, isTrue);
24 await db.close();
25 expect(db.db.isOpen, isFalse);
26 });
27 test('should setup medicine table', () async {
28 final db = await mockDBManager();
29 addTearDown(db.close);
30
31 final result = await db.db
32 .query('medicine', columns: ['medID', 'designation', 'defaultDose']);
33 expect(result, isEmpty);
34
35 final item1 = {
36 'medID': 1,
37 'designation': 'test',
38 'defaultDose': 42,
39 };
40 final id1 = await db.db.insert('medicine', item1);
41
42 final item2 = {
43 'medID': 2,
44 'designation': 'test2',
45 'defaultDose': 4.2,
46 };
47 final id2 = await db.db.insert('medicine', item2);
48
49 final item3 = {'medID': 3, 'designation': 'test2', 'defaultDose': null};
50 final id3 = await db.db.insert('medicine', item3);
51 expect(id2, greaterThan(id1));
52 expect(id3, greaterThan(id2));
53
54 final resultCols = await db.db
55 .query('medicine', columns: ['medID', 'designation', 'defaultDose']);
56 expect(resultCols, hasLength(equals(3)));
57 expect(
58 resultCols.first.keys,
59 containsAll([
60 'medID',
61 'designation',
62 'defaultDose',
63 ]));
64 expect(
65 resultCols,
66 containsAllInOrder([
67 item1,
68 item2,
69 item3,
70 ]));
71
72 final resultAll = await db.db.query('medicine');
73 expect(resultAll, hasLength(equals(3)));
74 expect(
75 resultCols.first.keys,
76 containsAll([
77 'medID',
78 'designation',
79 'defaultDose',
80 ]));
81 expect(resultCols.first.keys, hasLength(resultCols.first.keys.length),
82 reason: 'no extra columns.');
83
84 final item4 = {'medID': 1, 'designation': null, 'defaultDose': null};
85 await expectLater(
86 () async => db.db.insert('medicine', item4), throwsException);
87 });
88 test('creates timestamps table correctly', () async {
89 final db = await mockDBManager();
90 addTearDown(db.close);
91 await db.db.insert('Timestamps', {
92 'entryID': 1,
93 'timestampUnixS': DateTime.now().secondsSinceEpoch,
94 });
95 final data = await db.db.query('Timestamps');
96 expect(data, hasLength(1));
97 expect(data.first.keys, hasLength(2));
98
99 await expectLater(
100 () async => db.db.insert('Timestamps', {
101 'entryID': 1,
102 'timestampUnixS': DateTime.now().secondsSinceEpoch,
103 }),
104 throwsException);
105 await expectLater(
106 () async => db.db.insert('Timestamps', {
107 'entryID': 1,
108 'timestampUnixS': null,
109 }),
110 throwsException);
111 });
112 test('creates intake table correctly', () async {
113 final db = await mockDBManager();
114 addTearDown(db.close);
115
116 await db.db.insert('Intake', {
117 'entryID': 2,
118 'medID': 1,
119 'dosis': 1,
120 });
121 final data = await db.db.query('Intake');
122 expect(data, hasLength(1));
123 expect(data.first.keys, hasLength(3));
124 });
125 test('creates timestamps sys,dia,pul tables correctly', () async {
126 final db = await mockDBManager();
127 addTearDown(db.close);
128 for (final t in [
129 ('Systolic', 'sys'),
130 ('Diastolic', 'dia'),
131 ('Pulse', 'pul')
132 ]) {
133 await db.db.insert(t.$1, {
134 'entryID': 1,
135 t.$2: 1,
136 });
137 await db.db.insert(t.$1, {
138 'entryID': 2,
139 t.$2: null,
140 });
141 final data = await db.db.query(t.$1);
142 expect(data, hasLength(2));
143 expect(data.first.keys, hasLength(2));
144 }
145 });
146 test('creates notes table correctly', () async {
147 final db = await mockDBManager();
148 addTearDown(db.close);
149
150 await db.db.insert('Notes', {
151 'entryID': 2,
152 'note': 'This was a triumph',
153 'color': 0xFF990098,
154 });
155 final data = await db.db.query('Notes');
156 expect(data, hasLength(1));
157 expect(data.first.keys, hasLength(3));
158 expect(data.first['color'], equals(0xFF990098));
159 });
160 test('creates weight table correctly', () async {
161 final db = await mockDBManager();
162 addTearDown(db.close);
163
164 await db.db.insert('Weight', {
165 'entryID': 2,
166 'weightKg': 123.45,
167 });
168 final data = await db.db.query('Weight');
169 expect(data, hasLength(1));
170 expect(data.first.keys, hasLength(2));
171 expect(data.first['weightKg'], equals(123.45));
172 });
173 test('should cleanup unused timestamps', () async {
174 final db = await mockDBManager();
175 addTearDown(db.close);
176
177 await db.db.insert('Timestamps', {
178 'entryID': 1,
179 'timestampUnixS': DateTime.now().secondsSinceEpoch,
180 });
181 expect(await db.db.query('Timestamps'), hasLength(1));
182 await db.performCleanup();
183 expect(await db.db.query('Timestamps'), isEmpty);
184 });
185 test('should cleanup deleted medicines', () async {
186 final db = await mockDBManager();
187 addTearDown(db.close);
188
189 await db.db.insert('Medicine', {
190 'medID': 1,
191 'designation': 'test',
192 'defaultDose': 42,
193 'removed': 1,
194 });
195 await db.db.insert('Medicine', {
196 'medID': 2,
197 'designation': 'test2',
198 'removed': 1,
199 });
200 await db.db.insert('Intake', {
201 'entryID': 2,
202 'medID': 2,
203 'dosis': 1,
204 });
205
206 expect(await db.db.query('Medicine'), hasLength(2));
207 await db.performCleanup();
208 final data = await db.db.query('Medicine');
209 expect(data, hasLength(1));
210 expect(data, contains(isA<Map>().having((p0) => p0['medID'], 'medID', 2)));
211 });
212 test('cleanup should keep used timestamps', () async {
213 final db = await mockDBManager();
214 addTearDown(db.close);
215
216 for (int i = 1; i <= 7; i += 1) {
217 await db.db.insert('Timestamps', {
218 'entryID': i,
219 'timestampUnixS': i,
220 });
221 }
222 await db.db.insert('Intake', {
223 'entryID': 1,
224 'medID': 0,
225 'dosis': 0,
226 });
227 await db.db.insert('Systolic', {
228 'entryID': 2,
229 });
230 await db.db.insert('Diastolic', {
231 'entryID': 3,
232 });
233 await db.db.insert('Pulse', {
234 'entryID': 4,
235 });
236 await db.db.insert('Notes', {
237 'entryID': 5,
238 });
239 await db.db.insert('Weight', {'entryID': 6, 'weightKg': 1.0});
240
241 expect(await db.db.query('Timestamps'), hasLength(7));
242 await db.performCleanup();
243 expect(await db.db.query('Timestamps'), hasLength(6));
244 // only one isn't used
245 });
246}
247
248Future<DatabaseManager> mockDBManager() async => DatabaseManager.load(
249 await openDatabase(inMemoryDatabasePath),
250 );