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 {
|
Future<void> send() async {
|
||||||
if (_sendOnCommit != null) {
|
if (_sendOnCommit != null) {
|
||||||
await runCustom(_sendOnCommit, const []);
|
await runCustom(_sendOnCommit, const []);
|
||||||
|
_db.delegate.isInTransaction = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendCalled.complete();
|
_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 {
|
test('generates insert statements', () async {
|
||||||
await db.into(db.todosTable).insert(const TodosTableCompanion(
|
await db.into(db.todosTable).insert(const TodosTableCompanion(
|
||||||
content: Value('Implement insert statements'),
|
content: Value('Implement insert statements'),
|
||||||
|
title: Value.absent(),
|
||||||
));
|
));
|
||||||
|
|
||||||
verify(executor.runInsert('INSERT INTO todos (content) VALUES (?)',
|
verify(executor.runInsert('INSERT INTO todos (content) VALUES (?)',
|
||||||
|
@ -111,16 +112,21 @@ void main() {
|
||||||
verify(streamQueries.handleTableUpdates({db.users}));
|
verify(streamQueries.handleTableUpdates({db.users}));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('enforces data integrity', () {
|
test('enforces data integrity', () async {
|
||||||
expect(
|
InvalidDataException exception;
|
||||||
db.into(db.todosTable).insert(
|
try {
|
||||||
|
await db.into(db.todosTable).insert(
|
||||||
const TodosTableCompanion(
|
const TodosTableCompanion(
|
||||||
// not declared as nullable in table definition
|
// not declared as nullable in table definition
|
||||||
content: Value(null),
|
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 {
|
test('reports auto-increment id', () async {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:moor/moor.dart';
|
import 'package:moor/moor.dart';
|
||||||
|
import 'package:moor/src/runtime/components/join.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'data/tables/todos.dart';
|
import 'data/tables/todos.dart';
|
||||||
import 'data/utils/mocks.dart';
|
import 'data/utils/mocks.dart';
|
||||||
|
@ -113,4 +114,19 @@ void main() {
|
||||||
verify(executor.runSelect(
|
verify(executor.runSelect(
|
||||||
argThat(contains('WHERE t.id < ? ORDER BY t.title ASC')), [3]));
|
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', () {
|
group('Migrations', () {
|
||||||
test('creates all tables', () async {
|
test('creates all tables', () async {
|
||||||
await Migrator(db, mockQueryExecutor).createAllTables();
|
await db.handleDatabaseCreation(executor: mockQueryExecutor);
|
||||||
|
|
||||||
// should create todos, categories, users and shared_todos table
|
// should create todos, categories, users and shared_todos table
|
||||||
verify(mockQueryExecutor.call(
|
verify(mockQueryExecutor.call(
|
||||||
|
|
Loading…
Reference in New Issue