import 'package:platform_driver_rethinkdb/platform_driver_rethinkdb.dart'; import 'package:test/test.dart'; main() { RethinkDb r = RethinkDb(); String? tableName; String? testDbName; bool shouldDropTable = false; Connection? connection; setUp(() async { connection = await r.connect(); if (testDbName == null) { String useDb = await r.uuid().run(connection!); testDbName = 'unit_test_db${useDb.replaceAll("-", "")}'; await r.dbCreate(testDbName!).run(connection!); } connection!.use(testDbName!); if (tableName == null) { String tblName = await r.uuid().run(connection!); tableName = "test_table_${tblName.replaceAll("-", "")}"; await r.tableCreate(tableName!).run(connection!); } }); tearDown(() async { if (shouldDropTable) { shouldDropTable = false; await r.tableDrop(tableName!).run(connection!); } connection!.close(); }); group("insert command -> ", () { test("should insert a single record", () async { Map createdRecord = await r .table(tableName!) .insert({'id': 1, 'name': 'Jane Doe'}).run(connection!); expect(createdRecord['deleted'], equals(0)); expect(createdRecord['errors'], equals(0)); expect(createdRecord['inserted'], equals(1)); expect(createdRecord['replaced'], equals(0)); expect(createdRecord['skipped'], equals(0)); expect(createdRecord['unchanged'], equals(0)); }); test("should error if record exists", () async { Map createdRecord = await r .table(tableName!) .insert({'id': 1, 'name': 'Jane Doe'}).run(connection!); expect( createdRecord['first_error'].startsWith('Duplicate primary key `id`'), equals(true)); expect(createdRecord['deleted'], equals(0)); expect(createdRecord['errors'], equals(1)); expect(createdRecord['inserted'], equals(0)); expect(createdRecord['replaced'], equals(0)); expect(createdRecord['skipped'], equals(0)); expect(createdRecord['unchanged'], equals(0)); }); test("should insert multiple records", () async { Map createdRecord = await r.table(tableName!).insert([ {'name': 'Jane Doe'}, { 'id': 2, 'name': 'John Bonham', 'kit': { 'cymbals': ['hi-hat', 'crash', 'splash'], 'drums': ['kick', 'tom'] } } ]).run(connection!); expect(createdRecord['deleted'], equals(0)); expect(createdRecord['errors'], equals(0)); expect(createdRecord['generated_keys'].length, equals(1)); expect(createdRecord['inserted'], equals(2)); expect(createdRecord['replaced'], equals(0)); expect(createdRecord['skipped'], equals(0)); expect(createdRecord['unchanged'], equals(0)); }); test("should change durability", () async { Map createdRecord = await r .table(tableName!) .insert({'name': 'a'}, {'durability': 'hard'}).run(connection!); expect(createdRecord['deleted'], equals(0)); expect(createdRecord['errors'], equals(0)); expect(createdRecord['generated_keys'].length, equals(1)); expect(createdRecord['inserted'], equals(1)); expect(createdRecord['replaced'], equals(0)); expect(createdRecord['skipped'], equals(0)); expect(createdRecord['unchanged'], equals(0)); }); test("should allow return_changes", () async { Map createdRecord = await r .table(tableName!) .insert({'name': 'a'}, {'return_changes': true}).run(connection!); expect(createdRecord['changes'][0]['new_val']['name'], equals('a')); expect(createdRecord['changes'][0]['old_val'], equals(null)); expect(createdRecord['deleted'], equals(0)); expect(createdRecord['errors'], equals(0)); expect(createdRecord['generated_keys'].length, equals(1)); expect(createdRecord['inserted'], equals(1)); expect(createdRecord['replaced'], equals(0)); expect(createdRecord['skipped'], equals(0)); expect(createdRecord['unchanged'], equals(0)); }); test("should allow handle conflicts", () async { var update = await r.table(tableName!).insert( {'id': 1, 'birthYear': DateTime(1984)}, {'conflict': 'update', 'return_changes': true}).run(connection!); expect(update['changes'][0]['new_val'].containsKey('birthYear'), equals(true)); expect(update['changes'][0]['new_val'].containsKey('name'), equals(true)); expect(update['changes'][0]['old_val'].containsKey('birthYear'), equals(false)); expect(update['changes'][0]['old_val'].containsKey('name'), equals(true)); expect(update['replaced'], equals(1)); var replace = await r.table(tableName!).insert( {'id': 1, 'name': 'Jane Doe'}, {'conflict': 'replace', 'return_changes': true}).run(connection!); expect(replace['changes'][0]['new_val'].containsKey('birthYear'), equals(false)); expect( replace['changes'][0]['new_val'].containsKey('name'), equals(true)); expect(replace['changes'][0]['old_val'].containsKey('birthYear'), equals(true)); expect( replace['changes'][0]['old_val'].containsKey('name'), equals(true)); expect(replace['replaced'], equals(1)); var custom = await r.table(tableName!).insert({ 'id': 1, 'name': 'Jane Doe' }, { 'conflict': (id, oldVal, newVal) => {'id': oldVal('id'), 'err': 'bad record'}, 'return_changes': true }).run(connection!); expect(custom['changes'][0]['new_val'].containsKey('err'), equals(true)); expect(replace['replaced'], equals(1)); }); }); group("update command -> ", () { test("should update all records in a table", () async { Map update = await r .table(tableName!) .update({'lastModified': DateTime.now()}).run(connection!); expect(update['replaced'], equals(5)); }); test("should update all records in a selection", () async { Map updatedSelection = await r .table(tableName!) .getAll(1, 2) .update({'newField': 33}).run(connection!); expect(updatedSelection['replaced'], equals(2)); }); test("should update a single record", () async { Map updatedSelection = await r .table(tableName!) .get(1) .update({'newField2': 44}).run(connection!); expect(updatedSelection['replaced'], equals(1)); }); test("should update with durability option", () async { Map updatedSelection = await r .table(tableName!) .get(1) .update({'newField2': 22}, {'durability': 'soft'}).run(connection!); expect(updatedSelection['replaced'], equals(1)); }); test("should update with return_changes option", () async { Map updatedSelection = await r.table(tableName!).get(1).update( {'newField2': 11}, {'return_changes': 'always'}).run(connection!); expect(updatedSelection.containsKey('changes'), equals(true)); }); test("should update with non_atomic option", () async { Map updatedSelection = await r .table(tableName!) .get(1) .update({'newField2': 00}, {'non_atomic': true}).run(connection!); expect(updatedSelection['replaced'], equals(1)); }); test("should update with r.literal", () async { Map updated = await r.table(tableName!).get(2).update({ 'kit': r.literal({'bells': 'cow'}) }, { 'return_changes': true }).run(connection!); Map oldVal = updated['changes'][0]['old_val']; Map newVal = updated['changes'][0]['new_val']; expect(oldVal['kit'].containsKey('drums'), equals(true)); expect(newVal['kit'].containsKey('bells'), equals(true)); expect(newVal['kit'].containsKey('drums'), equals(false)); }); }); group("replace command -> ", () { test("should replace a single selection", () async { Map replaced = await r.table(tableName!).get(1).replace({'id': 1}).run(connection!); expect(replaced['replaced'], equals(1)); }); test("should replace a selection", () async { Map replaced = await r.table(tableName!).getAll(1, 2).replace((item) { return item.pluck('kit', 'id'); }, {'return_changes': true}).run(connection!); expect(replaced['replaced'], equals(1)); Map newVal = replaced['changes'][0]['new_val']; Map oldVal = replaced['changes'][0]['old_val']; expect(newVal.containsKey('lastModified'), equals(false)); expect(oldVal.containsKey('lastModified'), equals(true)); }); test("should populate errors", () async { Map replaceError = await r.table(tableName!).get(1).replace({}).run(connection!); expect(replaceError['errors'], equals(1)); expect(replaceError['first_error'], equals('Inserted object must have primary key `id`:\n{}')); }); }); group("delete command -> ", () { test("should delete a single selection", () async { Map? deleted = await r .table(tableName!) .get(1) .delete({'return_changes': true}).run(connection!); Map? newVal = deleted!['changes'][0]['new_val']; Map? oldVal = deleted['changes'][0]['old_val']; expect(deleted['deleted'], equals(1)); expect(newVal, equals(null)); expect(oldVal!['id'], equals(1)); }); test("should delete a selection", () async { Map? deleted = await r .table(tableName!) .limit(2) .delete({'return_changes': true}).run(connection!); expect(deleted!['changes'].length, equals(2)); Map? newVal = deleted['changes'][0]['new_val']; Map? oldVal = deleted['changes'][0]['old_val']; expect(deleted['deleted'], equals(2)); expect(newVal, equals(null)); expect(oldVal!.containsKey('name') || oldVal.containsKey('kit'), equals(true)); newVal = deleted['changes'][1]['new_val']; oldVal = deleted['changes'][1]['old_val']; expect(newVal, equals(null)); expect(oldVal!.containsKey('name') || oldVal.containsKey('kit'), equals(true)); }); test("should delete all records on a table", () async { await r.table(tableName!).delete().run(connection!); Cursor results = await r.table(tableName!).run(connection!); List resList = await results.toList(); expect(resList.isEmpty, equals(true)); }); }); group("sync command -> ", () { test("should sync", () async { Map syncComplete = await r.table(tableName!).sync().run(connection!); expect(syncComplete.containsKey('synced'), equals(true)); expect(syncComplete['synced'], equals(1)); }); }); test("remove the test database", () async { Map response = await r.dbDrop(testDbName!).run(connection!); expect(response.containsKey('config_changes'), equals(true)); expect(response['dbs_dropped'], equals(1)); }); }