Tests for enum type conversion from mirror
This commit is contained in:
parent
fe27845bd1
commit
79ffc00fb1
6 changed files with 116 additions and 21 deletions
7
.idea/runConfigurations/tests_in_mirrors_test_dart.xml
Normal file
7
.idea/runConfigurations/tests_in_mirrors_test_dart.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="tests in mirrors_test.dart" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true" nameIsGenerated="true">
|
||||
<option name="filePath" value="$PROJECT_DIR$/graphql_server/test/mirrors_test.dart" />
|
||||
<option name="testRunnerOptions" value="-j4" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
|
@ -25,7 +25,7 @@ main() async {
|
|||
fields: [
|
||||
field(
|
||||
'todo',
|
||||
type: listType(objectTypeFromDartType(Todo).nonNullable()),
|
||||
type: listType(convertDartType(Todo).nonNullable()),
|
||||
resolve: resolveFromService(todoService),
|
||||
arguments: [
|
||||
new GraphQLFieldArgument('id', graphQLId),
|
||||
|
|
|
@ -1,39 +1,54 @@
|
|||
part of graphql_schema.src.schema;
|
||||
|
||||
GraphQLEnumType enumType(String name, List<String> values,
|
||||
GraphQLEnumType enumType<Value>(String name, Map<String, Value> values,
|
||||
{String description}) {
|
||||
return new GraphQLEnumType(
|
||||
name, values.map((s) => new GraphQLEnumValue(s)).toList(),
|
||||
return new GraphQLEnumType<Value>(
|
||||
name, values.keys.map((k) => new GraphQLEnumValue(k, values[k])).toList(),
|
||||
description: description);
|
||||
}
|
||||
|
||||
class GraphQLEnumType extends _GraphQLStringType {
|
||||
GraphQLEnumType enumTypeFromStrings(String name, List<String> values,
|
||||
{String description}) {
|
||||
return new GraphQLEnumType<String>(
|
||||
name, values.map((s) => new GraphQLEnumValue(s, s)).toList(),
|
||||
description: description);
|
||||
}
|
||||
|
||||
class GraphQLEnumType<Value> extends GraphQLScalarType<Value, String>
|
||||
with _NonNullableMixin<Value, String> {
|
||||
final String name;
|
||||
final List<GraphQLEnumValue> values;
|
||||
final List<GraphQLEnumValue<Value>> values;
|
||||
final String description;
|
||||
|
||||
GraphQLEnumType(this.name, this.values, {this.description}) : super._();
|
||||
GraphQLEnumType(this.name, this.values, {this.description});
|
||||
|
||||
@override
|
||||
String serialize(Value value) {
|
||||
return values.firstWhere((v) => v.value == value).name;
|
||||
}
|
||||
|
||||
@override
|
||||
Value deserialize(String serialized) {
|
||||
return values.firstWhere((v) => v.name == serialized).value;
|
||||
}
|
||||
|
||||
@override
|
||||
ValidationResult<String> validate(String key, String input) {
|
||||
var result = super.validate(key, input);
|
||||
|
||||
if (result.successful &&
|
||||
!values.map((v) => v.name).contains(result.value)) {
|
||||
return result._asFailure()
|
||||
..errors.add(
|
||||
'"${result.value}" is not a valid value for the enum "$name".');
|
||||
if (!values.any((v) => v.name == input)) {
|
||||
return new ValidationResult<String>._failure(
|
||||
['"$input" is not a valid value for the enum "$name".']);
|
||||
}
|
||||
|
||||
return result;
|
||||
return new ValidationResult<String>._ok(input);
|
||||
}
|
||||
}
|
||||
|
||||
class GraphQLEnumValue {
|
||||
class GraphQLEnumValue<Value> {
|
||||
final String name;
|
||||
final Value value;
|
||||
final String deprecationReason;
|
||||
|
||||
GraphQLEnumValue(this.name, {this.deprecationReason});
|
||||
GraphQLEnumValue(this.name, this.value, {this.deprecationReason});
|
||||
|
||||
bool get isDeprecated => deprecationReason != null;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:graphql_schema/graphql_schema.dart';
|
|||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
var typeType = enumType('Type', [
|
||||
var typeType = enumTypeFromStrings('Type', [
|
||||
'FIRE',
|
||||
'WATER',
|
||||
'GRASS',
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:tuple/tuple.dart';
|
|||
///
|
||||
/// This function is aware of the annotations from `package:angel_serialize`, and works seamlessly
|
||||
/// with them.
|
||||
GraphQLType objectTypeFromDartType(Type type, [List<Type> typeArguments]) {
|
||||
GraphQLType convertDartType(Type type, [List<Type> typeArguments]) {
|
||||
var tuple = new Tuple2(type, typeArguments);
|
||||
return _cache.putIfAbsent(
|
||||
tuple, () => _objectTypeFromDartType(type, typeArguments));
|
||||
|
@ -44,7 +44,13 @@ GraphQLType _objectTypeFromDartType(Type type, [List<Type> typeArguments]) {
|
|||
'$type is not a class, and therefore cannot be converted into a GraphQL object type.');
|
||||
}
|
||||
|
||||
return objectTypeFromClassMirror(mirror as ClassMirror);
|
||||
var clazz = mirror as ClassMirror;
|
||||
|
||||
if (clazz.isEnum) {
|
||||
return enumTypeFromClassMirror(clazz);
|
||||
}
|
||||
|
||||
return objectTypeFromClassMirror(clazz);
|
||||
}
|
||||
|
||||
GraphQLObjectType objectTypeFromClassMirror(ClassMirror mirror) {
|
||||
|
@ -69,9 +75,30 @@ GraphQLObjectType objectTypeFromClassMirror(ClassMirror mirror) {
|
|||
);
|
||||
}
|
||||
|
||||
GraphQLEnumType enumTypeFromClassMirror(ClassMirror mirror) {
|
||||
var values = <GraphQLEnumValue>[];
|
||||
|
||||
for (var name in mirror.staticMembers.keys) {
|
||||
var methodMirror = mirror.staticMembers[name];
|
||||
values.add(
|
||||
new GraphQLEnumValue(
|
||||
MirrorSystem.getName(name),
|
||||
mirror.getField(name).reflectee,
|
||||
deprecationReason: _getDeprecationReason(methodMirror.metadata),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return new GraphQLEnumType(
|
||||
MirrorSystem.getName(mirror.simpleName),
|
||||
values,
|
||||
description: _getDescription(mirror.metadata),
|
||||
);
|
||||
}
|
||||
|
||||
GraphQLField fieldFromGetter(
|
||||
Symbol name, MethodMirror mirror, Exclude exclude, ClassMirror clazz) {
|
||||
var type = objectTypeFromDartType(mirror.returnType.reflectedType,
|
||||
var type = convertDartType(mirror.returnType.reflectedType,
|
||||
mirror.returnType.typeArguments.map((t) => t.reflectedType).toList());
|
||||
|
||||
var nameString = _getSerializedName(name, mirror, clazz);
|
||||
|
|
46
graphql_server/test/mirrors_test.dart
Normal file
46
graphql_server/test/mirrors_test.dart
Normal file
|
@ -0,0 +1,46 @@
|
|||
import 'package:graphql_schema/graphql_schema.dart';
|
||||
import 'package:graphql_server/mirrors.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('convertDartType', () {
|
||||
group('on enum', () {
|
||||
var type = convertDartType(RomanceLanguage);
|
||||
var asEnumType = type as GraphQLEnumType;
|
||||
|
||||
test('produces enum type', () {
|
||||
expect(type is GraphQLEnumType, true);
|
||||
});
|
||||
|
||||
test('rejects invalid value', () {
|
||||
expect(asEnumType.validate('@root', 'GERMAN').successful, false);
|
||||
});
|
||||
|
||||
test('accepts valid value', () {
|
||||
expect(asEnumType.validate('@root', 'SPANISH').successful, true);
|
||||
});
|
||||
|
||||
test('deserializes to concrete value', () {
|
||||
expect(asEnumType.deserialize('ITALIAN'), RomanceLanguage.ITALIAN);
|
||||
});
|
||||
|
||||
test('serializes to concrete value', () {
|
||||
expect(asEnumType.serialize(RomanceLanguage.FRANCE), 'FRANCE');
|
||||
});
|
||||
|
||||
test('fails to serialize invalid value', () {
|
||||
expect(() => asEnumType.serialize(34), throwsStateError);
|
||||
});
|
||||
|
||||
test('fails to deserialize invalid value', () {
|
||||
expect(() => asEnumType.deserialize('JAPANESE'), throwsStateError);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
enum RomanceLanguage {
|
||||
SPANISH,
|
||||
FRANCE,
|
||||
ITALIAN,
|
||||
}
|
Loading…
Reference in a new issue