Skip to content

Commit 89d7775

Browse files
authored
Merge pull request #559 from marcus-nl/bugfix/558
Test case and proposed fix for #558
2 parents fdb23af + dbcffac commit 89d7775

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

src/main/kotlin/graphql/kickstart/tools/DictionaryTypeResolver.kt

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,15 @@ internal abstract class DictionaryTypeResolver(
1616
private val dictionary: BiMap<JavaType, TypeDefinition<*>>,
1717
private val types: Map<String, GraphQLObjectType>
1818
) : TypeResolver {
19-
private fun <T> getTypeName(clazz: Class<T>): String? {
20-
val name = dictionary[clazz]?.name
21-
22-
if (name == null && clazz.superclass != null) {
23-
return getTypeName(clazz.superclass)
24-
}
25-
26-
return name
19+
private fun <T> getTypeDefinition(clazz: Class<T>): TypeDefinition<*>? {
20+
return dictionary[clazz]
21+
?: (if (clazz.superclass == null) null else getTypeDefinition(clazz.superclass))
22+
?: clazz.interfaces.mapNotNull { getTypeDefinition(it) }.firstOrNull()
2723
}
2824

2925
override fun getType(env: TypeResolutionEnvironment): GraphQLObjectType? {
3026
val clazz = env.getObject<Any>().javaClass
31-
val name = clazz.interfaces.fold(getTypeName(clazz), { name, interfaceClazz ->
32-
name ?: getTypeName(interfaceClazz)
33-
}) ?: clazz.simpleName
34-
27+
val name = getTypeDefinition(clazz)?.name ?: clazz.simpleName
3528
return types[name] ?: throw TypeResolverError(getError(name))
3629
}
3730

src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fun createSchema() = SchemaParser.newParser()
2222
.dictionary("ThirdItem", ThirdItem::class)
2323
.dictionary("ComplexMapItem", ComplexMapItem::class)
2424
.dictionary("NestedComplexMapItem", NestedComplexMapItem::class)
25+
.dictionary("NoDogError", NoDogError::class)
2526
.build()
2627
.makeExecutableSchema()
2728

@@ -83,6 +84,9 @@ type Query {
8384
arrayItems: [Item!]!
8485
8586
throwsIllegalArgumentException: String
87+
88+
allDogs: [Dog!]!
89+
findSuitableDog(preferredColor: String!, minimumFluffiness: Int!): FindDogResult!
8690
}
8791
8892
type ExtendedType {
@@ -216,6 +220,18 @@ type Tag {
216220
type ItemWithGenericProperties {
217221
keys: [String!]!
218222
}
223+
224+
type Dog {
225+
name: String!
226+
color: String!
227+
fluffiness: Int!
228+
}
229+
230+
type NoDogError {
231+
msg: String
232+
}
233+
234+
union FindDogResult = Dog | NoDogError
219235
"""
220236

221237
val items = listOf(
@@ -314,6 +330,13 @@ class Query : GraphQLQueryResolver, ListListResolver<String>() {
314330
fun throwsIllegalArgumentException(): String {
315331
throw IllegalArgumentException("Expected")
316332
}
333+
334+
fun allDogs(): List<Dog> = listOf(LabradorRetriever("Hershey", "chocolate", 42, 3.14159f))
335+
336+
fun findSuitableDog(preferredColor: String, minimumFluffiness: Int): Any =
337+
allDogs()
338+
.firstOrNull { it.color == preferredColor && it.fluffiness >= minimumFluffiness }
339+
?: NoDogError("No $preferredColor-colored dog found that is sufficiently fluffy")
317340
}
318341

319342
class UnusedRootResolver : GraphQLQueryResolver
@@ -410,6 +433,15 @@ class MockPart(private val name: String, private val content: String) : Part {
410433
override fun delete() = throw IllegalArgumentException("Not supported")
411434
}
412435

436+
interface Dog {
437+
val name: String
438+
val color: String
439+
val fluffiness: Int
440+
}
441+
interface Retriever : Dog { val speed: Float }
442+
class LabradorRetriever(override val name: String, override val color: String, override val fluffiness: Int, override val speed: Float) : Retriever
443+
class NoDogError(val msg: String)
444+
413445
val customScalarId = GraphQLScalarType.newScalar()
414446
.name("ID")
415447
.description("Overrides built-in ID")

src/test/kotlin/graphql/kickstart/tools/EndToEndTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,22 @@ class EndToEndTest {
178178
assertNotNull(data["itemByUUID"])
179179
}
180180

181+
@Test
182+
fun `generated schema should handle union types with deep hierarchy`() {
183+
val data = assertNoGraphQlErrors(gql) {
184+
"""
185+
{
186+
findSuitableDog(preferredColor: "chocolate", minimumFluffiness: 31) {
187+
... on Dog { name }
188+
... on NoDogError { msg }
189+
}
190+
}
191+
"""
192+
}
193+
194+
assertNotNull(data["findSuitableDog"])
195+
}
196+
181197
@Test
182198
fun `generated schema should handle non nullable scalar types`() {
183199
val fileParts = listOf(MockPart("test.doc", "Hello"), MockPart("test.doc", "World"))

0 commit comments

Comments
 (0)