Tests for transactions

This commit is contained in:
Simon Binder 2019-03-10 12:38:53 +01:00
parent b5237bf36b
commit 09d047a868
No known key found for this signature in database
GPG Key ID: B807FDF954BA00CF
5 changed files with 69 additions and 3 deletions

View File

@ -319,8 +319,8 @@ supporting floating / fixed point numbers as well would be awesome
- Validation
- Table joins
- Bulk inserts
- Transactions
- Custom column constraints
- When inserts / updates fail, explain why that happened
### Interesting stuff that would be nice to have
Implementing this will very likely result in backwards-incompatible changes.

View File

@ -206,10 +206,11 @@ abstract class GeneratedDatabase extends DatabaseConnectionUser
/// [action] function.
Future transaction(Future Function(QueryEngine transaction) action) async {
final transaction = Transaction(this, executor.beginTransaction());
try {
await action(transaction);
} finally {
await transaction?.complete();
await transaction.complete();
}
}
}

View File

@ -9,6 +9,9 @@ export 'package:mockito/mockito.dart';
typedef Future<T> _EnsureOpenAction<T>(QueryExecutor e);
class MockExecutor extends Mock implements QueryExecutor {
final MockTransactionExecutor transactions = MockTransactionExecutor();
MockExecutor() {
when(runSelect(any, any)).thenAnswer((_) => Future.value([]));
when(runUpdate(any, any)).thenAnswer((_) => Future.value(0));
@ -19,9 +22,29 @@ class MockExecutor extends Mock implements QueryExecutor {
return action(this);
});
when(beginTransaction()).thenAnswer((_) => transactions);
}
}
class MockTransactionExecutor extends Mock implements TransactionExecutor {
MockTransactionExecutor() {
when(runSelect(any, any)).thenAnswer((_) => Future.value([]));
when(runUpdate(any, any)).thenAnswer((_) => Future.value(0));
when(runDelete(any, any)).thenAnswer((_) => Future.value(0));
when(runInsert(any, any)).thenAnswer((_) => Future.value(0));
when(doWhenOpened(any)).thenAnswer((i) {
final action = i.positionalArguments.single as _EnsureOpenAction;
return action(this);
});
when(send()).thenAnswer((_) => Future.value(null));
}
}
class MockStreamQueries extends Mock implements StreamQueryStore {}
// used so that we can mock the SqlExecutor typedef

View File

@ -0,0 +1,42 @@
import 'package:test_api/test_api.dart';
import 'data/tables/todos.dart';
import 'data/utils/mocks.dart';
void main() {
TodoDb db;
MockExecutor executor;
MockStreamQueries streamQueries;
setUp(() {
executor = MockExecutor();
streamQueries = MockStreamQueries();
db = TodoDb(executor)..streamQueries = streamQueries;
});
test("transactions don't allow creating streams", () {
expect(() async {
await db.transaction((t) {
t.select(db.users).watch();
});
}, throwsStateError);
verify(executor.transactions.send());
});
test('transactions notify about table udpates after completing', () async {
when(executor.transactions.runUpdate(any, any)).thenAnswer((_) => Future.value(2));
await db.transaction((t) async {
await t.update(db.users).write(User(name: 'Updated name'));
// Even though we just wrote to users, this only happened inside the
// transaction, so the top level stream queries should not be updated.
verifyNever(streamQueries.handleTableUpdates(any));
});
// After the transaction completes, the queries should be updated
verify(streamQueries.handleTableUpdates({'users'}));
verify(executor.transactions.send());
});
}

View File

@ -319,8 +319,8 @@ supporting floating / fixed point numbers as well would be awesome
- Validation
- Table joins
- Bulk inserts
- Transactions
- Custom column constraints
- When inserts / updates fail, explain why that happened
### Interesting stuff that would be nice to have
Implementing this will very likely result in backwards-incompatible changes.