• 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

0.0
/lib/data/database/web_database.dart
1
import 'dart:convert';
2
import 'package:shared_preferences/shared_preferences.dart';
3
import 'database_interface.dart';
4

5
class WebDatabase implements DatabaseInterface {
6
  SharedPreferences? _prefs;
7
  final Map<String, List<Map<String, dynamic>>> _memoryStorage = {
8
    'games': [],
9
    'wishlist': [],
10
    'players': [],
11
    'settings': [],
12
  };
13

14
  bool _initialized = false;
15

NEW
16
  @override
×
17
  Future<String> getDatabasePath() async {
NEW
18
    throw Exception('Web storage does not have a path');
×
19
  }
20

NEW
21
  Future<void> _ensureInitialized() async {
×
NEW
22
    if (_initialized) return;
×
NEW
23
    _prefs = await SharedPreferences.getInstance();
×
NEW
24
    _loadFromPrefs();
×
NEW
25
    _initialized = true;
×
26
  }
27

NEW
28
  void _loadFromPrefs() {
×
NEW
29
    if (_prefs == null) return;
×
30

NEW
31
    final gamesJson = _prefs!.getString('games_data');
×
NEW
32
    final wishlistJson = _prefs!.getString('wishlist_data');
×
NEW
33
    final playersJson = _prefs!.getString('players_data');
×
34

35
    if (gamesJson != null) {
NEW
36
      _memoryStorage['games'] = List<Map<String, dynamic>>.from(
×
NEW
37
        json.decode(gamesJson),
×
38
      );
39
    }
40
    if (wishlistJson != null) {
NEW
41
      _memoryStorage['wishlist'] = List<Map<String, dynamic>>.from(
×
NEW
42
        json.decode(wishlistJson),
×
43
      );
44
    }
45
    if (playersJson != null) {
NEW
46
      _memoryStorage['players'] = List<Map<String, dynamic>>.from(
×
NEW
47
        json.decode(playersJson),
×
48
      );
49
    }
50
  }
51

NEW
52
  Future<void> _saveToPrefs() async {
×
NEW
53
    if (_prefs == null) return;
×
54

NEW
55
    await _prefs!.setString('games_data', json.encode(_memoryStorage['games']));
×
NEW
56
    await _prefs!.setString(
×
57
      'wishlist_data',
NEW
58
      json.encode(_memoryStorage['wishlist']),
×
59
    );
NEW
60
    await _prefs!.setString(
×
61
      'players_data',
NEW
62
      json.encode(_memoryStorage['players']),
×
63
    );
64
  }
65

NEW
66
  @override
×
67
  Future<String> insertGame(Map<String, dynamic> game) async {
NEW
68
    await _ensureInitialized();
×
NEW
69
    _memoryStorage['games']!.add(game);
×
NEW
70
    await _saveToPrefs();
×
NEW
71
    return game['id'] as String;
×
72
  }
73

NEW
74
  @override
×
75
  Future<List<Map<String, dynamic>>> getAllGames() async {
NEW
76
    await _ensureInitialized();
×
NEW
77
    return List<Map<String, dynamic>>.from(_memoryStorage['games']!)..sort(
×
NEW
78
      (a, b) => (b['created_at'] as int).compareTo(a['created_at'] as int),
×
79
    );
80
  }
81

NEW
82
  @override
×
83
  Future<List<Map<String, dynamic>>> searchGames(String query) async {
NEW
84
    await _ensureInitialized();
×
NEW
85
    return _memoryStorage['games']!
×
NEW
86
        .where(
×
NEW
87
          (g) => (g['title'] as String).toLowerCase().contains(
×
NEW
88
            query.toLowerCase(),
×
89
          ),
90
        )
NEW
91
        .toList()
×
NEW
92
      ..sort(
×
NEW
93
        (a, b) => (b['created_at'] as int).compareTo(a['created_at'] as int),
×
94
      );
95
  }
96

NEW
97
  @override
×
98
  Future<List<Map<String, dynamic>>> getGamesByCategory(String category) async {
NEW
99
    await _ensureInitialized();
×
NEW
100
    return _memoryStorage['games']!
×
NEW
101
        .where((g) => g['category'] == category)
×
NEW
102
        .toList()
×
NEW
103
      ..sort(
×
NEW
104
        (a, b) => (b['created_at'] as int).compareTo(a['created_at'] as int),
×
105
      );
106
  }
107

NEW
108
  @override
×
109
  Future<List<String>> getDistinctCategories() async {
NEW
110
    await _ensureInitialized();
×
NEW
111
    final categories = _memoryStorage['games']!
×
NEW
112
        .map((g) => g['category'] as String)
×
NEW
113
        .toSet()
×
NEW
114
        .toList();
×
NEW
115
    categories.sort();
×
116
    return categories;
117
  }
118

NEW
119
  @override
×
120
  Future<Map<String, dynamic>?> getGameById(String id) async {
NEW
121
    await _ensureInitialized();
×
122
    try {
NEW
123
      return _memoryStorage['games']!.firstWhere((g) => g['id'] == id);
×
124
    } catch (e) {
125
      return null;
126
    }
127
  }
128

NEW
129
  @override
×
130
  Future<int> updateGame(String id, Map<String, dynamic> game) async {
NEW
131
    await _ensureInitialized();
×
NEW
132
    final index = _memoryStorage['games']!.indexWhere((g) => g['id'] == id);
×
NEW
133
    if (index >= 0) {
×
NEW
134
      _memoryStorage['games']![index] = {
×
NEW
135
        ..._memoryStorage['games']![index],
×
NEW
136
        ...game,
×
137
      };
NEW
138
      await _saveToPrefs();
×
139
      return 1;
140
    }
141
    return 0;
142
  }
143

NEW
144
  @override
×
145
  Future<int> deleteGame(String id) async {
NEW
146
    await _ensureInitialized();
×
NEW
147
    final initialLength = _memoryStorage['games']!.length;
×
NEW
148
    _memoryStorage['games']!.removeWhere((g) => g['id'] == id);
×
NEW
149
    final removed = initialLength - _memoryStorage['games']!.length;
×
NEW
150
    await _saveToPrefs();
×
NEW
151
    return removed > 0 ? 1 : 0;
×
152
  }
153

NEW
154
  @override
×
155
  Future<String> insertWishlistItem(Map<String, dynamic> item) async {
NEW
156
    await _ensureInitialized();
×
NEW
157
    _memoryStorage['wishlist']!.add(item);
×
NEW
158
    await _saveToPrefs();
×
NEW
159
    return item['id'] as String;
×
160
  }
161

NEW
162
  @override
×
163
  Future<List<Map<String, dynamic>>> getAllWishlistItems() async {
NEW
164
    await _ensureInitialized();
×
NEW
165
    return List<Map<String, dynamic>>.from(_memoryStorage['wishlist']!)..sort(
×
NEW
166
      (a, b) => (b['created_at'] as int).compareTo(a['created_at'] as int),
×
167
    );
168
  }
169

NEW
170
  @override
×
171
  Future<int> updateWishlistItem(String id, Map<String, dynamic> item) async {
NEW
172
    await _ensureInitialized();
×
NEW
173
    final index = _memoryStorage['wishlist']!.indexWhere((w) => w['id'] == id);
×
NEW
174
    if (index >= 0) {
×
NEW
175
      _memoryStorage['wishlist']![index] = {
×
NEW
176
        ..._memoryStorage['wishlist']![index],
×
NEW
177
        ...item,
×
178
      };
NEW
179
      await _saveToPrefs();
×
180
      return 1;
181
    }
182
    return 0;
183
  }
184

NEW
185
  @override
×
186
  Future<int> deleteWishlistItem(String id) async {
NEW
187
    await _ensureInitialized();
×
NEW
188
    final initialLength = _memoryStorage['wishlist']!.length;
×
NEW
189
    _memoryStorage['wishlist']!.removeWhere((w) => w['id'] == id);
×
NEW
190
    final removed = initialLength - _memoryStorage['wishlist']!.length;
×
NEW
191
    await _saveToPrefs();
×
NEW
192
    return removed > 0 ? 1 : 0;
×
193
  }
194

NEW
195
  @override
×
196
  Future<String> insertPlayer(Map<String, dynamic> player) async {
NEW
197
    await _ensureInitialized();
×
NEW
198
    _memoryStorage['players']!.add(player);
×
NEW
199
    await _saveToPrefs();
×
NEW
200
    return player['id'] as String;
×
201
  }
202

NEW
203
  @override
×
204
  Future<List<Map<String, dynamic>>> getAllPlayers() async {
NEW
205
    await _ensureInitialized();
×
NEW
206
    return List<Map<String, dynamic>>.from(_memoryStorage['players']!)..sort(
×
NEW
207
      (a, b) => (b['created_at'] as int).compareTo(a['created_at'] as int),
×
208
    );
209
  }
210

NEW
211
  @override
×
212
  Future<int> deletePlayer(String id) async {
NEW
213
    await _ensureInitialized();
×
NEW
214
    final initialLength = _memoryStorage['players']!.length;
×
NEW
215
    _memoryStorage['players']!.removeWhere((p) => p['id'] == id);
×
NEW
216
    final removed = initialLength - _memoryStorage['players']!.length;
×
NEW
217
    await _saveToPrefs();
×
NEW
218
    return removed > 0 ? 1 : 0;
×
219
  }
220

NEW
221
  @override
×
222
  Future<Map<String, dynamic>> exportAllData() async {
NEW
223
    await _ensureInitialized();
×
NEW
224
    return {
×
NEW
225
      'games': _memoryStorage['games'],
×
NEW
226
      'wishlist': _memoryStorage['wishlist'],
×
NEW
227
      'players': _memoryStorage['players'],
×
NEW
228
      'settings': [],
×
NEW
229
      'export_date': DateTime.now().toIso8601String(),
×
230
      'version': 1,
231
    };
232
  }
233

NEW
234
  @override
×
235
  Future<void> importAllData(Map<String, dynamic> data) async {
NEW
236
    await _ensureInitialized();
×
NEW
237
    if (data['games'] != null) {
×
NEW
238
      _memoryStorage['games'] = List<Map<String, dynamic>>.from(
×
NEW
239
        data['games'] as List,
×
240
      );
241
    }
NEW
242
    if (data['wishlist'] != null) {
×
NEW
243
      _memoryStorage['wishlist'] = List<Map<String, dynamic>>.from(
×
NEW
244
        data['wishlist'] as List,
×
245
      );
246
    }
NEW
247
    if (data['players'] != null) {
×
NEW
248
      _memoryStorage['players'] = List<Map<String, dynamic>>.from(
×
NEW
249
        data['players'] as List,
×
250
      );
251
    }
NEW
252
    await _saveToPrefs();
×
253
  }
254

NEW
255
  @override
×
256
  Future<void> close() async {
NEW
257
    await _saveToPrefs();
×
258
  }
259
}
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