From b0cb385756333378020279731f35c583fd28b7af Mon Sep 17 00:00:00 2001 From: gelbeinhalb Date: Fri, 23 Jan 2026 11:54:37 +0100 Subject: [PATCH] ruleset is now a required game enum parameter --- lib/core/enums.dart | 23 +++++++++-------- lib/data/dao/game_dao.dart | 13 +++++----- lib/data/dao/match_dao.dart | 2 +- lib/data/dto/game.dart | 9 ++++--- lib/l10n/arb/app_de.arb | 3 +++ lib/l10n/arb/app_en.arb | 3 +++ lib/l10n/generated/app_localizations.dart | 18 +++++++++++++ lib/l10n/generated/app_localizations_de.dart | 9 +++++++ lib/l10n/generated/app_localizations_en.dart | 9 +++++++ .../create_match/create_match_view.dart | 6 ++--- test/db_tests/game_test.dart | 25 +++++++++++-------- test/db_tests/match_test.dart | 3 ++- test/db_tests/player_match_test.dart | 3 ++- test/db_tests/score_test.dart | 3 ++- test/db_tests/team_test.dart | 5 ++-- 15 files changed, 94 insertions(+), 40 deletions(-) diff --git a/lib/core/enums.dart b/lib/core/enums.dart index 17a01f6..ee8b445 100644 --- a/lib/core/enums.dart +++ b/lib/core/enums.dart @@ -29,24 +29,27 @@ enum ImportResult { /// - [ExportResult.unknownException]: An exception occurred during export. enum ExportResult { success, canceled, unknownException } -/// Different rulesets available for matches -/// - [Ruleset.singleWinner]: The match is won by a single player -/// - [Ruleset.singleLoser]: The match is lost by a single player -/// - [Ruleset.mostPoints]: The player with the most points wins. -/// - [Ruleset.leastPoints]: The player with the fewest points wins. -enum Ruleset { singleWinner, singleLoser, mostPoints, leastPoints } +/// Different rulesets available for games +/// - [Ruleset.highestScore]: The player with the highest score wins. +/// - [Ruleset.lowestScore]: The player with the lowest score wins. +/// - [Ruleset.singleWinner]: The match is won by a single player. +/// - [Ruleset.singleLoser]: The match has a single loser. +/// - [Ruleset.multipleWinners]: Multiple players can be winners. +enum Ruleset { highestScore, lowestScore, singleWinner, singleLoser, multipleWinners } /// Translates a [Ruleset] enum value to its corresponding localized string. String translateRulesetToString(Ruleset ruleset, BuildContext context) { final loc = AppLocalizations.of(context); switch (ruleset) { + case Ruleset.highestScore: + return loc.highest_score; + case Ruleset.lowestScore: + return loc.lowest_score; case Ruleset.singleWinner: return loc.single_winner; case Ruleset.singleLoser: return loc.single_loser; - case Ruleset.mostPoints: - return loc.most_points; - case Ruleset.leastPoints: - return loc.least_points; + case Ruleset.multipleWinners: + return loc.multiple_winners; } } diff --git a/lib/data/dao/game_dao.dart b/lib/data/dao/game_dao.dart index 62db351..95ecc70 100644 --- a/lib/data/dao/game_dao.dart +++ b/lib/data/dao/game_dao.dart @@ -2,6 +2,7 @@ import 'package:drift/drift.dart'; import 'package:game_tracker/data/db/database.dart'; import 'package:game_tracker/data/db/tables/game_table.dart'; import 'package:game_tracker/data/dto/game.dart'; +import 'package:game_tracker/core/enums.dart'; part 'game_dao.g.dart'; @@ -18,7 +19,7 @@ class GameDao extends DatabaseAccessor with _$GameDaoMixin { (row) => Game( id: row.id, name: row.name, - ruleset: row.ruleset, + ruleset: Ruleset.values.firstWhere((e) => e.name == row.ruleset), description: row.description, color: row.color, icon: row.icon, @@ -35,7 +36,7 @@ class GameDao extends DatabaseAccessor with _$GameDaoMixin { return Game( id: result.id, name: result.name, - ruleset: result.ruleset, + ruleset: Ruleset.values.firstWhere((e) => e.name == result.ruleset), description: result.description, color: result.color, icon: result.icon, @@ -52,7 +53,7 @@ class GameDao extends DatabaseAccessor with _$GameDaoMixin { GameTableCompanion.insert( id: game.id, name: game.name, - ruleset: game.ruleset ?? '', + ruleset: game.ruleset.name, description: game.description, color: game.color, icon: Value(game.icon), @@ -78,7 +79,7 @@ class GameDao extends DatabaseAccessor with _$GameDaoMixin { (game) => GameTableCompanion.insert( id: game.id, name: game.name, - ruleset: game.ruleset ?? '', + ruleset: game.ruleset.name, description: game.description, color: game.color, icon: Value(game.icon), @@ -122,10 +123,10 @@ class GameDao extends DatabaseAccessor with _$GameDaoMixin { /// Updates the ruleset of the game with the given [gameId]. Future updateGameRuleset({ required String gameId, - required String newRuleset, + required Ruleset newRuleset, }) async { await (update(gameTable)..where((g) => g.id.equals(gameId))).write( - GameTableCompanion(ruleset: Value(newRuleset)), + GameTableCompanion(ruleset: Value(newRuleset.name)), ); } diff --git a/lib/data/dao/match_dao.dart b/lib/data/dao/match_dao.dart index 3d5efb0..4ec5b4d 100644 --- a/lib/data/dao/match_dao.dart +++ b/lib/data/dao/match_dao.dart @@ -127,7 +127,7 @@ class MatchDao extends DatabaseAccessor with _$MatchDaoMixin { (game) => GameTableCompanion.insert( id: game.id, name: game.name, - ruleset: game.ruleset ?? '', + ruleset: game.ruleset.name, description: game.description, color: game.color, icon: Value(game.icon), diff --git a/lib/data/dto/game.dart b/lib/data/dto/game.dart index c63bdea..c74b8aa 100644 --- a/lib/data/dto/game.dart +++ b/lib/data/dto/game.dart @@ -1,11 +1,12 @@ import 'package:clock/clock.dart'; import 'package:uuid/uuid.dart'; +import 'package:game_tracker/core/enums.dart'; class Game { final String id; final DateTime createdAt; final String name; - final String? ruleset; + final Ruleset ruleset; final String description; final String color; final String? icon; @@ -14,7 +15,7 @@ class Game { String? id, DateTime? createdAt, required this.name, - this.ruleset, + required this.ruleset, required this.description, required this.color, this.icon, @@ -31,7 +32,7 @@ class Game { : id = json['id'], createdAt = DateTime.parse(json['createdAt']), name = json['name'], - ruleset = json['ruleset'], + ruleset = Ruleset.values.firstWhere((e) => e.name == json['ruleset']), description = json['description'], color = json['color'], icon = json['icon']; @@ -41,7 +42,7 @@ class Game { 'id': id, 'createdAt': createdAt.toIso8601String(), 'name': name, - 'ruleset': ruleset, + 'ruleset': ruleset.name, 'description': description, 'color': color, 'icon': icon, diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index 2ef9ee9..9e981b0 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -82,6 +82,9 @@ "settings": "Einstellungen", "single_loser": "Ein:e Verlierer:in", "single_winner": "Ein:e Gewinner:in", + "highest_score": "Höchste Punkte", + "lowest_score": "Niedrigste Punkte", + "multiple_winners": "Mehrere Gewinner:innen", "statistics": "Statistiken", "stats": "Statistiken", "successfully_added_player": "Spieler:in {playerName} erfolgreich hinzugefügt", diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index fa4adc8..27419c8 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -380,6 +380,9 @@ "settings": "Settings", "single_loser": "Single Loser", "single_winner": "Single Winner", + "highest_score": "Highest Score", + "lowest_score": "Lowest Score", + "multiple_winners": "Multiple Winners", "statistics": "Statistics", "stats": "Stats", "successfully_added_player": "Successfully added player {playerName}", diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index 57dbdd8..b0aabcb 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -590,6 +590,24 @@ abstract class AppLocalizations { /// **'Single Winner'** String get single_winner; + /// No description provided for @highest_score. + /// + /// In en, this message translates to: + /// **'Highest Score'** + String get highest_score; + + /// No description provided for @lowest_score. + /// + /// In en, this message translates to: + /// **'Lowest Score'** + String get lowest_score; + + /// No description provided for @multiple_winners. + /// + /// In en, this message translates to: + /// **'Multiple Winners'** + String get multiple_winners; + /// Statistics tab label /// /// In en, this message translates to: diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index f78f9f4..0580d4f 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -266,6 +266,15 @@ class AppLocalizationsDe extends AppLocalizations { @override String get single_winner => 'Ein:e Gewinner:in'; + @override + String get highest_score => 'Höchste Punkte'; + + @override + String get lowest_score => 'Niedrigste Punkte'; + + @override + String get multiple_winners => 'Mehrere Gewinner:innen'; + @override String get statistics => 'Statistiken'; diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index 32512c7..8e2e453 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -266,6 +266,15 @@ class AppLocalizationsEn extends AppLocalizations { @override String get single_winner => 'Single Winner'; + @override + String get highest_score => 'Highest Score'; + + @override + String get lowest_score => 'Lowest Score'; + + @override + String get multiple_winners => 'Multiple Winners'; + @override String get statistics => 'Statistics'; diff --git a/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart b/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart index 31e232f..a97de75 100644 --- a/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart +++ b/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart @@ -100,7 +100,7 @@ class _CreateMatchViewState extends State { } List<(String, String, Ruleset)> games = [ - ('Example Game 1', 'This is a description', Ruleset.leastPoints), + ('Example Game 1', 'This is a description', Ruleset.lowestScore), ('Example Game 2', '', Ruleset.singleWinner), ]; @@ -201,7 +201,7 @@ class _CreateMatchViewState extends State { gameToUse = Game( name: selectedGame.$1, description: selectedGame.$2, - ruleset: selectedGame.$3.name, + ruleset: selectedGame.$3, color: '0xFF000000', ); } else { @@ -210,7 +210,7 @@ class _CreateMatchViewState extends State { gameToUse = Game( name: selectedGame.$1, description: selectedGame.$2, - ruleset: selectedGame.$3.name, + ruleset: selectedGame.$3, color: '0xFF000000', ); } diff --git a/test/db_tests/game_test.dart b/test/db_tests/game_test.dart index 4182530..040d607 100644 --- a/test/db_tests/game_test.dart +++ b/test/db_tests/game_test.dart @@ -4,6 +4,7 @@ import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:game_tracker/data/db/database.dart'; import 'package:game_tracker/data/dto/game.dart'; +import 'package:game_tracker/core/enums.dart'; void main() { late AppDatabase database; @@ -24,7 +25,7 @@ void main() { withClock(fakeClock, () { testGame1 = Game( name: 'Chess', - ruleset: 'winner.single', + ruleset: Ruleset.singleWinner, description: 'A classic strategy game', color: '0xFF0000FF', icon: 'chess_icon', @@ -32,14 +33,15 @@ void main() { testGame2 = Game( id: 'game2', name: 'Poker', - ruleset: 'Texas Hold\'em rules', - description: 'winner.multiple', + ruleset: Ruleset.multipleWinners, + description: 'Card game with multiple winners', color: '0xFFFF0000', icon: 'poker_icon', ); testGame3 = Game( id: 'game3', name: 'Monopoly', + ruleset: Ruleset.highestScore, description: 'A board game about real estate', color: '0xFF000000', ); @@ -131,7 +133,7 @@ void main() { // Verifies that a game with null optional fields can be added and retrieved. test('addGame handles game with null optional fields', () async { - final gameWithNulls = Game(name: 'Simple Game', description: 'A simple game', color: '0xFF000000'); + final gameWithNulls = Game(name: 'Simple Game', ruleset: Ruleset.lowestScore, description: 'A simple game', color: '0xFF000000'); final result = await database.gameDao.addGame(game: gameWithNulls); expect(result, true); @@ -269,13 +271,13 @@ void main() { await database.gameDao.updateGameRuleset( gameId: testGame1.id, - newRuleset: 'New ruleset for chess', + newRuleset: Ruleset.highestScore, ); final updatedGame = await database.gameDao.getGameById( gameId: testGame1.id, ); - expect(updatedGame.ruleset, 'New ruleset for chess'); + expect(updatedGame.ruleset, Ruleset.highestScore); expect(updatedGame.name, testGame1.name); }); @@ -283,7 +285,7 @@ void main() { test('updateGameRuleset does nothing for non-existent game', () async { await database.gameDao.updateGameRuleset( gameId: 'non-existent-id', - newRuleset: 'New Ruleset', + newRuleset: Ruleset.lowestScore, ); final allGames = await database.gameDao.getAllGames(); @@ -455,6 +457,7 @@ void main() { test('Game with special characters in name is stored correctly', () async { final specialGame = Game( name: 'Game\'s & "Special" ', + ruleset: Ruleset.multipleWinners, description: 'Description with émojis 🎮🎲', color: '0xFF000000', ); @@ -471,7 +474,7 @@ void main() { test('Game with empty string fields is stored correctly', () async { final emptyGame = Game( name: '', - ruleset: '', + ruleset: Ruleset.singleWinner, description: '', icon: '', color: '0xFF000000', @@ -482,7 +485,7 @@ void main() { gameId: emptyGame.id, ); expect(fetchedGame.name, ''); - expect(fetchedGame.ruleset, ''); + expect(fetchedGame.ruleset, Ruleset.singleWinner); expect(fetchedGame.description, ''); expect(fetchedGame.icon, ''); }); @@ -493,7 +496,7 @@ void main() { final longGame = Game( name: longString, description: longString, - ruleset: longString, + ruleset: Ruleset.multipleWinners, color: '0xFF000000', ); await database.gameDao.addGame(game: longGame); @@ -503,7 +506,7 @@ void main() { ); expect(fetchedGame.name.length, 10000); expect(fetchedGame.description.length, 10000); - expect(fetchedGame.ruleset?.length, 10000); + expect(fetchedGame.ruleset, Ruleset.multipleWinners); }); // Verifies that multiple sequential updates to the same game work correctly. diff --git a/test/db_tests/match_test.dart b/test/db_tests/match_test.dart index f5d3fb2..80a9fa7 100644 --- a/test/db_tests/match_test.dart +++ b/test/db_tests/match_test.dart @@ -7,6 +7,7 @@ import 'package:game_tracker/data/dto/game.dart'; import 'package:game_tracker/data/dto/group.dart'; import 'package:game_tracker/data/dto/match.dart'; import 'package:game_tracker/data/dto/player.dart'; +import 'package:game_tracker/core/enums.dart'; void main() { late AppDatabase database; @@ -48,7 +49,7 @@ void main() { name: 'Test Group 2', members: [testPlayer4, testPlayer5], ); - testGame = Game(name: 'Test Game', description: 'A test game', color: '0xFF000000'); + testGame = Game(name: 'Test Game', ruleset: Ruleset.singleWinner, description: 'A test game', color: '0xFF000000'); testMatch1 = Match( name: 'First Test Match', game: testGame, diff --git a/test/db_tests/player_match_test.dart b/test/db_tests/player_match_test.dart index 3758e0b..0e5fb27 100644 --- a/test/db_tests/player_match_test.dart +++ b/test/db_tests/player_match_test.dart @@ -8,6 +8,7 @@ import 'package:game_tracker/data/dto/group.dart'; import 'package:game_tracker/data/dto/match.dart'; import 'package:game_tracker/data/dto/player.dart'; import 'package:game_tracker/data/dto/team.dart'; +import 'package:game_tracker/core/enums.dart'; void main() { late AppDatabase database; @@ -46,7 +47,7 @@ void main() { name: 'Test Group', members: [testPlayer1, testPlayer2, testPlayer3], ); - testGame = Game(name: 'Test Game', description: 'A test game', color: '0xFF000000'); + testGame = Game(name: 'Test Game', ruleset: Ruleset.singleWinner, description: 'A test game', color: '0xFF000000'); testMatchOnlyGroup = Match( name: 'Test Match with Group', game: testGame, diff --git a/test/db_tests/score_test.dart b/test/db_tests/score_test.dart index bc9d536..9052a32 100644 --- a/test/db_tests/score_test.dart +++ b/test/db_tests/score_test.dart @@ -6,6 +6,7 @@ import 'package:game_tracker/data/db/database.dart'; import 'package:game_tracker/data/dto/game.dart'; import 'package:game_tracker/data/dto/match.dart'; import 'package:game_tracker/data/dto/player.dart'; +import 'package:game_tracker/core/enums.dart'; void main() { late AppDatabase database; @@ -31,7 +32,7 @@ void main() { testPlayer1 = Player(name: 'Alice'); testPlayer2 = Player(name: 'Bob'); testPlayer3 = Player(name: 'Charlie'); - testGame = Game(name: 'Test Game', description: 'A test game', color: '0xFF000000'); + testGame = Game(name: 'Test Game', ruleset: Ruleset.singleWinner, description: 'A test game', color: '0xFF000000'); testMatch1 = Match( name: 'Test Match 1', game: testGame, diff --git a/test/db_tests/team_test.dart b/test/db_tests/team_test.dart index 84188a0..efeaf18 100644 --- a/test/db_tests/team_test.dart +++ b/test/db_tests/team_test.dart @@ -7,6 +7,7 @@ import 'package:game_tracker/data/dto/game.dart'; import 'package:game_tracker/data/dto/match.dart'; import 'package:game_tracker/data/dto/player.dart'; import 'package:game_tracker/data/dto/team.dart'; +import 'package:game_tracker/core/enums.dart'; void main() { late AppDatabase database; @@ -48,8 +49,8 @@ void main() { name: 'Team Gamma', members: [testPlayer1, testPlayer3], ); - testGame1 = Game(name: 'Game 1', description: 'Test game 1', color: '0xFF000000'); - testGame2 = Game(name: 'Game 2', description: 'Test game 2', color: '0xFF000000'); + testGame1 = Game(name: 'Game 1', ruleset: Ruleset.singleWinner, description: 'Test game 1', color: '0xFF000000'); + testGame2 = Game(name: 'Game 2', ruleset: Ruleset.highestScore, description: 'Test game 2', color: '0xFF000000'); }); await database.playerDao.addPlayersAsList(