Skip to content

Commit e0fa7f8

Browse files
committed
better support for Java enums
graphql-java#526 better support for Java enums by using a serialisation strategy that knows about how Java Enum<?> have unique String names
1 parent 4beb6d6 commit e0fa7f8

3 files changed

Lines changed: 142 additions & 4 deletions

File tree

src/main/java/graphql/schema/GraphQLEnumType.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,24 @@ private Object getValueByName(Object value) {
8484

8585
private Object getNameByValue(Object value) {
8686
for (GraphQLEnumValueDefinition valueDefinition : valueDefinitionMap.values()) {
87-
if (value.equals(valueDefinition.getValue())) return valueDefinition.getName();
87+
Object definitionValue = valueDefinition.getValue();
88+
if (value.equals(definitionValue)) {
89+
return valueDefinition.getName();
90+
}
91+
}
92+
// ok we didn't match on pure object.equals(). Lets try the Java enum strategy
93+
if (value instanceof Enum) {
94+
String enumNameValue = ((Enum<?>) value).name();
95+
for (GraphQLEnumValueDefinition valueDefinition : valueDefinitionMap.values()) {
96+
Object definitionValue = String.valueOf(valueDefinition.getValue());
97+
if (enumNameValue.equals(definitionValue)) {
98+
return valueDefinition.getName();
99+
}
100+
}
88101
}
89102
throw new CoercingSerializeException("Invalid input for Enum '" + name + "'. Unknown value '" + value + "'");
90103
}
91104

92-
93105
public String getName() {
94106
return name;
95107
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package graphql
2+
3+
import graphql.schema.DataFetcher
4+
import graphql.schema.DataFetchingEnvironment
5+
import spock.lang.Specification
6+
7+
import static graphql.ExecutionInput.newExecutionInput
8+
import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring
9+
import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring
10+
11+
class Issue526 extends Specification {
12+
13+
enum Episode {
14+
NEWHOPE, EMPIRE, JEDI
15+
}
16+
17+
class Droid {
18+
List<Episode> appearsIn = [Episode.NEWHOPE, Episode.EMPIRE]
19+
20+
List<Episode> getAppearsIn() {
21+
return appearsIn
22+
}
23+
24+
Episode getEpisode() {
25+
return Episode.NEWHOPE
26+
}
27+
28+
String getName() {
29+
return "C3PO"
30+
}
31+
}
32+
33+
def "526 - Java enums can match string generated versions of them"() {
34+
35+
given:
36+
37+
def spec = """
38+
enum Episode {
39+
NEWHOPE,
40+
EMPIRE,
41+
JEDI
42+
}
43+
44+
type Droid {
45+
name: String,
46+
episode : Episode,
47+
appearsIn: [Episode],
48+
}
49+
50+
type Query {
51+
droid : Droid
52+
}
53+
"""
54+
55+
def schema = TestUtil.schema(spec, newRuntimeWiring()
56+
.type(newTypeWiring("Query").dataFetcher("droid", new DataFetcher() {
57+
@Override
58+
Object get(DataFetchingEnvironment environment) {
59+
return new Droid()
60+
}
61+
})))
62+
63+
def graphQL = GraphQL.newGraphQL(schema).build()
64+
def query = """
65+
{
66+
droid {
67+
name
68+
episode
69+
appearsIn
70+
}
71+
}
72+
"""
73+
def executionInput = newExecutionInput().query(query).build()
74+
75+
when:
76+
77+
def executionResult = graphQL.execute(executionInput)
78+
79+
then:
80+
81+
executionResult.errors.size() == 0
82+
executionResult.data == [
83+
droid: [
84+
name : "C3PO",
85+
episode : "NEWHOPE",
86+
appearsIn: [
87+
"NEWHOPE", "EMPIRE"
88+
],
89+
]
90+
]
91+
}
92+
}

src/test/groovy/graphql/schema/GraphQLEnumTypeTest.groovy

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class GraphQLEnumTypeTest extends Specification {
1414
def setup() {
1515
enumType = newEnum().name("TestEnum")
1616
.value("NAME", 42)
17-
.build();
17+
.build()
1818
}
1919

2020
def "parse throws exception for unknown value"() {
@@ -74,8 +74,42 @@ class GraphQLEnumTypeTest extends Specification {
7474
newEnum().name("AnotherTestEnum")
7575
.value("NAME", 42)
7676
.value("NAME", 43)
77-
.build();
77+
.build()
7878
then:
7979
thrown(AssertException)
8080
}
81+
82+
enum Episode {
83+
NEWHOPE, EMPIRE
84+
}
85+
86+
def "serialize Java enum objects with String definition values"() {
87+
88+
given:
89+
enumType = newEnum().name("Episode")
90+
.value("NEWHOPE", "NEWHOPE")
91+
.value("EMPIRE", "EMPIRE")
92+
.build()
93+
94+
when:
95+
def serialized = enumType.coercing.serialize(Episode.EMPIRE)
96+
97+
then:
98+
serialized == "EMPIRE"
99+
}
100+
101+
def "serialize Java enum objects with Java enum definition values"() {
102+
103+
given:
104+
enumType = newEnum().name("Episode")
105+
.value("NEWHOPE", Episode.NEWHOPE)
106+
.value("EMPIRE", Episode.EMPIRE)
107+
.build()
108+
109+
when:
110+
def serialized = enumType.coercing.serialize(Episode.NEWHOPE)
111+
112+
then:
113+
serialized == "NEWHOPE"
114+
}
81115
}

0 commit comments

Comments
 (0)