[GH] Fix upper/lowercase locale issues
## Proposed Changes
- Get rid of all `toUpperCase()`, `toLowerCase()`, `capitalize()` and `decapitalize()` calls inside Room without a `Locale` to avoid localization issues (specifically with Turkish).
## Testing
Test: Added one test that verifies this fix (similar to the issue mentioned in the ticket, test fails without my changes)
## Issues Fixed
Fixes: 68159494
This is an imported pull request from https://github.com/androidx/androidx/pull/70.
Resolves #70
Github-Pr-Head-Sha: 937fcb76f264b10e7277025f74f4febebb899251
GitOrigin-RevId: 74697ccb895897266e374e40bfd5bd9bed370002
Change-Id: Ibea01d68d55be46db1a98655d69066409b463e99
diff --git a/room/compiler/src/main/kotlin/androidx/room/ext/string_ext.kt b/room/compiler/src/main/kotlin/androidx/room/ext/string_ext.kt
index a91bbd0..2d537f0 100644
--- a/room/compiler/src/main/kotlin/androidx/room/ext/string_ext.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/ext/string_ext.kt
@@ -1,3 +1,5 @@
+import java.util.Locale
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -17,7 +19,7 @@
private fun String.toCamelCase(): String {
val split = this.split("_")
if (split.isEmpty()) return ""
- if (split.size == 1) return split[0].capitalize()
+ if (split.size == 1) return split[0].capitalize(Locale.US)
return split.joinToCamelCase()
}
@@ -46,3 +48,17 @@
.map(String::trim)
.joinToCamelCaseAsVar()
}
+
+// TODO: Replace this with the function from the Kotlin stdlib once the API becomes stable
+fun String.capitalize(locale: Locale): String = if (isNotEmpty() && this[0].isLowerCase()) {
+ substring(0, 1).toUpperCase(locale) + substring(1)
+} else {
+ this
+}
+
+// TODO: Replace this with the function from the Kotlin stdlib once the API becomes stable
+fun String.decapitalize(locale: Locale): String = if (isNotEmpty() && this[0].isUpperCase()) {
+ substring(0, 1).toLowerCase(locale) + substring(1)
+} else {
+ this
+}
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
index 129aa5b..aed5aea 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/query/result/PojoRowAdapter.kt
@@ -32,8 +32,10 @@
import androidx.room.vo.Warning
import androidx.room.vo.findFieldByColumnName
import androidx.room.writer.FieldReadWriteWriter
+import capitalize
import com.squareup.javapoet.TypeName
import stripNonJava
+import java.util.Locale
/**
* Creates the entity from the given info.
@@ -117,7 +119,8 @@
override fun onCursorReady(cursorVarName: String, scope: CodeGenScope) {
mapping.fieldsWithIndices = mapping.matchedFields.map {
- val indexVar = scope.getTmpVar("_cursorIndexOf${it.name.stripNonJava().capitalize()}")
+ val indexVar = scope.getTmpVar(
+ "_cursorIndexOf${it.name.stripNonJava().capitalize(Locale.US)}")
val indexMethod = if (info == null) {
"getColumnIndex"
} else {
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/types/CustomTypeConverterWrapper.kt b/room/compiler/src/main/kotlin/androidx/room/solver/types/CustomTypeConverterWrapper.kt
index 90bef99..aa1e4e5 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/types/CustomTypeConverterWrapper.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/types/CustomTypeConverterWrapper.kt
@@ -24,6 +24,8 @@
import androidx.room.writer.ClassWriter
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.FieldSpec
+import decapitalize
+import java.util.Locale
import javax.lang.model.element.Modifier
/**
@@ -51,7 +53,7 @@
}
fun typeConverter(scope: CodeGenScope): FieldSpec {
- val baseName = (custom.typeName as ClassName).simpleName().decapitalize()
+ val baseName = (custom.typeName as ClassName).simpleName().decapitalize(Locale.US)
return scope.writer.getOrCreateField(object : ClassWriter.SharedFieldSpec(
baseName, custom.typeName) {
override fun getUniqueKey(): String {
diff --git a/room/compiler/src/main/kotlin/androidx/room/solver/types/PrimitiveColumnTypeAdapter.kt b/room/compiler/src/main/kotlin/androidx/room/solver/types/PrimitiveColumnTypeAdapter.kt
index 2dc78b2..22b6cf3 100644
--- a/room/compiler/src/main/kotlin/androidx/room/solver/types/PrimitiveColumnTypeAdapter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/solver/types/PrimitiveColumnTypeAdapter.kt
@@ -22,6 +22,7 @@
import androidx.room.compiler.processing.XProcessingEnv
import androidx.room.compiler.processing.XType
import androidx.room.solver.CodeGenScope
+import capitalize
import com.squareup.javapoet.TypeName.BYTE
import com.squareup.javapoet.TypeName.CHAR
import com.squareup.javapoet.TypeName.DOUBLE
@@ -29,6 +30,7 @@
import com.squareup.javapoet.TypeName.INT
import com.squareup.javapoet.TypeName.LONG
import com.squareup.javapoet.TypeName.SHORT
+import java.util.Locale
/**
* Adapters for all primitives that has direct cursor mappings.
@@ -39,7 +41,7 @@
val stmtSetter: String,
typeAffinity: SQLTypeAffinity
) : ColumnTypeAdapter(out, typeAffinity) {
- val cast = if (cursorGetter == "get${out.typeName.toString().capitalize()}")
+ val cast = if (cursorGetter == "get${out.typeName.toString().capitalize(Locale.US)}")
""
else
"(${out.typeName}) "
diff --git a/room/compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt b/room/compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt
index 4e07439..c1a7c33 100644
--- a/room/compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/verifier/jdbc_ext.kt
@@ -20,6 +20,7 @@
import java.sql.ResultSet
import java.sql.ResultSetMetaData
import java.sql.SQLException
+import java.util.Locale
internal fun <T> ResultSet.collect(f: (ResultSet) -> T): List<T> {
val result = arrayListOf<T>()
@@ -50,7 +51,7 @@
private fun PreparedStatement.tryGetAffinity(columnIndex: Int): SQLTypeAffinity {
return try {
- SQLTypeAffinity.valueOf(metaData.getColumnTypeName(columnIndex).capitalize())
+ SQLTypeAffinity.valueOf(metaData.getColumnTypeName(columnIndex).capitalize(Locale.US))
} catch (ex: IllegalArgumentException) {
SQLTypeAffinity.NULL
}
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt b/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt
index c5eca64..529bebd 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt
@@ -24,7 +24,10 @@
import androidx.room.compiler.processing.XVariableElement
import androidx.room.solver.types.CursorValueReader
import androidx.room.solver.types.StatementValueBinder
+import capitalize
import com.squareup.javapoet.TypeName
+import decapitalize
+import java.util.Locale
// used in cache matching, must stay as a data class or implement equals
data class Field(
@@ -93,15 +96,15 @@
result.add(name.substring(1))
}
if (name.startsWith("m") && name[1].isUpperCase()) {
- result.add(name.substring(1).decapitalize())
+ result.add(name.substring(1).decapitalize(Locale.US))
}
if (typeName == TypeName.BOOLEAN || typeName == TypeName.BOOLEAN.box()) {
if (name.length > 2 && name.startsWith("is") && name[2].isUpperCase()) {
- result.add(name.substring(2).decapitalize())
+ result.add(name.substring(2).decapitalize(Locale.US))
}
if (name.length > 3 && name.startsWith("has") && name[3].isUpperCase()) {
- result.add(name.substring(3).decapitalize())
+ result.add(name.substring(3).decapitalize(Locale.US))
}
}
}
@@ -109,10 +112,10 @@
}
val getterNameWithVariations by lazy {
- nameWithVariations.map { "get${it.capitalize()}" } +
+ nameWithVariations.map { "get${it.capitalize(Locale.US)}" } +
if (typeName == TypeName.BOOLEAN || typeName == TypeName.BOOLEAN.box()) {
nameWithVariations.flatMap {
- listOf("is${it.capitalize()}", "has${it.capitalize()}")
+ listOf("is${it.capitalize(Locale.US)}", "has${it.capitalize(Locale.US)}")
}
} else {
emptyList()
@@ -120,7 +123,7 @@
}
val setterNameWithVariations by lazy {
- nameWithVariations.map { "set${it.capitalize()}" }
+ nameWithVariations.map { "set${it.capitalize(Locale.US)}" }
}
/**
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/FtsOptions.kt b/room/compiler/src/main/kotlin/androidx/room/vo/FtsOptions.kt
index c886887..36819e6 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/FtsOptions.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/FtsOptions.kt
@@ -19,6 +19,7 @@
import androidx.room.FtsOptions.MatchInfo
import androidx.room.FtsOptions.Order
import androidx.room.migration.bundle.FtsOptionsBundle
+import java.util.Locale
data class FtsOptions(
val tokenizer: String,
@@ -62,7 +63,7 @@
}
if (matchInfo != MatchInfo.FTS4) {
- add("matchinfo=${matchInfo.name.toLowerCase()}")
+ add("matchinfo=${matchInfo.name.toLowerCase(Locale.US)}")
}
notIndexedColumns.forEach {
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/RelationCollector.kt b/room/compiler/src/main/kotlin/androidx/room/vo/RelationCollector.kt
index e90359c..f182418 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/RelationCollector.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/RelationCollector.kt
@@ -37,6 +37,7 @@
import androidx.room.verifier.DatabaseVerificationErrors
import androidx.room.writer.QueryWriter
import androidx.room.writer.RelationCollectorMethodWriter
+import capitalize
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.CodeBlock
import com.squareup.javapoet.ParameterizedTypeName
@@ -45,6 +46,7 @@
import java.nio.ByteBuffer
import java.util.ArrayList
import java.util.HashSet
+import java.util.Locale
/**
* Internal class that is used to manage fetching 1/N to N relationships.
@@ -66,7 +68,7 @@
fun writeInitCode(scope: CodeGenScope) {
varName = scope.getTmpVar(
- "_collection${relation.field.getPath().stripNonJava().capitalize()}")
+ "_collection${relation.field.getPath().stripNonJava().capitalize(Locale.US)}")
scope.builder().apply {
addStatement("final $T $L = new $T()", mapTypeName, varName, mapTypeName)
}
@@ -85,7 +87,7 @@
readKey(cursorVarName, indexVar, scope) { tmpVar ->
if (relationTypeIsCollection) {
val tmpCollectionVar = scope.getTmpVar(
- "_tmp${relation.field.name.stripNonJava().capitalize()}Collection")
+ "_tmp${relation.field.name.stripNonJava().capitalize(Locale.US)}Collection")
addStatement("$T $L = $L.get($L)", relationTypeName, tmpCollectionVar,
varName, tmpVar)
beginControlFlow("if ($L == null)", tmpCollectionVar).apply {
@@ -111,7 +113,7 @@
}?.indexVar
val tmpvarNameSuffix = if (relationTypeIsCollection) "Collection" else ""
val tmpRelationVar = scope.getTmpVar(
- "_tmp${relation.field.name.stripNonJava().capitalize()}$tmpvarNameSuffix")
+ "_tmp${relation.field.name.stripNonJava().capitalize(Locale.US)}$tmpvarNameSuffix")
scope.builder().apply {
addStatement("$T $L = null", relationTypeName, tmpRelationVar)
readKey(cursorVarName, indexVar, scope) { tmpVar ->
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/Warning.kt b/room/compiler/src/main/kotlin/androidx/room/vo/Warning.kt
index d63b495..82ca796 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Warning.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Warning.kt
@@ -16,6 +16,8 @@
package androidx.room.vo
+import java.util.Locale
+
/**
* Internal representation of supported warnings
*/
@@ -48,7 +50,7 @@
companion object {
val PUBLIC_KEY_MAP = values().associateBy { it.publicKey }
fun fromPublicKey(publicKey: String): Warning? {
- return PUBLIC_KEY_MAP[publicKey.toUpperCase()]
+ return PUBLIC_KEY_MAP[publicKey.toUpperCase(Locale.US)]
}
}
}
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
index 8f9be1c..d4d0af7 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/DaoWriter.kt
@@ -40,6 +40,7 @@
import androidx.room.vo.ShortcutMethod
import androidx.room.vo.TransactionMethod
import androidx.room.vo.WriteQueryMethod
+import capitalize
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.CodeBlock
import com.squareup.javapoet.FieldSpec
@@ -49,6 +50,7 @@
import com.squareup.javapoet.TypeName
import com.squareup.javapoet.TypeSpec
import stripNonJava
+import java.util.Locale
import javax.lang.model.element.Modifier.FINAL
import javax.lang.model.element.Modifier.PRIVATE
import javax.lang.model.element.Modifier.PUBLIC
@@ -508,7 +510,7 @@
}
class PreparedStatementField(val method: QueryMethod) : SharedFieldSpec(
- "preparedStmtOf${method.name.capitalize()}", RoomTypeNames.SHARED_SQLITE_STMT
+ "preparedStmtOf${method.name.capitalize(Locale.US)}", RoomTypeNames.SHARED_SQLITE_STMT
) {
override fun prepare(writer: ClassWriter, builder: FieldSpec.Builder) {
builder.addModifiers(PRIVATE, FINAL)
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/DatabaseWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/DatabaseWriter.kt
index 518575e..0ad8ad1 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/DatabaseWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/DatabaseWriter.kt
@@ -36,6 +36,7 @@
import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeName
import com.squareup.javapoet.TypeSpec
+import decapitalize
import stripNonJava
import java.util.Locale
import javax.lang.model.element.Modifier.FINAL
@@ -165,7 +166,7 @@
val scope = CodeGenScope(this)
builder.apply {
database.daoMethods.forEach { method ->
- val name = method.dao.typeName.simpleName().decapitalize().stripNonJava()
+ val name = method.dao.typeName.simpleName().decapitalize(Locale.US).stripNonJava()
val fieldName = scope.getTmpVar("_$name")
val field = FieldSpec.builder(method.dao.typeName, fieldName,
PRIVATE, VOLATILE).build()
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt
index 2d37196..9a3b80f 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/EntityCursorConverterWriter.kt
@@ -24,11 +24,13 @@
import androidx.room.solver.CodeGenScope
import androidx.room.vo.Entity
import androidx.room.vo.FieldWithIndex
+import capitalize
import com.squareup.javapoet.CodeBlock
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.ParameterSpec
import com.squareup.javapoet.TypeName
import stripNonJava
+import java.util.Locale
import javax.lang.model.element.Modifier.PRIVATE
class EntityCursorConverterWriter(val entity: Entity) : ClassWriter.SharedMethodSpec(
@@ -55,7 +57,7 @@
scope.builder().addStatement("final $T $L", entity.typeName, entityVar)
val fieldsWithIndices = entity.fields.map {
val indexVar = scope.getTmpVar(
- "_cursorIndexOf${it.name.stripNonJava().capitalize()}")
+ "_cursorIndexOf${it.name.stripNonJava().capitalize(Locale.US)}")
scope.builder().addStatement("final $T $L = $N.getColumnIndex($S)",
TypeName.INT, indexVar, cursorParam, it.columnName)
FieldWithIndex(field = it,
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/FieldReadWriteWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/FieldReadWriteWriter.kt
index aa4e649..8296746 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/FieldReadWriteWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/FieldReadWriteWriter.kt
@@ -27,7 +27,9 @@
import androidx.room.vo.FieldWithIndex
import androidx.room.vo.Pojo
import androidx.room.vo.RelationCollector
+import capitalize
import com.squareup.javapoet.TypeName
+import java.util.Locale
/**
* Handles writing a field into statement or reading it from statement.
@@ -73,7 +75,7 @@
rootNode.directFields = fieldsWithIndices.filter { it.field.parent == null }
val parentNodes = allParents.associate {
Pair(it, Node(
- varName = scope.getTmpVar("_tmp${it.field.name.capitalize()}"),
+ varName = scope.getTmpVar("_tmp${it.field.name.capitalize(Locale.US)}"),
fieldParent = it))
}
parentNodes.values.forEach { node ->
@@ -324,7 +326,8 @@
indexVar, scope)
}
CallType.METHOD -> {
- val tmpField = scope.getTmpVar("_tmp${field.name.capitalize()}")
+ val tmpField = scope.getTmpVar(
+ "_tmp${field.name.capitalize(Locale.US)}")
addStatement("final $T $L", field.setter.type.typeName, tmpField)
reader.readFromCursor(tmpField, cursorVar, indexVar, scope)
addStatement("$L.$L($L)", ownerVar, field.setter.name, tmpField)
@@ -356,7 +359,7 @@
typeName: TypeName,
scope: CodeGenScope
): String {
- val tmpField = scope.getTmpVar("_tmp${field.name.capitalize()}")
+ val tmpField = scope.getTmpVar("_tmp${field.name.capitalize(Locale.US)}")
scope.builder().apply {
addStatement("final $T $L", typeName, tmpField)
if (alwaysExists) {
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/FtsTableInfoValidationWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/FtsTableInfoValidationWriter.kt
index 2d5ffa9..e76424b 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/FtsTableInfoValidationWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/FtsTableInfoValidationWriter.kt
@@ -24,13 +24,15 @@
import androidx.room.ext.T
import androidx.room.ext.typeName
import androidx.room.vo.FtsEntity
+import capitalize
import com.squareup.javapoet.ParameterSpec
import com.squareup.javapoet.ParameterizedTypeName
import stripNonJava
+import java.util.Locale
class FtsTableInfoValidationWriter(val entity: FtsEntity) : ValidationWriter() {
override fun write(dbParam: ParameterSpec, scope: CountingCodeGenScope) {
- val suffix = entity.tableName.stripNonJava().capitalize()
+ val suffix = entity.tableName.stripNonJava().capitalize(Locale.US)
val expectedInfoVar = scope.getTmpVar("_info$suffix")
scope.builder().apply {
val columnListVar = scope.getTmpVar("_columns$suffix")
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/TableInfoValidationWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/TableInfoValidationWriter.kt
index 578dd43..69923a9 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/TableInfoValidationWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/TableInfoValidationWriter.kt
@@ -26,12 +26,14 @@
import androidx.room.parser.SQLTypeAffinity
import androidx.room.vo.Entity
import androidx.room.vo.columnNames
+import capitalize
import com.squareup.javapoet.ParameterSpec
import com.squareup.javapoet.ParameterizedTypeName
import stripNonJava
import java.util.Arrays
import java.util.HashMap
import java.util.HashSet
+import java.util.Locale
class TableInfoValidationWriter(val entity: Entity) : ValidationWriter() {
@@ -40,7 +42,7 @@
}
override fun write(dbParam: ParameterSpec, scope: CountingCodeGenScope) {
- val suffix = entity.tableName.stripNonJava().capitalize()
+ val suffix = entity.tableName.stripNonJava().capitalize(Locale.US)
val expectedInfoVar = scope.getTmpVar("_info$suffix")
scope.builder().apply {
val columnListVar = scope.getTmpVar("_columns$suffix")
diff --git a/room/compiler/src/main/kotlin/androidx/room/writer/ViewInfoValidationWriter.kt b/room/compiler/src/main/kotlin/androidx/room/writer/ViewInfoValidationWriter.kt
index 66c2892..16d68a5 100644
--- a/room/compiler/src/main/kotlin/androidx/room/writer/ViewInfoValidationWriter.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/writer/ViewInfoValidationWriter.kt
@@ -22,13 +22,15 @@
import androidx.room.ext.S
import androidx.room.ext.T
import androidx.room.vo.DatabaseView
+import capitalize
import com.squareup.javapoet.ParameterSpec
import stripNonJava
+import java.util.Locale
class ViewInfoValidationWriter(val view: DatabaseView) : ValidationWriter() {
override fun write(dbParam: ParameterSpec, scope: CountingCodeGenScope) {
- val suffix = view.viewName.stripNonJava().capitalize()
+ val suffix = view.viewName.stripNonJava().capitalize(Locale.US)
scope.builder().apply {
val expectedInfoVar = scope.getTmpVar("_info$suffix")
addStatement("final $T $L = new $T($S, $S)",
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt
index 25b6947..4c5939c 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt
@@ -38,6 +38,7 @@
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import simpleRun
+import java.util.Locale
@Suppress("HasPlatformType")
@RunWith(JUnit4::class)
@@ -181,7 +182,7 @@
fun primitiveArray() {
ALL_PRIMITIVES.forEach { primitive ->
singleEntity("@TypeConverters(foo.bar.MyConverter.class) " +
- "${primitive.toString().toLowerCase()}[] arr;") { field, invocation ->
+ "${primitive.toString().toLowerCase(Locale.US)}[] arr;") { field, invocation ->
assertThat(field, `is`(
Field(name = "arr",
type = invocation.processingEnv.getArrayType(primitive),
diff --git a/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt b/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt
index 4370c29..0397a3f 100644
--- a/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/writer/DaoWriterTest.kt
@@ -28,6 +28,7 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import java.util.Locale
import javax.tools.JavaFileObject
@RunWith(JUnit4::class)
@@ -44,6 +45,17 @@
}
@Test
+ fun complexDao_turkishLocale() {
+ val originalLocale = Locale.getDefault()
+ try {
+ Locale.setDefault(Locale("tr")) // Turkish has special upper/lowercase i chars
+ complexDao()
+ } finally {
+ Locale.setDefault(originalLocale)
+ }
+ }
+
+ @Test
fun writerDao() {
singleDao(
loadJavaCode("daoWriter/input/WriterDao.java", "foo.bar.WriterDao")