Skip to content

Commit

Permalink
Implement list of nullables with minimal refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsenko committed Sep 20, 2022
1 parent 6d4622c commit 958b123
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 7 deletions.
10 changes: 5 additions & 5 deletions generator/lib/src/dart_type_ex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ extension DartTypeEx on DartType {
if (isRealmCollection) {
return (this as ParameterizedType).typeArguments.last;
}
return this;
return asNonNullable;
}

String get basicMappedName => basicType.asNonNullable.mappedName;
String get basicMappedName => basicType.mappedName;

DartType get mappedType {
final self = this;
Expand All @@ -66,15 +66,15 @@ extension DartTypeEx on DartType {
if (self != mapped) {
if (self.isDartCoreList) {
final mappedList = provider.listType(mapped);
return PseudoType('Realm${mappedList.getDisplayString(withNullability: false)}', nullabilitySuffix: mappedList.nullabilitySuffix);
return PseudoType('Realm${mappedList.getDisplayString(withNullability: true)}', nullabilitySuffix: mappedList.nullabilitySuffix);
}
if (self.isDartCoreSet) {
final mappedSet = provider.setType(mapped);
return PseudoType('Realm${mappedSet.getDisplayString(withNullability: false)}', nullabilitySuffix: mappedSet.nullabilitySuffix);
return PseudoType('Realm${mappedSet.getDisplayString(withNullability: true)}', nullabilitySuffix: mappedSet.nullabilitySuffix);
}
if (self.isDartCoreMap) {
final mappedMap = provider.mapType(self.typeArguments.first, mapped);
return PseudoType('Realm${mappedMap.getDisplayString(withNullability: false)}', nullabilitySuffix: mappedMap.nullabilitySuffix);
return PseudoType('Realm${mappedMap.getDisplayString(withNullability: true)}', nullabilitySuffix: mappedMap.nullabilitySuffix);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion generator/lib/src/realm_field_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class RealmFieldInfo {
bool get isRealmCollection => fieldElement.type.isRealmCollection;
bool get isLate => fieldElement.isLate;
bool get hasDefaultValue => fieldElement.hasInitializer;
bool get optional => type.isNullable;
bool get optional => type.isNullable || (type.isRealmCollection && (type as ParameterizedType).typeArguments.last.isNullable);
bool get isRequired => !(hasDefaultValue || optional);

String get name => fieldElement.name;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/realm_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class RealmCoreAccessor implements RealmAccessor {
void set(RealmObject object, String name, Object? value, {bool isDefault = false, bool update = false}) {
final propertyMeta = metadata[name];
try {
if (value is RealmList<Object>) {
if (value is RealmList<Object?>) {
final handle = realmCore.getListProperty(object, propertyMeta.key);
if (update) realmCore.listClear(handle);
for (var i = 0; i < value.length; i++) {
Expand Down
67 changes: 67 additions & 0 deletions test/list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -806,4 +806,71 @@ Future<void> main([List<String>? args]) async {
expect(team.players.query('TRUEPREDICATE'), isNot(realm.all<Person>()));
expect(team.players.query('TRUEPREDICATE'), [alice, bob]);
});

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<Player> winnerByRound, Map<Player, List<int?>> scoresByPlayer) {
expect(game.winnerByRound, winnerByRound);
for (final p in players) {
expect(p.scoresByRound, scoresByPlayer[p] ?? []);
}
}

checkResult([], {});

int currentRound = 0;
void playRound(Map<Player, int> scores) {
realm.write(() {
for (final p in players) {
p.scoresByRound.add(scores[p]);
}
final bestResult =
scores.entries.fold<MapEntry<Player, int>?>(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]
});
});
}
22 changes: 22 additions & 0 deletions test/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ class _AllCollections {
late List<ObjectId> objectIds;
late List<Uuid> uuids;
late List<int> ints;

late List<String?> nullableStrings;
late List<bool?> nullableBools;
late List<DateTime?> nullableDates;
late List<double?> nullableDoubles;
late List<ObjectId?> nullableObjectIds;
late List<Uuid?> nullableUuids;
late List<int?> nullableInts;
}

@RealmModel()
Expand Down Expand Up @@ -193,6 +201,20 @@ class _Friend {
final friends = <_Friend>[];
}

@RealmModel()
class _Player {
@PrimaryKey()
late String name;
_Game? game;
final scoresByRound = <int?>[]; // 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<String, String?> arguments = {};
final baasApps = <String, BaasApp>{};
Expand Down
172 changes: 172 additions & 0 deletions test/test.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 958b123

Please sign in to comment.