Skip to content

Commit

Permalink
Increase test coverage (#539)
Browse files Browse the repository at this point in the history
* expand test coverage

* More tests, fix Index.equals

* test toString of ProcessorError
  • Loading branch information
mqus authored Apr 22, 2021
1 parent c3cdb4a commit 98333a4
Show file tree
Hide file tree
Showing 12 changed files with 765 additions and 62 deletions.
19 changes: 6 additions & 13 deletions floor_generator/lib/processor/deletion_method_processor.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:floor_generator/misc/change_method_processor_helper.dart';
import 'package:floor_generator/processor/error/change_method_processor_error.dart';
import 'package:floor_generator/processor/processor.dart';
import 'package:floor_generator/value_object/deletion_method.dart';
import 'package:floor_generator/value_object/entity.dart';
import 'package:source_gen/source_gen.dart';

class DeletionMethodProcessor implements Processor<DeletionMethod> {
final MethodElement _methodElement;
final ChangeMethodProcessorHelper _helper;
final ChangeMethodProcessorError _errors;

DeletionMethodProcessor(
final MethodElement methodElement,
final List<Entity> entities, [
final ChangeMethodProcessorHelper? changeMethodProcessorHelper,
]) : _methodElement = methodElement,
_errors = ChangeMethodProcessorError(methodElement, 'Deletion'),
_helper = changeMethodProcessorHelper ??
ChangeMethodProcessorHelper(methodElement, entities);

Expand All @@ -32,10 +34,7 @@ class DeletionMethodProcessor implements Processor<DeletionMethod> {
final returnsInt = flattenedReturnType.isDartCoreInt;

if (!returnsVoid && !returnsInt) {
throw InvalidGenerationSourceError(
'Deletion methods have to return a Future of either void or int.',
element: _methodElement,
);
throw _errors.doesNotReturnVoidNorInt;
}

final parameterElement = _helper.getParameterElement();
Expand All @@ -60,19 +59,13 @@ class DeletionMethodProcessor implements Processor<DeletionMethod> {

void _assertMethodReturnsNoList(final DartType flattenedReturnType) {
if (flattenedReturnType.isDartCoreList) {
throw InvalidGenerationSourceError(
'Deletion methods have to return a Future of either void or int but not a list.',
element: _methodElement,
);
throw _errors.shouldNotReturnList;
}
}

void _assertMethodReturnsFuture(final DartType returnType) {
if (!returnType.isDartAsyncFuture) {
throw InvalidGenerationSourceError(
'Deletion methods have to return a Future.',
element: _methodElement,
);
throw _errors.doesNotReturnFuture;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:floor_generator/misc/constants.dart';
import 'package:floor_annotation/floor_annotation.dart' as annotations
show OnConflictStrategy;
import 'package:source_gen/source_gen.dart';

class ChangeMethodProcessorError {
final MethodElement _methodElement;
final String _methodType;

ChangeMethodProcessorError(this._methodElement, this._methodType);

InvalidGenerationSourceError get doesNotReturnVoidNorInt =>
InvalidGenerationSourceError(
'$_methodType methods have to return a Future of either void or int.',
element: _methodElement,
);

InvalidGenerationSourceError get doesNotReturnFuture =>
InvalidGenerationSourceError(
'$_methodType methods have to return a Future.',
element: _methodElement,
);

InvalidGenerationSourceError get shouldNotReturnList =>
InvalidGenerationSourceError(
'$_methodType methods have to return a Future of either void or int but not a list.',
element: _methodElement,
);
InvalidGenerationSourceError get doesNotReturnVoidNorIntNorListInt =>
InvalidGenerationSourceError(
'$_methodType methods have to return a Future of either void, int or List<int>.',
element: _methodElement,
);
InvalidGenerationSourceError get wrongOnConflictValue =>
InvalidGenerationSourceError(
'Value of ${AnnotationField.onConflict} must be one of ${annotations.OnConflictStrategy.values.map((e) => e.toString()).join(',')}',
element: _methodElement,
);
}
21 changes: 7 additions & 14 deletions floor_generator/lib/processor/insertion_method_processor.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:floor_annotation/floor_annotation.dart' as annotations
show Insert, OnConflictStrategy;
show Insert;
import 'package:floor_generator/misc/change_method_processor_helper.dart';
import 'package:floor_generator/misc/constants.dart';
import 'package:floor_generator/misc/extension/dart_object_extension.dart';
import 'package:floor_generator/misc/type_utils.dart';
import 'package:floor_generator/processor/error/change_method_processor_error.dart';
import 'package:floor_generator/processor/processor.dart';
import 'package:floor_generator/value_object/entity.dart';
import 'package:floor_generator/value_object/insertion_method.dart';
import 'package:source_gen/source_gen.dart';

class InsertionMethodProcessor implements Processor<InsertionMethod> {
final MethodElement _methodElement;
final ChangeMethodProcessorHelper _helper;
final ChangeMethodProcessorError _errors;

InsertionMethodProcessor(
final MethodElement methodElement,
final List<Entity> entities, [
final ChangeMethodProcessorHelper? changeMethodProcessorHelper,
]) : _methodElement = methodElement,
_errors = ChangeMethodProcessorError(methodElement, 'Insertion'),
_helper = changeMethodProcessorHelper ??
ChangeMethodProcessorHelper(methodElement, entities);

Expand All @@ -39,10 +41,7 @@ class InsertionMethodProcessor implements Processor<InsertionMethod> {
final returnsIntList = returnsList && flattenedReturnType.isDartCoreInt;

if (!returnsVoid && !returnsIntList && !returnsInt) {
throw InvalidGenerationSourceError(
'Insertion methods have to return a Future of either void, int or List<int>.',
element: _methodElement,
);
throw _errors.doesNotReturnVoidNorIntNorListInt;
}

final parameterElement = _helper.getParameterElement();
Expand Down Expand Up @@ -83,21 +82,15 @@ class InsertionMethodProcessor implements Processor<InsertionMethod> {
?.toEnumValueString();

if (onConflictStrategy == null) {
throw InvalidGenerationSourceError(
'Value of ${AnnotationField.onConflict} must be one of ${annotations.OnConflictStrategy.values.map((e) => e.toString()).join(',')}',
element: _methodElement,
);
throw _errors.wrongOnConflictValue;
} else {
return onConflictStrategy;
}
}

void _assertMethodReturnsFuture(final DartType returnType) {
if (!returnType.isDartAsyncFuture) {
throw InvalidGenerationSourceError(
'Insertion methods have to return a Future.',
element: _methodElement,
);
throw _errors.doesNotReturnFuture;
}
}
}
26 changes: 8 additions & 18 deletions floor_generator/lib/processor/update_method_processor.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:floor_annotation/floor_annotation.dart' as annotations
show Update, OnConflictStrategy;
show Update;
import 'package:floor_generator/misc/change_method_processor_helper.dart';
import 'package:floor_generator/misc/constants.dart';
import 'package:floor_generator/misc/extension/dart_object_extension.dart';
import 'package:floor_generator/misc/type_utils.dart';
import 'package:floor_generator/processor/error/change_method_processor_error.dart';
import 'package:floor_generator/processor/processor.dart';
import 'package:floor_generator/value_object/entity.dart';
import 'package:floor_generator/value_object/update_method.dart';
import 'package:source_gen/source_gen.dart';

class UpdateMethodProcessor implements Processor<UpdateMethod> {
final MethodElement _methodElement;
final ChangeMethodProcessorHelper _helper;
final ChangeMethodProcessorError _errors;

UpdateMethodProcessor(
final MethodElement methodElement,
final List<Entity> entities, [
final ChangeMethodProcessorHelper? changeMethodProcessorHelper,
]) : _methodElement = methodElement,
_errors = ChangeMethodProcessorError(methodElement, 'Update'),
_helper = changeMethodProcessorHelper ??
ChangeMethodProcessorHelper(methodElement, entities);

Expand All @@ -37,10 +39,7 @@ class UpdateMethodProcessor implements Processor<UpdateMethod> {
final returnsVoid = flattenedReturnType.isVoid;

if (!returnsInt && !returnsVoid) {
throw InvalidGenerationSourceError(
'Update methods have to return a Future of either void or int.',
element: _methodElement,
);
throw _errors.doesNotReturnVoidNorInt;
}

final parameterElement = _helper.getParameterElement();
Expand All @@ -67,10 +66,7 @@ class UpdateMethodProcessor implements Processor<UpdateMethod> {
?.toEnumValueString();

if (onConflictStrategy == null) {
throw InvalidGenerationSourceError(
'Value of ${AnnotationField.onConflict} must be one of ${annotations.OnConflictStrategy.values.map((e) => e.toString()).join(',')}',
element: _methodElement,
);
throw _errors.wrongOnConflictValue;
} else {
return onConflictStrategy;
}
Expand All @@ -82,19 +78,13 @@ class UpdateMethodProcessor implements Processor<UpdateMethod> {

void _assertMethodReturnsNoList(final DartType flattenedReturnType) {
if (flattenedReturnType.isDartCoreList) {
throw InvalidGenerationSourceError(
'Update methods have to return a Future of either void or int but not a list.',
element: _methodElement,
);
throw _errors.shouldNotReturnList;
}
}

void _assertMethodReturnsFuture(final DartType returnType) {
if (!returnType.isDartAsyncFuture) {
throw InvalidGenerationSourceError(
'Update methods have to return a Future.',
element: _methodElement,
);
throw _errors.doesNotReturnFuture;
}
}
}
4 changes: 3 additions & 1 deletion floor_generator/lib/value_object/index.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:collection/collection.dart';

class Index {
final String name;
final String tableName;
Expand Down Expand Up @@ -25,7 +27,7 @@ class Index {
name == other.name &&
tableName == other.tableName &&
unique == other.unique &&
columnNames == other.columnNames;
const ListEquality<String>().equals(columnNames, other.columnNames);

@override
int get hashCode =>
Expand Down
116 changes: 116 additions & 0 deletions floor_generator/test/processor/deletion_method_processor_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import 'package:floor_generator/processor/deletion_method_processor.dart';
import 'package:floor_generator/processor/error/change_method_processor_error.dart';
import 'package:source_gen/source_gen.dart';
import 'package:test/test.dart';

import '../test_utils.dart';

void main() {
group('expected errors', () {
test('when not accepting Parameter', () async {
final deletionMethod = await '''
@delete
Future<void> deletePerson();
'''
.asDaoMethodElement();
final entities = await getPersonEntity();

final actual =
() => DeletionMethodProcessor(deletionMethod, [entities]).process();

expect(
actual,
throwsInvalidGenerationSourceError(InvalidGenerationSourceError(
'There is no parameter supplied for this method. Please add one.',
element: deletionMethod,
)));
});
test('when accepting more than one Parameter', () async {
final deletionMethod = await '''
@delete
Future<void> deletePerson(Person p1, Person p2);
'''
.asDaoMethodElement();
final entities = await getPersonEntity();

final actual =
() => DeletionMethodProcessor(deletionMethod, [entities]).process();

expect(
actual,
throwsInvalidGenerationSourceError(InvalidGenerationSourceError(
'Only one parameter is allowed on this.',
element: deletionMethod,
)));
});
test('when not accepting an Entity', () async {
final deletionMethod = await '''
@delete
Future<void> deletePerson(int p2);
'''
.asDaoMethodElement();
final entities = await getPersonEntity();

final actual =
() => DeletionMethodProcessor(deletionMethod, [entities]).process();

expect(
actual,
throwsInvalidGenerationSourceError(InvalidGenerationSourceError(
'You are trying to change an object which is not an entity.',
element: deletionMethod,
)));
});
test('when not returning Future', () async {
final deletionMethod = await '''
@delete
void deletePerson(Person person);
'''
.asDaoMethodElement();
final entities = await getPersonEntity();

final actual =
() => DeletionMethodProcessor(deletionMethod, [entities]).process();

expect(
actual,
throwsInvalidGenerationSourceError(
ChangeMethodProcessorError(deletionMethod, 'Deletion')
.doesNotReturnFuture));
});
test('when returning a List', () async {
final deletionMethod = await '''
@delete
Future<List<int>> deletePerson(Person person);
'''
.asDaoMethodElement();
final entities = await getPersonEntity();

final actual =
() => DeletionMethodProcessor(deletionMethod, [entities]).process();

expect(
actual,
throwsInvalidGenerationSourceError(
ChangeMethodProcessorError(deletionMethod, 'Deletion')
.shouldNotReturnList));
});
test('when not returning int or void', () async {
final deletionMethod = await '''
@delete
Future<bool> deletePerson(Person person);
'''
.asDaoMethodElement();
final entities = await getPersonEntity();

final actual =
() => DeletionMethodProcessor(deletionMethod, [entities]).process();

expect(
actual,
throwsInvalidGenerationSourceError(
ChangeMethodProcessorError(deletionMethod, 'Deletion')
.doesNotReturnVoidNorInt));
});
});
}
Loading

0 comments on commit 98333a4

Please sign in to comment.