add some more tests

This commit is contained in:
Moshe Dicker 2024-04-11 12:38:54 -04:00
parent 6a693a9016
commit 2f9a57317f
4 changed files with 168 additions and 59 deletions

View File

@ -230,7 +230,10 @@ class TableManagerState<
final count = countAll();
final result =
_buildSelectStatement(targetColumns: [count]) as _JoinedResult;
return result.statement.map((row) => row.read(count)!).getSingle();
return result.statement
.map((row) => row.read(count)!)
.get()
.then((value) => value.firstOrNull ?? 0);
}
/// Check if any rows exists using the built statement
@ -331,7 +334,7 @@ abstract class BaseTableManager<
///
/// See also: [RootTableManager.replace], which does not require [filter] statements and
/// supports setting fields back to null.
Future<int> write(Insertable<DT> Function(CU o) f) =>
Future<int> update(Insertable<DT> Function(CU o) f) =>
$state.buildUpdateStatement().write(f($state._getUpdateCompanionBuilder));
}
@ -441,8 +444,7 @@ abstract class RootTableManager<
/// Returns the amount of rows that were deleted by this statement directly
/// (not including additional rows that might be affected through triggers or
/// foreign key constraints).
Future<int> delete(Insertable<D> entity) =>
$state.db.delete($state._tableAsTableInfo).delete(entity);
Future<int> delete() => $state.db.delete($state._tableAsTableInfo).go();
/// Select all rows from the table
C all() => $state._getChildManagerBuilder($state);
@ -532,7 +534,7 @@ abstract class RootTableManager<
/// If [entity] has absent values (set to null on the [DataClass] or
/// explicitly to absent on the [UpdateCompanion]), and a default value for
/// the field exists, that default value will be used. Otherwise, the field
/// will be reset to null. This behavior is different to [write], which simply
/// will be reset to null. This behavior is different to [update], which simply
/// ignores such fields without changing them in the database.
///
/// Returns true if a row was affected by this operation.

View File

@ -1,54 +0,0 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
import '../generated/todos.dart';
import '../test_utils/matchers.dart';
import '../test_utils/mocks.dart';
void main() {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
late TodoDb db;
late MockExecutor executor;
setUp(() {
executor = MockExecutor();
db = TodoDb(executor);
});
test('manager - generates parentheses for OR in AND', () {
final filterComposer = $$CategoriesTableFilterComposer(db, db.categories);
final expr = (filterComposer.idValue(1) | filterComposer.idValue(2)) &
(filterComposer.idValue(3) | filterComposer.idValue(4));
expect(
expr.expression,
generates(
'("id" = ? OR "id" = ?) AND ("id" = ? OR "id" = ?)', [1, 2, 3, 4]));
});
test('manager - equals', () {
final filterComposer = $$CategoriesTableFilterComposer(db, db.categories);
// Numeric
expect(filterComposer.idValue.equals(3).expression,
generates('"id" = ?', [3]));
expect(filterComposer.idValue(3).expression, generates('"id" = ?', [3]));
expect(
filterComposer.idValue.isNull().expression, generates('"id" IS NULL'));
// Text
expect(filterComposer.description.equals("Hi").expression,
generates('"desc" = ?', ["Hi"]));
expect(filterComposer.description("Hi").expression,
generates('"desc" = ?', ["Hi"]));
expect(filterComposer.description.isNull().expression,
generates('"desc" IS NULL'));
});
// test('manager - combine query with AND ', () {
// e.expression.hashCode;
// expect(
// countAll(filter: e.expression),
// generates('WHERE "id" = FILTER (WHERE foo >= ?)', [1, 2]),
// );
// });
}

View File

@ -0,0 +1,16 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
import '../generated/todos.dart';
import '../test_utils/test_utils.dart';
void main() {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
late TodoDb db;
setUp(() {
db = TodoDb(testInMemoryDatabase());
});
tearDown(() => db.close());
}

View File

@ -0,0 +1,145 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
import '../generated/todos.dart';
import '../test_utils/test_utils.dart';
void main() {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
late TodoDb db;
setUp(() {
db = TodoDb(testInMemoryDatabase());
});
tearDown(() => db.close());
test('manager - create', () async {
// Initial count should be 0
expect(db.managers.categories.all().count(), completion(0));
// Creating a row should return the id
final create1 = db.managers.categories.create(
(o) => o(priority: Value(CategoryPriority.high), description: "High"));
expect(create1, completion(1));
expect(db.managers.categories.all().count(), completion(1));
// Creating another row should increment the id
final create2 = db.managers.categories.create(
(o) => o(priority: Value(CategoryPriority.low), description: "Low"));
expect(create2, completion(2));
expect(db.managers.categories.all().count(), completion(2));
// Using an existing id should throw an exception
final create3 = db.managers.categories.create((o) => o(
priority: Value(CategoryPriority.medium),
description: "Medium",
id: Value(RowId(1))));
expect(create3, throwsException);
// Using on conflict should not throw an exception
// Only using DoNothing test that onConflict is being passed to the create method
final create4 = db.managers.categories.create(
(o) => o(
priority: Value(CategoryPriority.medium),
description: "Medium",
id: Value(RowId(1))),
onConflict: DoNothing());
// The is incorrect when using onConflict
expect(create4, completion(2));
expect(db.managers.categories.all().count(), completion(2));
// Likewise, test that mode is passed to the create method
final create5 = db.managers.categories.create(
(o) => o(
priority: Value(CategoryPriority.medium),
description: "Medium",
id: Value(RowId(1))),
mode: InsertMode.insertOrIgnore);
// The is incorrect when using mode
expect(create5, completion(2));
expect(db.managers.categories.all().count(), completion(2));
// Test the other create methods
final create6 = db.managers.categories.createReturning((o) =>
o(priority: Value(CategoryPriority.high), description: "Other High"));
expect(create6, completion(isA<Category>()));
expect(db.managers.categories.all().count(), completion(3));
// Will return null because the description is not unique
final create7 = db.managers.categories.createReturningOrNull(
(o) => o(
priority: Value(CategoryPriority.high),
description: "High",
),
mode: InsertMode.insertOrIgnore);
expect(create7, completion(null));
// Test batch create
await db.managers.categories.bulkCreate((o) => [
o(priority: Value(CategoryPriority.high), description: "Super High"),
o(priority: Value(CategoryPriority.low), description: "Super Low"),
o(
priority: Value(CategoryPriority.medium),
description: "Super Medium")
]);
expect(db.managers.categories.all().count(), completion(6));
});
test('manager - update', () async {
// Create a row
final obj1 = await db.managers.categories.createReturning(
(o) => o(priority: Value(CategoryPriority.low), description: "Low"));
final obj2 = await db.managers.categories.createReturning((o) =>
o(priority: Value(CategoryPriority.low), description: "Other Low"));
// Replace the row
final update1 =
db.managers.categories.replace(obj1.copyWith(description: "Hello"));
expect(update1, completion(true));
expect(
db.managers.categories
.filter(((f) => f.id(obj1.id)))
.getSingle()
.then((value) => value.description),
completion("Hello"));
// Update All Rows
final update2 = db.managers.categories
.update((o) => o(priority: Value(CategoryPriority.high)));
expect(update2, completion(2));
// Update a single row
final update3 = db.managers.categories
.filter(((f) => f.id(obj2.id)))
.update((o) => o(description: Value("World")));
expect(update3, completion(1));
expect(
db.managers.categories
.filter(((f) => f.id(obj2.id)))
.getSingle()
.then((value) => value.description),
completion("World"));
});
test('manager - delete', () async {
// Create a row
final obj1 = await db.managers.categories.createReturning(
(o) => o(priority: Value(CategoryPriority.low), description: "Low"));
// ignore: unused_local_variable
final obj2 = await db.managers.categories.createReturning((o) =>
o(priority: Value(CategoryPriority.low), description: "Other Low"));
// Delete a single row
final delete1 =
db.managers.categories.filter(((f) => f.id(obj1.id))).delete();
expect(delete1, completion(1));
expect(db.managers.categories.all().count(), completion(1));
// Delete all rows
final delete2 = db.managers.categories.delete();
expect(delete2, completion(1));
expect(db.managers.categories.all().count(), completion(0));
});
}