import 'package:drift_offline_first/drift_offline_first.dart'; import 'package:test/test.dart'; import '../utils/crdt_context.dart'; import '../utils/database.dart'; import '../utils/tables.dart'; void main() { late OfflineSyncCrdt crdt; late CrdtDatabase crdtDb; late String nodeId; group('Given CRDT for an empty database and a pending changeset', () { late Iterable changeset; setUp(() async { (crdt, crdtDb, nodeId) = database.crdtContext; final todo = TodoEntry( id: const RowId(1), content: 'test', targetDate: DateTime.now(), ); changeset = todo.toCrdtDataEntry(crdtDb, Hlc.now(nodeId)); }); test( 'when merging a changeset ' 'then the changeset is saved to the database.', () async { await crdt.merge(changeset); expect(await crdtDb.managers.crdtDataTable.get(), changeset); }); }); group( 'Given CRDT for a database with data and a pending changeset with conflicting data and older HLC', () { late Iterable firstChangeset; late Iterable lateOldChangeset; setUp(() async { (crdt, crdtDb, nodeId) = database.crdtContext; final todo = TodoEntry( id: const RowId(1), content: 'test', targetDate: DateTime.now(), ); firstChangeset = todo.toCrdtDataEntry(crdtDb, Hlc.now(nodeId)); await crdt.merge(firstChangeset); lateOldChangeset = todo.toCrdtDataEntry(crdtDb, Hlc.zero(nodeId)); }); test( 'when merging a changeset with older HLC ' 'then no changes are saved to the database.', () async { await crdt.merge(lateOldChangeset); expect(await crdtDb.managers.crdtDataTable.get(), firstChangeset); }); }); group( 'Given CRDT for a database with data and a pending changeset with conflicting data and some entries with newer HLC', () { late Iterable firstChangeset; late Iterable newerChangeset; setUp(() async { (crdt, crdtDb, nodeId) = database.crdtContext; final todo = TodoEntry( id: const RowId(1), content: 'test', targetDate: DateTime.now(), ); firstChangeset = todo.toCrdtDataEntry(crdtDb, Hlc.now(nodeId)); await crdt.merge(firstChangeset); newerChangeset = todo .toCrdtDataEntry(crdtDb, Hlc.now(nodeId)) .where((e) => e.columnName == 'content'); }); test( 'when merging a changeset with some entries with newer HLC ' 'then the entries with newer HLC are saved to the database.', () async { await crdt.merge(newerChangeset); final expectedResultingChangeset = [ for (final e in firstChangeset) if (e.columnName == 'content') newerChangeset.first else e, ]; expect(await crdtDb.managers.crdtDataTable.get(), expectedResultingChangeset); }); }); }