blob: 150a7a3296584f19410c44c72c2b624b85aa4ebf [file] [log] [blame]
/*
* Copyright 2021 The Android Open Source Project
*
* 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
*
* http://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 androidx.room.solver
import androidx.room.compiler.codegen.CodeLanguage
import androidx.room.compiler.processing.util.Source
import androidx.room.compiler.processing.util.runProcessorTest
import androidx.room.processor.CustomConverterProcessor
import androidx.room.solver.types.CompositeTypeConverter
import androidx.room.solver.types.CustomTypeConverterWrapper
import androidx.room.solver.types.TypeConverter
import androidx.room.testing.context
import androidx.room.vo.BuiltInConverterFlags
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class TypeConverterStoreTest {
@Test
fun multiStepTypeConverters() {
val source = Source.kotlin(
"Foo.kt",
"""
import androidx.room.*
interface Type1_Super
interface Type1 : Type1_Super
interface Type1_Sub : Type1
interface Type2_Super
interface Type2 : Type2_Super
interface Type2_Sub : Type2
interface JumpType_1
interface JumpType_2
interface JumpType_3
class MyConverters {
@TypeConverter
fun t1_jump1(inp : Type1): JumpType_1 = TODO()
@TypeConverter
fun jump1_t2_Sub(inp : JumpType_1): Type2_Sub = TODO()
@TypeConverter
fun jump1_t2(inp : JumpType_1): Type2 = TODO()
@TypeConverter
fun t1_super_jump2(inp : Type1_Super): JumpType_2 = TODO()
@TypeConverter
fun jump2_jump3(inp : JumpType_2): JumpType_3 = TODO()
@TypeConverter
fun jump2_Type2_Sub(inp : JumpType_3): Type2_Sub = TODO()
}
""".trimIndent()
)
runProcessorTest(sources = listOf(source)) { invocation ->
val convertersElm = invocation.processingEnv.requireTypeElement("MyConverters")
val converters = CustomConverterProcessor(invocation.context, convertersElm)
.process()
val store = TypeAdapterStore.create(
invocation.context,
BuiltInConverterFlags.DEFAULT,
converters.map(::CustomTypeConverterWrapper)
).typeConverterStore
fun findConverter(from: String, to: String): String? {
val input = invocation.processingEnv.requireType(from)
val output = invocation.processingEnv.requireType(to)
return store.findTypeConverter(
input = input,
output = output
)?.also {
// validate that it makes sense to ensure test is correct
assertThat(output.isAssignableFrom(it.to)).isTrue()
assertThat(it.from.isAssignableFrom(input)).isTrue()
}?.toSignature()
}
assertThat(
findConverter("Type1", "Type2")
).isEqualTo(
"Type1 -> JumpType_1 : JumpType_1 -> Type2"
)
assertThat(
findConverter("Type1", "Type2_Sub")
).isEqualTo(
"Type1 -> JumpType_1 : JumpType_1 -> Type2_Sub"
)
assertThat(
findConverter("Type1_Super", "Type2_Super")
).isEqualTo(
"Type1_Super -> JumpType_2 : JumpType_2 -> JumpType_3 : JumpType_3 -> Type2_Sub"
.let { tillSub ->
if (invocation.context.useNullAwareConverter) {
// new type converter will have a step for upcasts too
"$tillSub : Type2_Sub -> Type2_Super"
} else {
tillSub
}
}
)
assertThat(
findConverter("Type1", "Type2_Sub")
).isEqualTo(
"Type1 -> JumpType_1 : JumpType_1 -> Type2_Sub"
)
assertThat(
findConverter("Type1_Sub", "Type2_Sub")
).isEqualTo(
"Type1 -> JumpType_1 : JumpType_1 -> Type2_Sub".let { end ->
if (invocation.context.useNullAwareConverter) {
// new type converter will have a step for upcasts too
"Type1_Sub -> Type1 : $end"
} else {
end
}
}
)
assertThat(
findConverter("Type2", "Type2_Sub")
).isNull()
assertThat(
findConverter("Type2", "Type1")
).isNull()
}
}
private fun TypeConverter.toSignature(): String {
return when (this) {
is CompositeTypeConverter -> "${conv1.toSignature()} : ${conv2.toSignature()}"
else -> from.asTypeName().toString(CodeLanguage.JAVA) + " -> " +
to.asTypeName().toString(CodeLanguage.JAVA)
}
}
}