Updated test cases

This commit is contained in:
thomashii@dukefirehawk.com 2021-05-06 09:19:23 +08:00
parent 291c852f65
commit 64bddb1ff7
7 changed files with 50 additions and 29 deletions

View file

@ -4,13 +4,14 @@ import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart'; import 'package:angel_orm/angel_orm.dart';
import 'package:angel_orm/src/query.dart'; import 'package:angel_orm/src/query.dart';
import 'package:angel_serialize/angel_serialize.dart'; import 'package:angel_serialize/angel_serialize.dart';
import 'package:optional/optional.dart';
part 'main.g.dart'; part 'main.g.dart';
void main() async { void main() async {
var query = EmployeeQuery() var query = EmployeeQuery()
..where!.firstName.equals('Rich') ..where!.firstName.equals('Rich')
..where!.lastName.equals('Person') ..where!.lastName.equals('Person')
..orWhere((w) => w!.salary.greaterThanOrEqualTo(75000)) ..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
..join('companies', 'company_id', 'id'); ..join('companies', 'company_id', 'id');
var richPerson = await (query.getOne(_FakeExecutor()) as FutureOr<Employee>); var richPerson = await (query.getOne(_FakeExecutor()) as FutureOr<Employee>);
@ -23,7 +24,7 @@ class _FakeExecutor extends QueryExecutor {
@override @override
Future<List<List>> query( Future<List<List>> query(
String tableName, String? query, Map<String, dynamic> substitutionValues, String tableName, String? query, Map<String, dynamic> substitutionValues,
[returningFields]) async { [returningFields = const []]) async {
var now = DateTime.now(); var now = DateTime.now();
print( print(
'_FakeExecutor received query: $query and values: $substitutionValues'); '_FakeExecutor received query: $query and values: $substitutionValues');

View file

@ -30,7 +30,7 @@ class EmployeeMigration extends Migration {
// OrmGenerator // OrmGenerator
// ************************************************************************** // **************************************************************************
class EmployeeQuery extends Query<Employee?, EmployeeQueryWhere?> { class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
EmployeeQuery({Set<String>? trampoline}) { EmployeeQuery({Set<String>? trampoline}) {
trampoline ??= {}; trampoline ??= {};
trampoline.add(tableName); trampoline.add(tableName);
@ -75,8 +75,10 @@ class EmployeeQuery extends Query<Employee?, EmployeeQueryWhere?> {
return EmployeeQueryWhere(this); return EmployeeQueryWhere(this);
} }
static Employee? parseRow(List row) { static Optional<Employee> parseRow(List row) {
if (row.every((x) => x == null)) return null; if (row.every((x) => x == null)) {
return Optional.empty();
}
var model = Employee( var model = Employee(
id: (row[0] as String?), id: (row[0] as String?),
createdAt: (row[1] as DateTime?), createdAt: (row[1] as DateTime?),
@ -85,11 +87,11 @@ class EmployeeQuery extends Query<Employee?, EmployeeQueryWhere?> {
firstName: (row[4] as String?), firstName: (row[4] as String?),
lastName: (row[5] as String?), lastName: (row[5] as String?),
salary: double.tryParse(row[6].toString())); salary: double.tryParse(row[6].toString()));
return model; return Optional.of(model);
} }
@override @override
Employee? deserialize(List row) { Optional<Employee> deserialize(List row) {
return parseRow(row); return parseRow(row);
} }
} }

View file

@ -42,11 +42,11 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
return null; return null;
} }
var resolver = await buildStep.resolver; var resolver = buildStep.resolver;
var ctx = await buildOrmContext({}, element, annotation, buildStep, var ctx = await buildOrmContext({}, element, annotation, buildStep,
resolver, autoSnakeCaseNames != false); resolver, autoSnakeCaseNames != false);
var lib = generateMigrationLibrary(ctx, element, resolver, buildStep); var lib = generateMigrationLibrary(ctx, element, resolver, buildStep);
if (lib == null) return null; //if (lib == null) return null;
return DartFormatter().format(lib.accept(DartEmitter()).toString()); return DartFormatter().format(lib.accept(DartEmitter()).toString());
} }
@ -79,7 +79,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
..body = Block((closureBody) { ..body = Block((closureBody) {
var table = refer('table'); var table = refer('table');
List<String?> dup = []; var dup = <String>[];
ctx.columns.forEach((name, col) { ctx.columns.forEach((name, col) {
// Skip custom-expression columns. // Skip custom-expression columns.
if (col.hasExpression) return; if (col.hasExpression) return;
@ -106,13 +106,16 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
if (relationship.localKey == key) return; if (relationship.localKey == key) return;
} }
} }
if (key != null) {
dup.add(key); dup.add(key);
} else {
print('Skip: key is null');
}
} }
String? methodName; String? methodName;
List<Expression> positional = [literal(key)]; var positional = <Expression>[literal(key)];
Map<String, Expression> named = {}; var named = <String, Expression>{};
if (autoIdAndDateFields != false && name == 'id') { if (autoIdAndDateFields != false && name == 'id') {
methodName = 'serial'; methodName = 'serial';
@ -195,7 +198,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
try { try {
var index = var index =
ConstantReader(defaultValue).read('index').intValue; ConstantReader(defaultValue).read('index').intValue;
if (index != null) defaultExpr = literalNum(index); defaultExpr = literalNum(index);
} catch (_) { } catch (_) {
// Extremely weird error occurs here: `Not an instance of int`. // Extremely weird error occurs here: `Not an instance of int`.
// Definitely an analyzer issue. // Definitely an analyzer issue.

View file

@ -247,7 +247,7 @@ Future<OrmBuildContext?> buildOrmContext(
var enumFields = var enumFields =
joinTypeType.element.fields.where((f) => f.isEnumConstant).toList(); joinTypeType.element.fields.where((f) => f.isEnumConstant).toList();
for (int i = 0; i < enumFields.length; i++) { for (var i = 0; i < enumFields.length; i++) {
if (enumFields[i].computeConstantValue() == joinTypeRdr) { if (enumFields[i].computeConstantValue() == joinTypeRdr) {
joinType = JoinType.values[i]; joinType = JoinType.values[i];
break; break;
@ -411,6 +411,7 @@ class RelationFieldImpl extends ShimFieldImpl {
String get originalFieldName => originalField.name; String get originalFieldName => originalField.name;
@override
PropertyAccessorElement? get getter => originalField.getter; PropertyAccessorElement? get getter => originalField.getter;
} }

View file

@ -72,7 +72,7 @@ class RelationshipReader {
orElse: () { orElse: () {
throw '${ctx.buildContext.clazz.name} has no field that maps to the name "$localKey", ' throw '${ctx.buildContext.clazz.name} has no field that maps to the name "$localKey", '
'but it has a @HasMany() relation that expects such a field.'; 'but it has a @HasMany() relation that expects such a field.';
} as FieldElement Function()?); });
} }
FieldElement findForeignField(OrmBuildContext? ctx) { FieldElement findForeignField(OrmBuildContext? ctx) {
@ -82,6 +82,6 @@ class RelationshipReader {
orElse: () { orElse: () {
throw '${foreign.buildContext.clazz.name} has no field that maps to the name "$foreignKey", ' throw '${foreign.buildContext.clazz.name} has no field that maps to the name "$foreignKey", '
'but ${ctx!.buildContext.clazz.name} has a @HasMany() relation that expects such a field.'; 'but ${ctx!.buildContext.clazz.name} has a @HasMany() relation that expects such a field.';
} as FieldElement Function()?); });
} }
} }

View file

@ -57,3 +57,4 @@ dev_dependencies:
pedantic: ^1.11.0 pedantic: ^1.11.0
postgres: ^2.3.2 postgres: ^2.3.2
test: ^1.17.3 test: ^1.17.3
optional: ^6.0.0-nullsafety.2

View file

@ -95,15 +95,22 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
Future<User?> fetchThosakwe() async { Future<User?> fetchThosakwe() async {
var query = UserQuery()..where!.id.equals(int.parse(thosakwe!.id!)); var query = UserQuery()..where!.id.equals(int.parse(thosakwe!.id!));
return (await query.getOne(executor)).value; var userOpt = await query.getOne(executor);
expect(userOpt.isPresent, true);
if (userOpt.isPresent) {
return userOpt.value;
} else {
return null;
}
} }
test('fetch roles for user', () async { test('fetch roles for user', () async {
printSeparator('Fetch roles for user test'); printSeparator('Fetch roles for user test');
var user = await (fetchThosakwe() as FutureOr<User>); var user = await fetchThosakwe();
expect(user.roles, hasLength(2));
expect(user.roles, contains(canPub)); expect(user?.roles, hasLength(2));
expect(user.roles, contains(canSub)); expect(user?.roles, contains(canPub));
expect(user?.roles, contains(canSub));
}); });
test('fetch users for role', () async { test('fetch users for role', () async {
@ -122,12 +129,18 @@ manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
..username = 'Prince' ..username = 'Prince'
..password = 'Rogers' ..password = 'Rogers'
..email = 'Nelson'; ..email = 'Nelson';
var user = await (userQuery.insert(executor) as FutureOr<User>); var userOpt = await userQuery.insert(executor);
expect(user.roles, isEmpty); expect(userOpt.isPresent, true);
userOpt.ifPresent((user) async {
expect(user.roles, isEmpty);
// Fetch again, just to be doubly sure. // Fetch again, just to be doubly sure.
var query = UserQuery()..where!.id.equals(user.idAsInt!); var query = UserQuery()..where!.id.equals(user.idAsInt!);
var fetched = await (query.getOne(executor) as FutureOr<User>); var fetchedOpt = await query.getOne(executor);
expect(fetched.roles, isEmpty); expect(fetchedOpt.isPresent, true);
fetchedOpt.ifPresent((fetched) {
expect(fetched.roles, isEmpty);
});
});
}); });
} }