diff --git a/examples/client/gradle-client/build.gradle.kts b/examples/client/gradle-client/build.gradle.kts index 952c502bfd..b2b1a27f04 100644 --- a/examples/client/gradle-client/build.gradle.kts +++ b/examples/client/gradle-client/build.gradle.kts @@ -3,7 +3,7 @@ import com.expediagroup.graphql.plugin.gradle.graphql plugins { application - id("org.jetbrains.kotlin.jvm") version "1.3.72" + id("org.jetbrains.kotlin.jvm") version "1.4.0" id("com.expediagroup.graphql") version "3.1.0" } diff --git a/examples/client/maven-client/pom.xml b/examples/client/maven-client/pom.xml index 95e436c7a3..21e59a305c 100755 --- a/examples/client/maven-client/pom.xml +++ b/examples/client/maven-client/pom.xml @@ -10,8 +10,8 @@ 3.1.0 - 1.3.72 - 1.3.6 + 1.4.0 + 1.3.9 1.3.1 diff --git a/examples/client/server/build.gradle.kts b/examples/client/server/build.gradle.kts index 2542cea0a3..c84568d4a9 100644 --- a/examples/client/server/build.gradle.kts +++ b/examples/client/server/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("org.jetbrains.kotlin.jvm") version "1.3.72" - id("org.jetbrains.kotlin.plugin.spring") version "1.3.72" + id("org.jetbrains.kotlin.jvm") version "1.4.0" + id("org.jetbrains.kotlin.plugin.spring") version "1.4.0" id("org.springframework.boot") version "2.2.7.RELEASE" } diff --git a/gradle.properties b/gradle.properties index c2018c3e17..4eab5e7acc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,8 +15,8 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError # dependencies kotlinJvmVersion = 1.8 -kotlinVersion = 1.3.72 -kotlinCoroutinesVersion = 1.3.7 +kotlinVersion = 1.4.0 +kotlinCoroutinesVersion = 1.3.9 classGraphVersion = 4.8.87 graphQLJavaVersion = 15.0 diff --git a/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/extensions/kTypeExtensions.kt b/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/extensions/kTypeExtensions.kt index 5f24c9ef8a..9664fdbdbe 100644 --- a/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/extensions/kTypeExtensions.kt +++ b/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/extensions/kTypeExtensions.kt @@ -21,7 +21,6 @@ import kotlin.reflect.KClass import kotlin.reflect.KType import kotlin.reflect.full.createType import kotlin.reflect.full.isSubclassOf -import kotlin.reflect.jvm.javaType import kotlin.reflect.jvm.jvmErasure private val primitiveArrayTypes = mapOf( @@ -36,7 +35,7 @@ private val primitiveArrayTypes = mapOf( internal fun KType.getKClass() = this.jvmErasure -internal fun KType.getJavaClass() = this.javaType as Class<*> +internal fun KType.getJavaClass(): Class<*> = this.getKClass().java internal fun KType.isSubclassOf(kClass: KClass<*>) = this.getKClass().isSubclassOf(kClass) diff --git a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/directives/KotlinDirectiveWiringFactoryTest.kt b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/directives/KotlinDirectiveWiringFactoryTest.kt index a860703e3f..eab8a1c8a0 100644 --- a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/directives/KotlinDirectiveWiringFactoryTest.kt +++ b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/directives/KotlinDirectiveWiringFactoryTest.kt @@ -211,7 +211,7 @@ class KotlinDirectiveWiringFactoryTest { } @Test - fun `verify exception is thrown if no coordinates or code registry is specified for the field`() { + fun `verify exception is thrown if no coordinates are specified for the field`() { val myTestField = GraphQLFieldDefinition.newFieldDefinition() .name("MyField") .type { context, visitor -> context.thisNode().accept(context, visitor) } @@ -220,7 +220,21 @@ class KotlinDirectiveWiringFactoryTest { .build() assertFailsWith(InvalidSchemaDirectiveWiringException::class) { - SimpleWiringFactory().onWire(graphQLSchemaElement = myTestField, coordinates = null, codeRegistry = null) + SimpleWiringFactory().onWire(graphQLSchemaElement = myTestField, coordinates = null, codeRegistry = mockk()) + } + } + + @Test + fun `verify exception is thrown if no code registry is specified for the field`() { + val myTestField = GraphQLFieldDefinition.newFieldDefinition() + .name("MyField") + .type { context, visitor -> context.thisNode().accept(context, visitor) } + .description("My Field Description") + .withDirective(graphQLLowercaseDirective) + .build() + + assertFailsWith(InvalidSchemaDirectiveWiringException::class) { + SimpleWiringFactory().onWire(graphQLSchemaElement = myTestField, coordinates = mockk(), codeRegistry = null) } } diff --git a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/extensions/KTypeExtensionsKtTest.kt b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/extensions/KTypeExtensionsKtTest.kt index e0cf5aaa11..f70016e131 100644 --- a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/extensions/KTypeExtensionsKtTest.kt +++ b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/extensions/KTypeExtensionsKtTest.kt @@ -25,16 +25,18 @@ import org.junit.jupiter.api.condition.EnabledOnJre import org.junit.jupiter.api.condition.JRE import kotlin.reflect.KType import kotlin.reflect.KTypeProjection +import kotlin.reflect.full.createType import kotlin.reflect.full.findParameterByName import kotlin.reflect.full.starProjectedType import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertFalse +import kotlin.test.assertNotNull import kotlin.test.assertTrue -internal class KTypeExtensionsKtTest { +class KTypeExtensionsKtTest { - internal class MyClass { + class MyClass { fun listFun(list: List) = list.joinToString(separator = ",") { it } fun arrayFun(array: Array) = array.joinToString(separator = ",") { it } @@ -44,9 +46,9 @@ internal class KTypeExtensionsKtTest { fun stringFun(string: String) = "hello $string" } - internal interface SimpleInterface + interface SimpleInterface - internal class SimpleClass(val id: String) : SimpleInterface + class SimpleClass(val id: String) : SimpleInterface @Test fun getTypeOfFirstArgument() { @@ -77,7 +79,22 @@ internal class KTypeExtensionsKtTest { @Test fun getKClass() { - assertEquals(MyClass::class, MyClass::class.starProjectedType.getKClass()) + assertEquals(MyClass::class, MyClass::class.createType().getKClass()) + } + + @Test + fun getJavaClass() { + val listType = assertNotNull(MyClass::listFun.findParameterByName("list")?.type) + assertEquals(List::class.java, listType.getJavaClass()) + + val arrayType = assertNotNull(MyClass::arrayFun.findParameterByName("array")?.type) + assertEquals(Array::class.java, arrayType.getJavaClass()) + + val primitiveArrayType = assertNotNull(MyClass::primitiveArrayFun.findParameterByName("intArray")?.type) + assertEquals(IntArray::class.java, primitiveArrayType.getJavaClass()) + + val stringType = assertNotNull(MyClass::stringFun.findParameterByName("string")?.type) + assertEquals(String::class.java, stringType.getJavaClass()) } @Test diff --git a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GenerateDirectiveTest.kt b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GenerateDirectiveTest.kt index 224bb7b9c5..177e9dd817 100644 --- a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GenerateDirectiveTest.kt +++ b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GenerateDirectiveTest.kt @@ -26,6 +26,7 @@ import com.expediagroup.graphql.test.utils.SimpleDirective import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.Test import kotlin.reflect.KClass +import kotlin.reflect.KFunction import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -92,40 +93,47 @@ class GenerateDirectiveTest { @Test fun `no annotation`() { - assertTrue(generateDirectives(basicGenerator, MyClass::noAnnotation).isEmpty().isTrue()) + val noAnnotation: KFunction = MyClass::noAnnotation + assertTrue(generateDirectives(basicGenerator, noAnnotation).isEmpty().isTrue()) } @Test fun `no directive`() { - assertTrue(generateDirectives(basicGenerator, MyClass::noDirective).isEmpty().isTrue()) + val noDirective: KFunction = MyClass::noDirective + assertTrue(generateDirectives(basicGenerator, noDirective).isEmpty().isTrue()) } @Test fun `has directive`() { - assertEquals(expected = 1, actual = generateDirectives(basicGenerator, MyClass::simpleDirective).size) + val simpleDirective: KFunction = MyClass::simpleDirective + assertEquals(expected = 1, actual = generateDirectives(basicGenerator, simpleDirective).size) } @Test fun `has directive with string`() { - assertEquals(expected = 1, actual = generateDirectives(basicGenerator, MyClass::directiveWithString).size) + val directiveWithString: KFunction = MyClass::directiveWithString + assertEquals(expected = 1, actual = generateDirectives(basicGenerator, directiveWithString).size) } @Test fun `has directive with enum`() { - assertEquals(expected = 1, actual = generateDirectives(basicGenerator, MyClass::directiveWithEnum).size) + val directiveWithEnum: KFunction = MyClass::directiveWithEnum + assertEquals(expected = 1, actual = generateDirectives(basicGenerator, directiveWithEnum).size) } @Test fun `has directive with class`() { - assertEquals(expected = 1, actual = generateDirectives(basicGenerator, MyClass::directiveWithClass).size) + val directiveWithClass: KFunction = MyClass::directiveWithClass + assertEquals(expected = 1, actual = generateDirectives(basicGenerator, directiveWithClass).size) } @Test fun `directives are only added to the schema once`() { val initialCount = basicGenerator.directives.size - val firstInvocation = generateDirectives(basicGenerator, MyClass::simpleDirective) + val simpleDirective: KFunction = MyClass::simpleDirective + val firstInvocation = generateDirectives(basicGenerator, simpleDirective) assertEquals(1, firstInvocation.size) - val secondInvocation = generateDirectives(basicGenerator, MyClass::simpleDirective) + val secondInvocation = generateDirectives(basicGenerator, simpleDirective) assertEquals(1, secondInvocation.size) assertEquals(firstInvocation.first(), secondInvocation.first()) assertEquals(initialCount + 1, basicGenerator.directives.size) @@ -154,8 +162,10 @@ class GenerateDirectiveTest { @Test fun `directives are created per each declaration`() { val initialCount = basicGenerator.directives.size - val directivesOnFirstField = generateDirectives(basicGenerator, MyClass::directiveWithString) - val directivesOnSecondField = generateDirectives(basicGenerator, MyClass::directiveWithAnotherString) + val directiveWithString: KFunction = MyClass::directiveWithString + val directiveWithAnotherString: KFunction = MyClass::directiveWithAnotherString + val directivesOnFirstField = generateDirectives(basicGenerator, directiveWithString) + val directivesOnSecondField = generateDirectives(basicGenerator, directiveWithAnotherString) assertEquals(expected = 1, actual = directivesOnFirstField.size) assertEquals(expected = 1, actual = directivesOnSecondField.size) @@ -191,7 +201,8 @@ class GenerateDirectiveTest { @Test fun `exlude directive arguments @GraphQLIgnore`() { - val directives = generateDirectives(basicGenerator, MyClass::directiveWithIgnoredArgs) + val directiveWithIgnoredArgs: KFunction = MyClass::directiveWithIgnoredArgs + val directives = generateDirectives(basicGenerator, directiveWithIgnoredArgs) assertEquals(expected = 1, actual = directives.size) assertEquals(expected = 1, actual = directives.first().arguments.size) assertEquals(expected = "string", actual = directives.first().arguments.first().name) diff --git a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/FlowSubscriptionSchemaGeneratorHooksTest.kt b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/FlowSubscriptionSchemaGeneratorHooksTest.kt new file mode 100644 index 0000000000..9133f3b5e5 --- /dev/null +++ b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/FlowSubscriptionSchemaGeneratorHooksTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2020 Expedia, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.expediagroup.graphql.hooks + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import org.junit.jupiter.api.Test +import java.util.concurrent.CompletableFuture +import kotlin.reflect.full.createType +import kotlin.reflect.jvm.reflect +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class FlowSubscriptionSchemaGeneratorHooksTest { + + val hooks = FlowSubscriptionSchemaGeneratorHooks() + + @Test + fun `willResolveMonad unwraps Flow`() { + val type = assertNotNull(TestQuery::getFlow.reflect()?.returnType) + val result = hooks.willResolveMonad(type) + assertEquals(String::class.createType(), result) + } + + @Test + fun `willResolveMonad does nothing on any other type`() { + val stringType = assertNotNull(TestQuery::getString.reflect()?.returnType) + val cfType = assertNotNull(TestQuery::getCompletableFuture.reflect()?.returnType) + + assertEquals(stringType, hooks.willResolveMonad(stringType)) + assertEquals(cfType, hooks.willResolveMonad(cfType)) + } + + @Test + fun isValidSubscriptionReturnType() { + assertTrue(hooks.isValidSubscriptionReturnType(TestQuery::class, TestQuery::getFlow)) + assertFalse(hooks.isValidSubscriptionReturnType(TestQuery::class, TestQuery::getString)) + assertFalse(hooks.isValidSubscriptionReturnType(TestQuery::class, TestQuery::getCompletableFuture)) + } + + class TestQuery { + fun getFlow(): Flow = emptyFlow() + fun getString(): String = "" + fun getCompletableFuture(): CompletableFuture = CompletableFuture.completedFuture("") + } +} diff --git a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/SchemaGeneratorHooksTest.kt b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/SchemaGeneratorHooksTest.kt index 774bfbf96c..3bbef2ee93 100644 --- a/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/SchemaGeneratorHooksTest.kt +++ b/graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/hooks/SchemaGeneratorHooksTest.kt @@ -302,7 +302,7 @@ class SchemaGeneratorHooksTest { @Test fun `willResolveMonad returns basic type`() { val hooks = NoopSchemaGeneratorHooks - val type = TestQuery::query.returnType + val type = (TestQuery::query as KFunction<*>).returnType assertEquals(expected = "SomeData", actual = hooks.willResolveMonad(type).getSimpleName()) } diff --git a/plugins/graphql-kotlin-gradle-plugin/src/test/kotlin/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePluginAbstractIT.kt b/plugins/graphql-kotlin-gradle-plugin/src/test/kotlin/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePluginAbstractIT.kt index 4c717f8f18..81a184d348 100755 --- a/plugins/graphql-kotlin-gradle-plugin/src/test/kotlin/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePluginAbstractIT.kt +++ b/plugins/graphql-kotlin-gradle-plugin/src/test/kotlin/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePluginAbstractIT.kt @@ -34,8 +34,8 @@ abstract class GraphQLGradlePluginAbstractIT { // unsure if there is a better way - correct values are set from Gradle build // when running directly from IDE you will need to manually update those to correct values - private val gqlKotlinVersion = System.getProperty("graphQLKotlinVersion") ?: "3.0.0-SNAPSHOT" - private val kotlinVersion = System.getProperty("kotlinVersion") ?: "1.3.72" + private val gqlKotlinVersion = System.getProperty("graphQLKotlinVersion") ?: "4.0.0-SNAPSHOT" + private val kotlinVersion = System.getProperty("kotlinVersion") ?: "1.4.0" private val junitVersion = System.getProperty("junitVersion") ?: "5.6.2" val testSchema = loadResource("mocks/schema.graphql")