Skip to content

Commit e3a00b7

Browse files
committed
test for union types (bugfixing along the way)
1 parent 20a7177 commit e3a00b7

8 files changed

Lines changed: 174 additions & 20 deletions

File tree

‎src/main/java/graphql/execution/Execution.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import java.util.concurrent.ExecutorService;
1717
import java.util.concurrent.Future;
1818

19-
import static graphql.introspection.Schema.*;
19+
import static graphql.introspection.Introspection.*;
2020

2121
public class Execution {
2222

‎src/main/java/graphql/execution/ValuesResolver.java‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ public Map<String, Object> getArgumentValues(List<GraphQLArgument> argumentTypes
2424
Map<String, Argument> argumentMap = argumentMap(arguments);
2525
for (GraphQLArgument fieldArgument : argumentTypes) {
2626
Argument argument = argumentMap.get(fieldArgument.getName());
27-
Object value = coerceValueAst(fieldArgument.getType(), argument.getValue(), variables);
28-
result.put(argument.getName(), value);
27+
Object value;
28+
if (argument != null) {
29+
value = coerceValueAst(fieldArgument.getType(), argument.getValue(), variables);
30+
} else {
31+
value = fieldArgument.getDefaultValue();
32+
}
33+
result.put(fieldArgument.getName(), value);
2934
}
3035
return result;
3136
}
@@ -120,7 +125,7 @@ private Object coerceValueAst(GraphQLType type, Value inputValue, Map<String, Ob
120125
return ((GraphQLEnumType) type).getCoercing().coerceLiteral(inputValue);
121126
}
122127
if (type instanceof GraphQLList) {
123-
return coerceValueAstForList((GraphQLList) type,inputValue,variables);
128+
return coerceValueAstForList((GraphQLList) type, inputValue, variables);
124129
}
125130
return null;
126131
}

src/main/java/graphql/introspection/Schema.java renamed to src/main/java/graphql/introspection/Introspection.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88

99
import static graphql.Scalars.GraphQLBoolean;
1010
import static graphql.Scalars.GraphQLString;
11+
import static graphql.schema.GraphQLArgument.newArgument;
1112
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
1213
import static graphql.schema.GraphQLObjectType.newObject;
1314

14-
public class Schema {
15+
public class Introspection {
1516

1617
public enum TypeKind {
1718
SCALAR,
@@ -253,7 +254,7 @@ public Object get(DataFetchingEnvironment environment) {
253254
.field(newFieldDefinition()
254255
.name("fields")
255256
.type(new GraphQLList(new GraphQLNonNull(__Field)))
256-
.argument(GraphQLArgument.newArgument()
257+
.argument(newArgument()
257258
.name("includeDeprecated")
258259
.type(GraphQLBoolean)
259260
.defaultValue(false)
@@ -273,7 +274,7 @@ public Object get(DataFetchingEnvironment environment) {
273274
.field(newFieldDefinition()
274275
.name("enumValues")
275276
.type(new GraphQLList(new GraphQLNonNull(__EnumValue)))
276-
.argument(GraphQLArgument.newArgument()
277+
.argument(newArgument()
277278
.name("includeDeprecated")
278279
.type(GraphQLBoolean)
279280
.defaultValue(false)
@@ -323,7 +324,7 @@ public Object get(DataFetchingEnvironment environment) {
323324

324325
public static GraphQLObjectType __Schema = newObject()
325326
.name("__Schema")
326-
.description("A GraphQL Schema defines the capabilities" +
327+
.description("A GraphQL Introspection defines the capabilities" +
327328
" of a GraphQL server. It exposes all available types and directives on " +
328329
"'the server, as well as the entry points for query and 'mutation operations.")
329330
.field(newFieldDefinition()
@@ -390,8 +391,12 @@ public Object get(DataFetchingEnvironment environment) {
390391

391392
public static GraphQLFieldDefinition TypeMetaFieldDef = newFieldDefinition()
392393
.name("__type")
393-
.type(new GraphQLNonNull(__Type))
394-
.description("Access the current type schema of this server.")
394+
.type(__Type)
395+
.description("Request the type information of a single type.")
396+
.argument(newArgument()
397+
.name("name")
398+
.type(new GraphQLNonNull(GraphQLString))
399+
.build())
395400
.dataFetcher(new DataFetcher() {
396401
@Override
397402
public Object get(DataFetchingEnvironment environment) {
@@ -404,7 +409,7 @@ public Object get(DataFetchingEnvironment environment) {
404409
public static GraphQLFieldDefinition TypeNameMetaFieldDef = newFieldDefinition()
405410
.name("__typename")
406411
.type(new GraphQLNonNull(GraphQLString))
407-
.description("Access the current type schema of this server.")
412+
.description("The name of the current Object type at runtime.")
408413
.dataFetcher(new DataFetcher() {
409414
@Override
410415
public Object get(DataFetchingEnvironment environment) {
@@ -414,4 +419,14 @@ public Object get(DataFetchingEnvironment environment) {
414419
.build();
415420

416421

422+
static {
423+
// make sure all TypeReferences are resolved
424+
GraphQLSchema.newSchema()
425+
.query(GraphQLObjectType.newObject()
426+
.field(SchemaMetaFieldDef)
427+
.field(TypeMetaFieldDef)
428+
.field(TypeNameMetaFieldDef)
429+
.build())
430+
.build();
431+
}
417432
}

‎src/main/java/graphql/schema/SchemaUtil.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ private void collectTypes(GraphQLType root, Map<String, GraphQLType> result) {
5656
}
5757

5858
private void collectTypesForUnions(GraphQLUnionType unionType, Map<String, GraphQLType> result) {
59+
result.put(unionType.getName(), unionType);
5960
for (GraphQLType type : unionType.getTypes()) {
6061
collectTypes(type, result);
6162
}

‎src/main/java/graphql/validation/TraversalContext.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.util.ArrayList;
1010
import java.util.List;
1111

12-
import static graphql.introspection.Schema.*;
12+
import static graphql.introspection.Introspection.*;
1313

1414
public class TraversalContext implements QueryLanguageVisitor {
1515
GraphQLSchema schema;

‎src/test/groovy/graphql/GarfieldSchema.java‎

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
import graphql.schema.*;
55

6+
import java.util.Arrays;
7+
import java.util.Collections;
8+
import java.util.List;
9+
610
import static graphql.Scalars.GraphQLBoolean;
711
import static graphql.Scalars.GraphQLString;
812
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
@@ -11,7 +15,69 @@
1115

1216
public class GarfieldSchema {
1317

14-
public static GraphQLInterfaceType Named = newInterface()
18+
public interface Named {
19+
String getName();
20+
}
21+
22+
public static class Dog implements Named {
23+
private final String name;
24+
private final boolean barks;
25+
26+
public Dog(String name, boolean barks) {
27+
this.name = name;
28+
this.barks = barks;
29+
}
30+
31+
@Override
32+
public String getName() {
33+
return name;
34+
}
35+
}
36+
37+
public static class Cat implements Named {
38+
private final String name;
39+
private final boolean meows;
40+
41+
public Cat(String name, boolean meows) {
42+
this.name = name;
43+
this.meows = meows;
44+
}
45+
46+
@Override
47+
public String getName() {
48+
return name;
49+
}
50+
}
51+
52+
public static class Person implements Named {
53+
private final String name;
54+
private List<Dog> dogs;
55+
private List<Cat> cats;
56+
private List<Named> friends;
57+
58+
public Person(String name) {
59+
this(name, Collections.<Cat>emptyList(), Collections.<Dog>emptyList(), Collections.<Named>emptyList());
60+
}
61+
62+
public Person(String name, List<Cat> cats, List<Dog> dogs, List<Named> friends) {
63+
this.name = name;
64+
this.dogs = dogs;
65+
this.cats = cats;
66+
this.friends = friends;
67+
}
68+
69+
@Override
70+
public String getName() {
71+
return name;
72+
}
73+
}
74+
75+
public static Cat garfield = new Cat("Garfield", false);
76+
public static Dog odie = new Dog("Odie", true);
77+
public static Person liz = new Person("Liz");
78+
public static Person john = new Person("John", Arrays.asList(garfield), Arrays.asList(odie), Arrays.asList(liz, odie));
79+
80+
public static GraphQLInterfaceType NamedType = newInterface()
1581
.name("Named")
1682
.field(newFieldDefinition()
1783
.name("name")
@@ -29,7 +95,7 @@ public class GarfieldSchema {
2995
.name("barks")
3096
.type(GraphQLBoolean)
3197
.build())
32-
.withInterface(Named)
98+
.withInterface(NamedType)
3399
.build();
34100

35101
public static GraphQLObjectType CatType = newObject()
@@ -39,18 +105,25 @@ public class GarfieldSchema {
39105
.type(GraphQLString)
40106
.build())
41107
.field(newFieldDefinition()
42-
.name("barks")
108+
.name("meows")
43109
.type(GraphQLBoolean)
44110
.build())
45-
.withInterface(Named)
111+
.withInterface(NamedType)
46112
.build();
47113

48114
public static GraphQLUnionType PetType = GraphQLUnionType.newUnionType()
49-
.possibleType(DogType)
115+
.name("Pet")
50116
.possibleType(CatType)
117+
.possibleType(DogType)
51118
.typeResolver(new TypeResolver() {
52119
@Override
53120
public GraphQLObjectType getType(Object object) {
121+
if (object instanceof Cat) {
122+
return CatType;
123+
}
124+
if (object instanceof Dog){
125+
return DogType;
126+
}
54127
return null;
55128
}
56129
})
@@ -68,9 +141,9 @@ public GraphQLObjectType getType(Object object) {
68141
.build())
69142
.field(newFieldDefinition()
70143
.name("friends")
71-
.type(new GraphQLList(Named))
144+
.type(new GraphQLList(NamedType))
72145
.build())
73-
.withInterface(Named)
146+
.withInterface(NamedType)
74147
.build();
75148

76149
public static GraphQLSchema GarfieldSchema = GraphQLSchema.newSchema()

‎src/test/groovy/graphql/UnionTest.groovy‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,64 @@ import spock.lang.Specification
44

55
class UnionTest extends Specification {
66

7+
8+
def "can introspect on union and intersection types"() {
9+
def query = """
10+
{
11+
Named: __type(name: "Named") {
12+
kind
13+
name
14+
fields { name }
15+
interfaces { name }
16+
possibleTypes { name }
17+
enumValues { name }
18+
inputFields { name }
19+
}
20+
Pet: __type(name: "Pet") {
21+
kind
22+
name
23+
fields { name }
24+
interfaces { name }
25+
possibleTypes { name }
26+
enumValues { name }
27+
inputFields { name }
28+
}
29+
}
30+
"""
31+
when:
32+
def exeutionResult = new GraphQL(GarfieldSchema.GarfieldSchema, query).execute()
33+
34+
then:
35+
exeutionResult.result == [Named: [
36+
kind : 'INTERFACE',
37+
name : 'Named',
38+
fields : [
39+
[name: 'name']
40+
],
41+
interfaces : null,
42+
possibleTypes: [
43+
[name: 'Person'],
44+
[name: 'Cat'],
45+
[name: 'Dog']
46+
],
47+
enumValues : null,
48+
inputFields : null
49+
],
50+
Pet : [
51+
kind : 'UNION',
52+
name : 'Pet',
53+
fields : null,
54+
interfaces : null,
55+
possibleTypes: [
56+
[name: 'Cat'],
57+
[name: 'Dog']
58+
],
59+
enumValues : null,
60+
inputFields : null
61+
]
62+
]
63+
64+
65+
}
66+
767
}

src/test/groovy/graphql/schema/SchemaUtilTest.groovy renamed to src/test/groovy/graphql/schema/IntrospectionUtilTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import spock.lang.Specification
55
import static graphql.Scalars.GraphQLString
66
import static graphql.StarWarsSchema.*
77

8-
class SchemaUtilTest extends Specification {
8+
class IntrospectionUtilTest extends Specification {
99

1010
def "collectAllTypes"() {
1111
when:

0 commit comments

Comments
 (0)