Repository: graphql-java-kickstart/graphql-java-tools
Pull request #565 (2021-08-13 21:03:41)

Make compatible with other JVM Locales
capitalize() without Locale.ENGLISH leads to unexpected chars which are language specific

<!-- Uncomment one of the following lines as necessary. -->
<!-- Fixes #<ISSUE_NUMBER> -->
<!-- Resolves #<ISSUE_NUMBER> -->

## Checklist
<!-- Change [ ] to [x] to indicate you acknowledge the check. -->
- [x] Pull requests follows the [contribution guide](https://github.com/graphql-java-kickstart/graphql-java-tools/wiki/Contribution-guide)
- [x] New or modified functionality is covered by tests

## Description
<!-- Briefly describe how you resolved the issue or a bug. -->



Patch:
diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolverScanner.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolverScanner.kt
index f89d413..c961301 100644
--- a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolverScanner.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolverScanner.kt
@@ -86,11 +86,11 @@ internal class FieldResolverScanner(val options: SchemaParserOptions) {
         return methods.find {
             it.name == name && verifyMethodArguments(it, argumentCount, search)
         } ?: methods.find {
-            (isBoolean(field.type) && it.name == "is${name.capitalize()}") && verifyMethodArguments(it, argumentCount, search)
+            (isBoolean(field.type) && it.name == "is${name.replaceFirstChar(Char::titlecase)}") && verifyMethodArguments(it, argumentCount, search)
         } ?: methods.find {
-            it.name == "get${name.capitalize()}" && verifyMethodArguments(it, argumentCount, search)
+            it.name == "get${name.replaceFirstChar(Char::titlecase)}" && verifyMethodArguments(it, argumentCount, search)
         } ?: methods.find {
-            it.name == "getField${name.capitalize()}" && verifyMethodArguments(it, argumentCount, search)
+            it.name == "getField${name.replaceFirstChar(Char::titlecase)}" && verifyMethodArguments(it, argumentCount, search)
         } ?: methods.find {
             it.name == "get${name.snakeToCamelCase()}" && verifyMethodArguments(it, argumentCount, search)
         }
@@ -179,9 +179,9 @@ internal class FieldResolverScanner(val options: SchemaParserOptions) {
 
         signatures.add("${baseType.name}.${field.name}($argString)")
         if (isBoolean) {
-            signatures.add("${baseType.name}.is${field.name.capitalize()}($argString)")
+            signatures.add("${baseType.name}.is${field.name.replaceFirstChar(Char::titlecase)}($argString)")
         }
-        signatures.add("${baseType.name}.get${field.name.capitalize()}($argString)")
+        signatures.add("${baseType.name}.get${field.name.replaceFirstChar(Char::titlecase)}($argString)")
         if (scannedProperties) {
             signatures.add("${baseType.name}.${field.name}")
         }
diff --git a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt
index 55efc2c..eb72f88 100644
--- a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt
@@ -79,5 +79,5 @@ private fun isBooleanGetter(method: Method) = (method.name.startsWith("is")
     && (method.returnType == java.lang.Boolean::class.java)
     || method.returnType == Boolean::class.java)
 
-internal fun String.snakeToCamelCase(): String = split("_").joinToString(separator = "") { it.capitalize() }
+internal fun String.snakeToCamelCase(): String = split("_").joinToString(separator = "") { it.replaceFirstChar(Char::titlecase) }
 


Test patch:
diff --git a/src/test/kotlin/graphql/kickstart/tools/FieldResolverScannerTest.kt b/src/test/kotlin/graphql/kickstart/tools/FieldResolverScannerTest.kt
index 4646ddf..f092b3b 100644
--- a/src/test/kotlin/graphql/kickstart/tools/FieldResolverScannerTest.kt
+++ b/src/test/kotlin/graphql/kickstart/tools/FieldResolverScannerTest.kt
@@ -11,6 +11,7 @@ import graphql.relay.Connection
 import graphql.relay.DefaultConnection
 import graphql.relay.DefaultPageInfo
 import org.junit.Test
+import java.util.*
 
 class FieldResolverScannerTest {
 
@@ -81,6 +82,20 @@ class FieldResolverScannerTest {
         assertEquals((meta as MethodFieldResolver).method.returnType, HullType::class.java)
     }
 
+    @Test
+    fun `scanner finds field resolver method using capitalize field_name in different locale`() {
+        val default = Locale.getDefault()
+        Locale.setDefault(Locale.forLanguageTag("tr-TR"))
+
+        val resolverInfo = RootResolverInfo(listOf(CapitalizeQuery()), options)
+        val fieldResolver = scanner.findFieldResolver(FieldDefinition("id", TypeName("HullType")), resolverInfo)
+
+        assert(fieldResolver is MethodFieldResolver)
+        assertEquals((fieldResolver as MethodFieldResolver).method.returnType, HullType::class.java)
+
+        Locale.setDefault(default)
+    }
+
     class RootQuery1 : GraphQLQueryResolver {
         fun field1() {}
     }
@@ -97,6 +112,10 @@ class FieldResolverScannerTest {
         fun getHullType(): HullType = HullType()
     }
 
+    class CapitalizeQuery : GraphQLQueryResolver {
+        fun getId(): HullType = HullType()
+    }
+
     class HullType
 
     open class ParentPropertyQuery {