• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Oda2 / boardpocket / 23079113453

14 Mar 2026 03:10AM UTC coverage: 72.339% (+7.5%) from 64.881%
23079113453

push

github

Oda2
Add comprehensive tests for settings components, star rating, theme container, and database interactions

- Implement tests for SettingsSection, SettingsListTile, SettingsToggle, SettingsActionButtons, UserCard, and SettingsDivider components.
- Create tests for StarRating component to ensure proper rendering and interaction.
- Add tests for ThemeContainer to verify child rendering and padding/margin application.
- Refactor database helper tests to utilize a mock database interface for better isolation and control.
- Introduce a MockDatabaseInterface to streamline testing for game, player, and wishlist repositories.
- Enhance BackupService tests to validate JSON export/import functionality and database path retrieval.

1146 of 1581 new or added lines in 29 files covered. (72.49%)

12 existing lines in 8 files now uncovered.

2691 of 3720 relevant lines covered (72.34%)

1.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.98
/lib/data/database/native_database.dart
1
import 'package:sqflite/sqflite.dart';
2
import 'package:path/path.dart';
3
import 'database_interface.dart';
4

5
class NativeDatabase implements DatabaseInterface {
6
  Database? _database;
7
  static const String _dbName = 'boardpocket.db';
8

NEW
9
  @override
×
10
  Future<String> getDatabasePath() async {
NEW
11
    final db = await database;
×
NEW
12
    return db.path;
×
13
  }
14

15
  Future<Database> get database async {
2✔
16
    if (_database != null) return _database!;
3✔
17
    _database = await _initDB(_dbName);
3✔
18
    return _database!;
1✔
19
  }
20

21
  Future<Database> _initDB(String filePath) async {
2✔
22
    final dbPath = await getDatabasesPath();
2✔
23
    final path = join(dbPath, filePath);
1✔
24

25
    return await openDatabase(
1✔
26
      path,
27
      version: 2,
28
      onCreate: _createDB,
1✔
29
      onUpgrade: _upgradeDB,
1✔
30
    );
31
  }
32

NEW
33
  Future<void> _upgradeDB(Database db, int oldVersion, int newVersion) async {
×
NEW
34
    if (oldVersion < 2) {
×
NEW
35
      await db.execute('ALTER TABLE games ADD COLUMN wins INTEGER DEFAULT 0');
×
NEW
36
      await db.execute('ALTER TABLE games ADD COLUMN losses INTEGER DEFAULT 0');
×
37
    }
38
  }
39

NEW
40
  Future<void> _createDB(Database db, int version) async {
×
41
    const idType = 'TEXT PRIMARY KEY';
42
    const textType = 'TEXT';
43
    const intType = 'INTEGER';
44
    const realType = 'REAL';
45

NEW
46
    await db.execute('''
×
47
      CREATE TABLE games (
48
        id $idType,
49
        title $textType NOT NULL,
50
        image_path $textType,
51
        players $textType NOT NULL,
52
        time $textType NOT NULL,
53
        category $textType NOT NULL,
54
        min_players $intType,
55
        max_players $intType,
56
        play_time $intType,
57
        complexity $realType,
58
        total_plays $intType DEFAULT 0,
59
        wins $intType DEFAULT 0,
60
        losses $intType DEFAULT 0,
61
        win_rate $realType DEFAULT 0.0,
62
        last_played $intType,
63
        created_at $intType NOT NULL,
64
        updated_at $intType NOT NULL
65
      )
66
    ''');
67

NEW
68
    await db.execute('''
×
69
      CREATE TABLE wishlist (
70
        id $idType,
71
        title $textType NOT NULL,
72
        image_path $textType,
73
        image_url $textType,
74
        price $textType,
75
        purchase_url $textType,
76
        players $textType NOT NULL,
77
        time $textType NOT NULL,
78
        tag $textType,
79
        category $textType,
80
        created_at $intType NOT NULL
81
      )
82
    ''');
83

NEW
84
    await db.execute('''
×
85
      CREATE TABLE players (
86
        id $idType,
87
        name $textType NOT NULL,
88
        created_at $intType NOT NULL
89
      )
90
    ''');
91

NEW
92
    await db.execute('''
×
93
      CREATE TABLE settings (
94
        key $textType PRIMARY KEY,
95
        value $textType NOT NULL
96
      )
97
    ''');
98

NEW
99
    await db.insert('settings', {'key': 'dark_mode', 'value': 'true'});
×
NEW
100
    await db.insert('settings', {'key': 'language', 'value': 'en'});
×
NEW
101
    await db.insert('settings', {'key': 'initialized', 'value': 'true'});
×
102
  }
103

104
  @override
1✔
105
  Future<String> insertGame(Map<String, dynamic> game) async {
106
    final db = await database;
1✔
107
    await db.insert('games', game);
1✔
108
    return game['id'] as String;
1✔
109
  }
110

111
  @override
1✔
112
  Future<List<Map<String, dynamic>>> getAllGames() async {
113
    final db = await database;
1✔
114
    return await db.query('games', orderBy: 'created_at DESC');
1✔
115
  }
116

117
  @override
1✔
118
  Future<List<Map<String, dynamic>>> searchGames(String query) async {
119
    final db = await database;
1✔
120
    return await db.query(
1✔
121
      'games',
122
      where: 'title LIKE ?',
123
      whereArgs: ['%$query%'],
2✔
124
      orderBy: 'created_at DESC',
125
    );
126
  }
127

128
  @override
1✔
129
  Future<List<Map<String, dynamic>>> getGamesByCategory(String category) async {
130
    final db = await database;
1✔
131
    return await db.query(
1✔
132
      'games',
133
      where: 'category = ?',
134
      whereArgs: [category],
1✔
135
      orderBy: 'created_at DESC',
136
    );
137
  }
138

139
  @override
1✔
140
  Future<List<String>> getDistinctCategories() async {
141
    final db = await database;
1✔
142
    final result = await db.rawQuery(
1✔
143
      'SELECT DISTINCT category FROM games ORDER BY category ASC',
144
    );
145
    return result.map((e) => e['category'] as String).toList();
4✔
146
  }
147

148
  @override
1✔
149
  Future<Map<String, dynamic>?> getGameById(String id) async {
150
    final db = await database;
1✔
151
    final results = await db.query('games', where: 'id = ?', whereArgs: [id]);
2✔
152
    return results.isNotEmpty ? results.first : null;
2✔
153
  }
154

155
  @override
1✔
156
  Future<int> updateGame(String id, Map<String, dynamic> game) async {
157
    final db = await database;
1✔
158
    return await db.update('games', game, where: 'id = ?', whereArgs: [id]);
2✔
159
  }
160

161
  @override
1✔
162
  Future<int> deleteGame(String id) async {
163
    final db = await database;
1✔
164
    return await db.delete('games', where: 'id = ?', whereArgs: [id]);
2✔
165
  }
166

167
  @override
1✔
168
  Future<String> insertWishlistItem(Map<String, dynamic> item) async {
169
    final db = await database;
1✔
170
    await db.insert('wishlist', item);
1✔
171
    return item['id'] as String;
1✔
172
  }
173

174
  @override
1✔
175
  Future<List<Map<String, dynamic>>> getAllWishlistItems() async {
176
    final db = await database;
1✔
177
    return await db.query('wishlist', orderBy: 'created_at DESC');
1✔
178
  }
179

180
  @override
1✔
181
  Future<int> updateWishlistItem(String id, Map<String, dynamic> item) async {
182
    final db = await database;
1✔
183
    return await db.update('wishlist', item, where: 'id = ?', whereArgs: [id]);
2✔
184
  }
185

186
  @override
1✔
187
  Future<int> deleteWishlistItem(String id) async {
188
    final db = await database;
1✔
189
    return await db.delete('wishlist', where: 'id = ?', whereArgs: [id]);
2✔
190
  }
191

192
  @override
1✔
193
  Future<String> insertPlayer(Map<String, dynamic> player) async {
194
    final db = await database;
1✔
195
    await db.insert('players', player);
1✔
196
    return player['id'] as String;
1✔
197
  }
198

199
  @override
1✔
200
  Future<List<Map<String, dynamic>>> getAllPlayers() async {
201
    final db = await database;
1✔
202
    return await db.query('players', orderBy: 'created_at DESC');
1✔
203
  }
204

205
  @override
1✔
206
  Future<int> deletePlayer(String id) async {
207
    final db = await database;
1✔
208
    return await db.delete('players', where: 'id = ?', whereArgs: [id]);
2✔
209
  }
210

211
  @override
1✔
212
  Future<Map<String, dynamic>> exportAllData() async {
213
    final db = await database;
1✔
214

215
    final games = await db.query('games');
1✔
216
    final wishlist = await db.query('wishlist');
1✔
217
    final players = await db.query('players');
1✔
218
    final settings = await db.query('settings');
1✔
219

220
    return {
1✔
221
      'games': games,
222
      'wishlist': wishlist,
223
      'players': players,
224
      'settings': settings,
225
      'export_date': DateTime.now().toIso8601String(),
2✔
226
      'version': 1,
227
    };
228
  }
229

230
  @override
1✔
231
  Future<void> importAllData(Map<String, dynamic> data) async {
232
    final db = await database;
1✔
233

234
    await db.transaction((txn) async {
2✔
235
      await txn.delete('games');
1✔
236
      await txn.delete('wishlist');
1✔
237
      await txn.delete('players');
1✔
238
      await txn.delete('settings');
1✔
239

240
      if (data['games'] != null) {
1✔
241
        for (final game in data['games'] as List) {
3✔
242
          await txn.insert('games', game as Map<String, dynamic>);
1✔
243
        }
244
      }
245

246
      if (data['wishlist'] != null) {
1✔
247
        for (final item in data['wishlist'] as List) {
3✔
248
          await txn.insert('wishlist', item as Map<String, dynamic>);
1✔
249
        }
250
      }
251

252
      if (data['players'] != null) {
1✔
253
        for (final player in data['players'] as List) {
3✔
254
          await txn.insert('players', player as Map<String, dynamic>);
1✔
255
        }
256
      }
257

258
      if (data['settings'] != null) {
1✔
259
        for (final setting in data['settings'] as List) {
3✔
260
          await txn.insert('settings', setting as Map<String, dynamic>);
1✔
261
        }
262
      }
263
    });
264
  }
265

266
  @override
1✔
267
  Future<void> close() async {
268
    final db = await database;
1✔
269
    db.close();
1✔
270
  }
271
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc