Skip to content

Commit c2ad125

Browse files
committed
graphql-java#427 added spec tests and values resolver support
1 parent 35524b1 commit c2ad125

File tree

6 files changed

+340
-21
lines changed

6 files changed

+340
-21
lines changed

src/main/java/graphql/execution/ExecutionStrategy.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import graphql.execution.instrumentation.parameters.FieldFetchParameters;
1212
import graphql.execution.instrumentation.parameters.FieldParameters;
1313
import graphql.language.Field;
14+
import graphql.schema.DataFetcher;
1415
import graphql.schema.DataFetchingEnvironment;
1516
import graphql.schema.DataFetchingEnvironmentImpl;
1617
import graphql.schema.DataFetchingFieldSelectionSet;
@@ -96,7 +97,8 @@ protected ExecutionResult resolveField(ExecutionContext executionContext, Execut
9697
InstrumentationContext<Object> fetchCtx = instrumentation.beginFieldFetch(new FieldFetchParameters(executionContext, fieldDef, environment));
9798
Object resolvedValue = null;
9899
try {
99-
resolvedValue = fieldDef.getDataFetcher().get(environment);
100+
DataFetcher dataFetcher = fieldDef.getDataFetcher();
101+
resolvedValue = dataFetcher.get(environment);
100102

101103
fetchCtx.onEnd(resolvedValue);
102104
} catch (Exception e) {

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

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,43 @@
22

33

44
import graphql.GraphQLException;
5-
import graphql.language.*;
6-
import graphql.schema.*;
5+
import graphql.language.Argument;
6+
import graphql.language.ArrayValue;
7+
import graphql.language.NullValue;
8+
import graphql.language.ObjectField;
9+
import graphql.language.ObjectValue;
10+
import graphql.language.Value;
11+
import graphql.language.VariableDefinition;
12+
import graphql.language.VariableReference;
13+
import graphql.schema.GraphQLArgument;
14+
import graphql.schema.GraphQLEnumType;
15+
import graphql.schema.GraphQLInputObjectField;
16+
import graphql.schema.GraphQLInputObjectType;
17+
import graphql.schema.GraphQLList;
18+
import graphql.schema.GraphQLNonNull;
19+
import graphql.schema.GraphQLScalarType;
20+
import graphql.schema.GraphQLSchema;
21+
import graphql.schema.GraphQLType;
722

8-
import java.util.*;
23+
import java.util.ArrayList;
24+
import java.util.Collections;
25+
import java.util.LinkedHashMap;
26+
import java.util.List;
27+
import java.util.Map;
928

1029
public class ValuesResolver {
1130

1231

13-
public Map<String, Object> getVariableValues(GraphQLSchema schema, List<VariableDefinition> variableDefinitions, Map<String, Object> inputs) {
32+
public Map<String, Object> getVariableValues(GraphQLSchema schema, List<VariableDefinition> variableDefinitions, Map<String, Object> args) {
1433
Map<String, Object> result = new LinkedHashMap<>();
1534
for (VariableDefinition variableDefinition : variableDefinitions) {
16-
result.put(variableDefinition.getName(), getVariableValue(schema, variableDefinition, inputs.get(variableDefinition.getName())));
35+
String varName = variableDefinition.getName();
36+
// we transfer the variable as field arguments if its present as value
37+
if (args.containsKey(varName)) {
38+
Object arg = args.get(varName);
39+
Object variableValue = getVariableValue(schema, variableDefinition, arg);
40+
result.put(varName, variableValue);
41+
}
1742
}
1843
return result;
1944
}
@@ -23,14 +48,19 @@ public Map<String, Object> getArgumentValues(List<GraphQLArgument> argumentTypes
2348
Map<String, Object> result = new LinkedHashMap<>();
2449
Map<String, Argument> argumentMap = argumentMap(arguments);
2550
for (GraphQLArgument fieldArgument : argumentTypes) {
26-
Argument argument = argumentMap.get(fieldArgument.getName());
51+
String argName = fieldArgument.getName();
52+
Argument argument = argumentMap.get(argName);
2753
Object value;
2854
if (argument != null) {
2955
value = coerceValueAst(fieldArgument.getType(), argument.getValue(), variables);
3056
} else {
3157
value = fieldArgument.getDefaultValue();
3258
}
33-
result.put(fieldArgument.getName(), value);
59+
// only put an arg into the result IF they specified a variable at all or
60+
// the default value ended up being something non null
61+
if (argumentMap.containsKey(argName) || value != null) {
62+
result.put(argName, value);
63+
}
3464
}
3565
return result;
3666
}
@@ -48,6 +78,7 @@ private Map<String, Argument> argumentMap(List<Argument> arguments) {
4878
private Object getVariableValue(GraphQLSchema schema, VariableDefinition variableDefinition, Object inputValue) {
4979
GraphQLType type = TypeFromAST.getTypeFromAST(schema, variableDefinition.getType());
5080

81+
//noinspection ConstantConditions
5182
if (!isValid(type, inputValue)) {
5283
throw new GraphQLException("Invalid value for type");
5384
}
@@ -81,6 +112,7 @@ private Object coerceValue(GraphQLType graphQLType, Object value) {
81112
} else if (graphQLType instanceof GraphQLList) {
82113
return coerceValueForList((GraphQLList) graphQLType, value);
83114
} else if (graphQLType instanceof GraphQLInputObjectType && value instanceof Map) {
115+
//noinspection unchecked
84116
return coerceValueForInputObjectType((GraphQLInputObjectType) graphQLType, (Map<String, Object>) value);
85117
} else if (graphQLType instanceof GraphQLInputObjectType) {
86118
return value;
@@ -170,22 +202,49 @@ private Object coerceValueAstForInputObject(GraphQLInputObjectType type, ObjectV
170202

171203
for (GraphQLInputObjectField inputTypeField : type.getFields()) {
172204
if (inputValueFieldsByName.containsKey(inputTypeField.getName())) {
205+
boolean putObjectInMap = true;
206+
173207
ObjectField field = inputValueFieldsByName.get(inputTypeField.getName());
174-
Object fieldValue = coerceValueAst(inputTypeField.getType(), field.getValue(), variables);
175-
if (fieldValue == null) {
176-
fieldValue = inputTypeField.getDefaultValue();
208+
Value fieldInputValue = field.getValue();
209+
210+
Object fieldObject = null;
211+
if (fieldInputValue instanceof VariableReference) {
212+
String varName = ((VariableReference) fieldInputValue).getName();
213+
if (!variables.containsKey(varName)) {
214+
putObjectInMap = false;
215+
} else {
216+
fieldObject = variables.get(varName);
217+
}
218+
} else {
219+
fieldObject = coerceValueAst(inputTypeField.getType(), fieldInputValue, variables);
220+
}
221+
222+
if (fieldObject == null) {
223+
if (!field.getValue().isEqualTo(NullValue.Null)) {
224+
fieldObject = inputTypeField.getDefaultValue();
225+
}
226+
}
227+
if (putObjectInMap) {
228+
result.put(field.getName(), fieldObject);
229+
} else {
230+
assertNonNullInputField(inputTypeField);
177231
}
178-
result.put(field.getName(), fieldValue);
179232
} else if (inputTypeField.getDefaultValue() != null) {
180233
result.put(inputTypeField.getName(), inputTypeField.getDefaultValue());
181-
} else if (inputTypeField.getType() instanceof GraphQLNonNull) {
182-
// Possibly overkill; an object literal with a missing non null field shouldn't pass validation
183-
throw new GraphQLException("Null value for NonNull type " + inputTypeField.getType());
234+
} else {
235+
assertNonNullInputField(inputTypeField);
184236
}
185237
}
186238
return result;
187239
}
188240

241+
private void assertNonNullInputField(GraphQLInputObjectField inputTypeField) {
242+
if (inputTypeField.getType() instanceof GraphQLNonNull) {
243+
// Possibly overkill; an object literal with a missing non null field shouldn't pass validation
244+
throw new GraphQLException("Null value for NonNull type " + inputTypeField.getType());
245+
}
246+
}
247+
189248
private Map<String, ObjectField> mapObjectValueFieldsByName(ObjectValue inputValue) {
190249
Map<String, ObjectField> inputValueFieldsByName = new LinkedHashMap<>();
191250
for (ObjectField objectField : inputValue.getObjectFields()) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package graphql
2+
3+
import graphql.schema.DataFetcher
4+
import graphql.schema.DataFetchingEnvironment
5+
6+
/**
7+
* Help to capture data fetcher arguments passed in
8+
*/
9+
class CapturingDataFetcher implements DataFetcher {
10+
Map<String, Object> args
11+
DataFetchingEnvironment environment
12+
13+
@Override
14+
Object get(DataFetchingEnvironment environment) {
15+
this.environment = environment
16+
this.args = environment.getArguments()
17+
null
18+
}
19+
}

src/test/groovy/graphql/GraphQLTest.groovy

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ class GraphQLTest extends Specification {
157157
set.add("One")
158158
set.add("Two")
159159

160-
def schema = GraphQLSchema.newSchema()
161-
.query(GraphQLObjectType.newObject()
160+
def schema = newSchema()
161+
.query(newObject()
162162
.name("QueryType")
163-
.field(GraphQLFieldDefinition.newFieldDefinition()
163+
.field(newFieldDefinition()
164164
.name("set")
165165
.type(new GraphQLList(GraphQLString))
166166
.dataFetcher({ set })))
@@ -231,7 +231,7 @@ class GraphQLTest extends Specification {
231231
.build()
232232

233233
when:
234-
def result = new GraphQL(schema).execute("mutation { doesNotExist }");
234+
def result = new GraphQL(schema).execute("mutation { doesNotExist }")
235235

236236
then:
237237
result.errors.size() == 1
@@ -373,12 +373,12 @@ class GraphQLTest extends Specification {
373373
.build()
374374
def query = "{foo}"
375375
when:
376-
def result = GraphQL.newGraphQL(schema).build().execute(query)
376+
GraphQL.newGraphQL(schema).build().execute(query)
377377

378378
then:
379379
1 * dataFetcher.get(_) >> {
380380
DataFetchingEnvironment env ->
381-
assert env.arguments.size() == 1
381+
assert env.arguments.size() == 0
382382
assert env.arguments['bar'] == null
383383
}
384384
}

0 commit comments

Comments
 (0)