mirror of https://github.com/AMT-Cheif/drift.git
Write unit tests for DelegateDatabase
This commit is contained in:
parent
308167dc12
commit
4137f6cffa
|
@ -168,6 +168,7 @@ class _TransactionExecutor extends TransactionExecutor
|
|||
Future<void> send() async {
|
||||
if (_sendOnCommit != null) {
|
||||
await runCustom(_sendOnCommit, const []);
|
||||
_db.delegate.isInTransaction = false;
|
||||
}
|
||||
|
||||
_sendCalled.complete();
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
import 'package:mockito/mockito.dart';
|
||||
import 'package:moor/backends.dart';
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockDelegate extends Mock implements DatabaseDelegate {}
|
||||
|
||||
class _MockUserDb extends Mock implements GeneratedDatabase {}
|
||||
|
||||
class _MockDynamicVersionDelegate extends Mock
|
||||
implements DynamicVersionDelegate {}
|
||||
|
||||
class _MockTransactionDelegate extends Mock
|
||||
implements SupportedTransactionDelegate {}
|
||||
|
||||
void main() {
|
||||
_MockDelegate delegate;
|
||||
setUp(() {
|
||||
delegate = _MockDelegate();
|
||||
|
||||
when(delegate.isOpen).thenAnswer((_) => Future.value(true));
|
||||
when(delegate.runSelect(any, any))
|
||||
.thenAnswer((_) => Future.value(QueryResult.fromRows([])));
|
||||
when(delegate.runUpdate(any, any)).thenAnswer((_) => Future.value(3));
|
||||
when(delegate.runInsert(any, any)).thenAnswer((_) => Future.value(4));
|
||||
when(delegate.runCustom(any, any)).thenAnswer((_) => Future.value());
|
||||
when(delegate.runBatched(any)).thenAnswer((_) => Future.value());
|
||||
});
|
||||
|
||||
group('delegates queries', () {
|
||||
void _runTests(bool sequential) {
|
||||
test('when sequential = $sequential', () async {
|
||||
final db = DelegatedDatabase(delegate, isSequential: sequential);
|
||||
|
||||
await db.doWhenOpened((_) async {
|
||||
expect(await db.runSelect(null, null), isEmpty);
|
||||
expect(await db.runUpdate(null, null), 3);
|
||||
expect(await db.runInsert(null, null), 4);
|
||||
await db.runCustom(null);
|
||||
await db.runBatched(null);
|
||||
});
|
||||
|
||||
verifyInOrder([
|
||||
delegate.isOpen,
|
||||
delegate.runSelect(null, null),
|
||||
delegate.runUpdate(null, null),
|
||||
delegate.runInsert(null, null),
|
||||
delegate.runCustom(null, []),
|
||||
delegate.runBatched(null),
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
_runTests(false);
|
||||
_runTests(true);
|
||||
});
|
||||
|
||||
group('migrations', () {
|
||||
DelegatedDatabase db;
|
||||
_MockUserDb userDb;
|
||||
setUp(() {
|
||||
userDb = _MockUserDb();
|
||||
when(userDb.schemaVersion).thenReturn(3);
|
||||
|
||||
when(delegate.isOpen).thenAnswer((_) => Future.value(false));
|
||||
db = DelegatedDatabase(delegate)..databaseInfo = userDb;
|
||||
|
||||
when(userDb.handleDatabaseCreation(executor: anyNamed('executor')))
|
||||
.thenAnswer((i) async {
|
||||
final executor = i.namedArguments.values.single as SqlExecutor;
|
||||
await executor('created', []);
|
||||
});
|
||||
|
||||
when(userDb.handleDatabaseVersionChange(
|
||||
executor: anyNamed('executor'),
|
||||
from: anyNamed('from'),
|
||||
to: anyNamed('to'),
|
||||
)).thenAnswer((i) async {
|
||||
final executor = i.namedArguments[#executor] as SqlExecutor;
|
||||
final from = i.namedArguments[#from] as int;
|
||||
final to = i.namedArguments[#to] as int;
|
||||
await executor('upgraded', [from, to]);
|
||||
});
|
||||
});
|
||||
|
||||
test('when the database does not support versions', () async {
|
||||
when(delegate.versionDelegate).thenReturn(const NoVersionDelegate());
|
||||
await db.doWhenOpened((_) async {});
|
||||
|
||||
verify(delegate.open(userDb));
|
||||
verifyNever(delegate.runCustom(any, any));
|
||||
});
|
||||
|
||||
test('when the database supports versions at opening', () async {
|
||||
when(delegate.versionDelegate)
|
||||
.thenReturn(OnOpenVersionDelegate(() => Future.value(3)));
|
||||
await db.doWhenOpened((_) async {});
|
||||
|
||||
verify(delegate.open(userDb));
|
||||
verifyNever(delegate.runCustom(any, any));
|
||||
});
|
||||
|
||||
test('when the database supports dynamic version', () async {
|
||||
final version = _MockDynamicVersionDelegate();
|
||||
when(version.schemaVersion).thenAnswer((_) => Future.value(3));
|
||||
|
||||
when(delegate.versionDelegate).thenReturn(version);
|
||||
await db.doWhenOpened((_) async {});
|
||||
|
||||
verify(delegate.open(userDb));
|
||||
verifyNever(delegate.runCustom(any, any));
|
||||
verify(version.schemaVersion);
|
||||
verify(version.setSchemaVersion(3));
|
||||
});
|
||||
|
||||
test('handles database creations', () async {
|
||||
when(delegate.versionDelegate)
|
||||
.thenReturn(OnOpenVersionDelegate(() => Future.value(0)));
|
||||
await db.doWhenOpened((_) async {});
|
||||
|
||||
verify(delegate.runCustom('created', []));
|
||||
});
|
||||
|
||||
test('handles database upgrades', () async {
|
||||
when(delegate.versionDelegate)
|
||||
.thenReturn(OnOpenVersionDelegate(() => Future.value(1)));
|
||||
await db.doWhenOpened((_) async {});
|
||||
|
||||
verify(delegate.runCustom('upgraded', [1, 3]));
|
||||
});
|
||||
});
|
||||
|
||||
group('transactions', () {
|
||||
DelegatedDatabase db;
|
||||
|
||||
setUp(() {
|
||||
db = DelegatedDatabase(delegate, isSequential: true);
|
||||
});
|
||||
|
||||
test('when the delegate does not support transactions', () async {
|
||||
when(delegate.transactionDelegate)
|
||||
.thenReturn(const NoTransactionDelegate());
|
||||
await db.doWhenOpened((_) async {
|
||||
final transaction = db.beginTransaction();
|
||||
await transaction.doWhenOpened((e) async {
|
||||
await e.runSelect(null, null);
|
||||
|
||||
await transaction.send();
|
||||
});
|
||||
});
|
||||
|
||||
verifyInOrder([
|
||||
delegate.runCustom('BEGIN TRANSACTION', []),
|
||||
delegate.runSelect(null, null),
|
||||
delegate.runCustom('COMMIT TRANSACTION', []),
|
||||
]);
|
||||
});
|
||||
|
||||
test('when the database supports transactions', () async {
|
||||
final transaction = _MockTransactionDelegate();
|
||||
when(transaction.startTransaction(any)).thenAnswer((i) {
|
||||
(i.positionalArguments.single as Function(QueryDelegate))(delegate);
|
||||
});
|
||||
|
||||
when(delegate.transactionDelegate).thenReturn(transaction);
|
||||
|
||||
await db.doWhenOpened((_) async {
|
||||
final transaction = db.beginTransaction();
|
||||
await transaction.doWhenOpened((e) async {
|
||||
await e.runSelect(null, null);
|
||||
|
||||
await transaction.send();
|
||||
});
|
||||
});
|
||||
|
||||
verify(transaction.startTransaction(any));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -18,6 +18,7 @@ void main() {
|
|||
test('generates insert statements', () async {
|
||||
await db.into(db.todosTable).insert(const TodosTableCompanion(
|
||||
content: Value('Implement insert statements'),
|
||||
title: Value.absent(),
|
||||
));
|
||||
|
||||
verify(executor.runInsert('INSERT INTO todos (content) VALUES (?)',
|
||||
|
@ -111,16 +112,21 @@ void main() {
|
|||
verify(streamQueries.handleTableUpdates({db.users}));
|
||||
});
|
||||
|
||||
test('enforces data integrity', () {
|
||||
expect(
|
||||
db.into(db.todosTable).insert(
|
||||
test('enforces data integrity', () async {
|
||||
InvalidDataException exception;
|
||||
try {
|
||||
await db.into(db.todosTable).insert(
|
||||
const TodosTableCompanion(
|
||||
// not declared as nullable in table definition
|
||||
content: Value(null),
|
||||
),
|
||||
),
|
||||
throwsA(const TypeMatcher<InvalidDataException>()),
|
||||
);
|
||||
);
|
||||
fail('inserting invalid data did not throw');
|
||||
} on InvalidDataException catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
expect(exception.toString(), startsWith('InvalidDataException'));
|
||||
});
|
||||
|
||||
test('reports auto-increment id', () async {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:moor/moor.dart';
|
||||
import 'package:moor/src/runtime/components/join.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'data/tables/todos.dart';
|
||||
import 'data/utils/mocks.dart';
|
||||
|
@ -113,4 +114,19 @@ void main() {
|
|||
verify(executor.runSelect(
|
||||
argThat(contains('WHERE t.id < ? ORDER BY t.title ASC')), [3]));
|
||||
});
|
||||
|
||||
test('injects custom error message when a table is used multiple times',
|
||||
() async {
|
||||
when(executor.runSelect(any, any)).thenAnswer((_) => Future.error('nah'));
|
||||
|
||||
MoorWrappedException wrappedException;
|
||||
try {
|
||||
await db.select(db.todosTable).join([crossJoin(db.todosTable)]).get();
|
||||
fail('expected this to throw');
|
||||
} on MoorWrappedException catch (e) {
|
||||
wrappedException = e;
|
||||
}
|
||||
|
||||
expect(wrappedException.toString(), contains('possible cause'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void main() {
|
|||
|
||||
group('Migrations', () {
|
||||
test('creates all tables', () async {
|
||||
await Migrator(db, mockQueryExecutor).createAllTables();
|
||||
await db.handleDatabaseCreation(executor: mockQueryExecutor);
|
||||
|
||||
// should create todos, categories, users and shared_todos table
|
||||
verify(mockQueryExecutor.call(
|
||||
|
|
Loading…
Reference in New Issue