Skip to content

Commit 119250f

Browse files
authored
Added ability to return lists of DataFetcherResults in functions (#1150)
1 parent a3b49f3 commit 119250f

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

generator/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/internal/types/utils/functionReturnTypes.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import graphql.execution.DataFetcherResult
2222
import org.reactivestreams.Publisher
2323
import java.util.concurrent.CompletableFuture
2424
import kotlin.reflect.KType
25+
import kotlin.reflect.KTypeProjection
26+
import kotlin.reflect.KVariance
27+
import kotlin.reflect.full.createType
2528

2629
/**
2730
* These are the classes that can be returned from data fetchers (ie functions)
@@ -38,12 +41,16 @@ import kotlin.reflect.KType
3841
* Publisher<DataFetcherResult<T>>
3942
* CompletableFuture<T>
4043
* CompletableFuture<DataFetcherResult<T>>
44+
* List<DataFetcherResult<T>>
4145
*/
4246
internal fun getWrappedReturnType(returnType: KType): KType {
4347
return when {
4448
returnType.isSubclassOf(DataFetcherResult::class) -> returnType.getTypeOfFirstArgument()
4549
returnType.isSubclassOf(Publisher::class) -> { checkTypeForDataFetcherResult(returnType) }
4650
returnType.isSubclassOf(CompletableFuture::class) -> { checkTypeForDataFetcherResult(returnType) }
51+
returnType.isSubclassOf(List::class) && returnType.getTypeOfFirstArgument().isSubclassOf(DataFetcherResult::class) -> {
52+
List::class.createType(listOf(KTypeProjection(KVariance.INVARIANT, getWrappedReturnType(returnType.getTypeOfFirstArgument()))))
53+
}
4754
else -> returnType
4855
}
4956
}
@@ -55,6 +62,7 @@ internal fun getWrappedReturnType(returnType: KType): KType {
5562
* Published<DataFetcherResult<T>>
5663
* CompletableFuture<T>
5764
* CompletableFuture<DataFetcherResult<T>>
65+
* List<DataFetcherResult<T>>
5866
*/
5967
private fun checkTypeForDataFetcherResult(returnType: KType): KType {
6068
val wrappedType = returnType.getTypeOfFirstArgument()

generator/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/internal/types/utils/FunctionReturnTypesKtTest.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ class FunctionReturnTypesKtTest {
2828
class MyClass {
2929
// Valid Types
3030
val string = "my string"
31+
val listOfString: List<String> = listOf(string)
3132
val dataFetcherResult: DataFetcherResult<String> = DataFetcherResult.newResult<String>().data(string).build()
33+
val listDataFetcherResult: List<DataFetcherResult<String>> = listOf(DataFetcherResult.newResult<String>().data(string).build())
3234
val publisher: Publisher<String> = Flowable.just(string)
3335
val flowable: Flowable<String> = Flowable.just(string)
3436
val publisherDataFetcherResult: Publisher<DataFetcherResult<String>> = Flowable.just(dataFetcherResult)
@@ -54,6 +56,11 @@ class FunctionReturnTypesKtTest {
5456
assertEquals(MyClass::publisher.returnType, actual = getWrappedReturnType(MyClass::invalidDataFetcherResultPublisher.returnType))
5557
}
5658

59+
@Test
60+
fun `getWrappedReturnType of List of DataFetcherResult`() {
61+
assertEquals(MyClass::listOfString.returnType, actual = getWrappedReturnType(MyClass::listDataFetcherResult.returnType))
62+
}
63+
5764
@Test
5865
fun `getWrappedReturnType of CompletableFuture`() {
5966
assertEquals(MyClass::string.returnType, actual = getWrappedReturnType(MyClass::completableFuture.returnType))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2021 Expedia, Inc
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.expediagroup.graphql.generator.test.integration
18+
19+
import com.expediagroup.graphql.generator.TopLevelObject
20+
import com.expediagroup.graphql.generator.testSchemaConfig
21+
import com.expediagroup.graphql.generator.toSchema
22+
import graphql.execution.DataFetcherResult
23+
import org.junit.jupiter.api.Test
24+
import kotlin.test.assertEquals
25+
import kotlin.test.assertNotNull
26+
27+
class DataFetcherResultListTest {
28+
29+
@Test
30+
fun validateSchema() {
31+
val queries = listOf(TopLevelObject(SimpleQuery()))
32+
val schema = toSchema(testSchemaConfig, queries)
33+
assertNotNull(schema)
34+
assertEquals("String!", schema.queryType.getFieldDefinition("getString").type.toString())
35+
assertEquals("String!", schema.queryType.getFieldDefinition("getDataFetcherResultString").type.toString())
36+
assertEquals("[String!]!", schema.queryType.getFieldDefinition("getListString").type.toString())
37+
}
38+
39+
class SimpleQuery {
40+
private val string = "hello"
41+
42+
fun getString(): String = string
43+
fun getDataFetcherResultString(): DataFetcherResult<String> =
44+
DataFetcherResult.newResult<String>().data(string).build()
45+
fun getListString(): List<DataFetcherResult<String>> = listOf(DataFetcherResult.newResult<String>().data(string).build())
46+
}
47+
}

0 commit comments

Comments
 (0)