diff --git a/test/list_test.dart b/test/list_test.dart index fb02ab7eef..225024f378 100644 --- a/test/list_test.dart +++ b/test/list_test.dart @@ -699,4 +699,71 @@ Future main([List? args]) async { expect(team.players, isNot(players)); expect(team.players, unorderedMatches(players)); }); + + test('List of nullables', () { + final config = Configuration.local([Player.schema, Game.schema]); + final realm = getRealm(config); + + final game = Game(); + final alice = Player('alice', game: game); + final bob = Player('bob', game: game); + final carol = Player('carol', game: game); + final players = [alice, bob, carol]; + + realm.write(() => realm.addAll(players)); + + void checkResult(List winnerByRound, Map> scoresByPlayer) { + expect(game.winnerByRound, winnerByRound); + for (final p in players) { + expect(p.scoresByRound, scoresByPlayer[p] ?? []); + } + } + + checkResult([], {}); + + int currentRound = 0; + void playRound(Map scores) { + realm.write(() { + for (final p in players) { + p.scoresByRound.add(scores[p]); + } + final bestResult = + scores.entries.fold?>(null, (bestResult, result) => result.value > (bestResult?.value ?? 0) ? result : bestResult); + game.winnerByRound[currentRound++] = bestResult!.key; + }); + } + + playRound({alice: 1, bob: 2}); + + checkResult([ + bob + ], { + alice: [1], + bob: [2], + carol: [null] + }); + + playRound({alice: 3, carol: 1}); + + checkResult([ + bob, + alice + ], { + alice: [1, 3], + bob: [2, null], + carol: [null, 1] + }); + + playRound({alice: 2, bob: 3, carol: 1}); + + checkResult([ + bob, + alice, + bob + ], { + alice: [1, 3, 2], + bob: [2, null, 3], + carol: [null, 1, 1] + }); + }); } diff --git a/test/test.dart b/test/test.dart index 6bdc4e73fe..52717c1e05 100644 --- a/test/test.dart +++ b/test/test.dart @@ -201,6 +201,20 @@ class _Friend { final friends = <_Friend>[]; } +@RealmModel() +class _Player { + @PrimaryKey() + late String name; + _Game? game; + final scoresByRound = []; // null means player didn't finish +} + +@RealmModel() +class _Game { + final winnerByRound = <_Player>[]; // null means no winner yet + int get rounds => winnerByRound.length; +} + String? testName; Map arguments = {}; final baasApps = {}; diff --git a/test/test.g.dart b/test/test.g.dart index 48f6eeabe7..e5e2fd9b7a 100644 --- a/test/test.g.dart +++ b/test/test.g.dart @@ -1253,3 +1253,91 @@ class Friend extends _Friend with RealmEntityMixin, RealmObjectMixin { @override SchemaObject get instanceSchema => schema; } + +class Player extends _Player with RealmEntityMixin, RealmObjectMixin { + Player( + String name, { + Game? game, + Iterable scoresByRound = const [], + }) { + _nameProperty.setValue(this, name); + _gameProperty.setValue(this, game); + _scoresByRoundProperty.setValue(this, RealmList(scoresByRound)); + } + + Player._(); + + static const _nameProperty = ValueProperty( + 'name', + RealmPropertyType.string, + primaryKey: true, + ); + @override + String get name => _nameProperty.getValue(this); + @override + set name(String value) => throw RealmUnsupportedSetError(); + + static const _gameProperty = ObjectProperty('game', 'Game'); + @override + Game? get game => _gameProperty.getValue(this); + @override + set game(covariant Game? value) => _gameProperty.setValue(this, value); + + static const _scoresByRoundProperty = + ListProperty('scoresByRound', RealmPropertyType.int); + @override + RealmList get scoresByRound => _scoresByRoundProperty.getValue(this); + @override + set scoresByRound(covariant RealmList value) => + throw RealmUnsupportedSetError(); + + @override + Stream> get changes => + RealmObjectMixin.getChanges(this); + + static const schema = SchemaObject( + Player._, + 'Player', + { + 'name': _nameProperty, + 'game': _gameProperty, + 'scoresByRound': _scoresByRoundProperty, + }, + _nameProperty, + ); + @override + SchemaObject get instanceSchema => schema; +} + +class Game extends _Game with RealmEntityMixin, RealmObjectMixin { + Game({ + Iterable winnerByRound = const [], + }) { + _winnerByRoundProperty.setValue(this, RealmList(winnerByRound)); + } + + Game._(); + + static const _winnerByRoundProperty = ListProperty( + 'winnerByRound', RealmPropertyType.object, + linkTarget: 'Player'); + @override + RealmList get winnerByRound => _winnerByRoundProperty.getValue(this); + @override + set winnerByRound(covariant RealmList value) => + throw RealmUnsupportedSetError(); + + @override + Stream> get changes => + RealmObjectMixin.getChanges(this); + + static const schema = SchemaObject( + Game._, + 'Game', + { + 'winnerByRound': _winnerByRoundProperty, + }, + ); + @override + SchemaObject get instanceSchema => schema; +}