Skip to content

Commit b5b6a20

Browse files
committed
Add some compile tests
1 parent f64bdf3 commit b5b6a20

File tree

2 files changed

+140
-10
lines changed

2 files changed

+140
-10
lines changed

packages/plugin-compiler/src/main/kotlin/io/realm/kotlin/compiler/AccessorModifierIrGeneration.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import org.jetbrains.kotlin.ir.interpreter.getAnnotation
9393
import org.jetbrains.kotlin.ir.types.IrSimpleType
9494
import org.jetbrains.kotlin.ir.types.IrType
9595
import org.jetbrains.kotlin.ir.types.IrTypeArgument
96+
import org.jetbrains.kotlin.ir.types.classFqName
9697
import org.jetbrains.kotlin.ir.types.getClass
9798
import org.jetbrains.kotlin.ir.types.impl.IrAbstractSimpleType
9899
import org.jetbrains.kotlin.ir.types.isBoolean
@@ -752,7 +753,7 @@ class AccessorModifierIrGeneration(private val pluginContext: IrPluginContext) {
752753
// TODO extract the type from the annotation, by now hardcoded one
753754

754755
val schemaProperty =
755-
retrieveSchemaProperty(declaration, realmType.typeOrNull!!)
756+
retrieveSchemaProperty(declaration, realmType.typeOrNull!!.makeNotNull())
756757

757758
if(schemaProperty!= null) {
758759
fields[name] = schemaProperty!!
@@ -826,6 +827,11 @@ class AccessorModifierIrGeneration(private val pluginContext: IrPluginContext) {
826827

827828
private fun retrieveSchemaProperty(property: IrProperty, type: IrType): SchemaProperty? =
828829
when {
830+
// TODO should we allow these realm int subtypes?
831+
type.isChar() ||
832+
type.isByte() ||
833+
type.isShort() ||
834+
type.isInt() ||
829835
type.isLong() -> SchemaProperty(
830836
propertyType = PropertyType.RLM_PROPERTY_TYPE_INT,
831837
declaration = property,
@@ -873,7 +879,8 @@ class AccessorModifierIrGeneration(private val pluginContext: IrPluginContext) {
873879
declaration = property,
874880
collectionType = CollectionType.NONE
875881
)
876-
type.isObjectId() -> SchemaProperty(
882+
type.isObjectId() ||
883+
type.isRealmObjectId() -> SchemaProperty(
877884
propertyType = PropertyType.RLM_PROPERTY_TYPE_OBJECT_ID,
878885
declaration = property,
879886
collectionType = CollectionType.NONE
@@ -885,7 +892,7 @@ class AccessorModifierIrGeneration(private val pluginContext: IrPluginContext) {
885892
)
886893
else -> {
887894
logError(
888-
"Invalid type parameter, only Realm types are supported", // TODO find a better error message
895+
"Invalid type parameter '${type.classFqName}', only Realm types are supported", // TODO find a better error message
889896
property.locationOf()
890897
)
891898
null

packages/test-base/src/jvmTest/kotlin/io/realm/kotlin/test/compiler/TypeAdaptersTests.kt

Lines changed: 130 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import com.tschuchort.compiletesting.KotlinCompilation
2020
import com.tschuchort.compiletesting.SourceFile
2121
import io.realm.kotlin.internal.interop.CollectionType
2222
import io.realm.kotlin.test.util.Compiler.compileFromSource
23+
import io.realm.kotlin.test.util.TypeDescriptor
2324
import io.realm.kotlin.test.util.TypeDescriptor.allFieldTypes
2425
import io.realm.kotlin.types.MutableRealmInt
2526
import io.realm.kotlin.types.ObjectId
2627
import io.realm.kotlin.types.RealmAny
2728
import io.realm.kotlin.types.RealmInstant
29+
import io.realm.kotlin.types.RealmObject
2830
import io.realm.kotlin.types.RealmUUID
2931
import org.junit.Test
3032
import org.mongodb.kbson.BsonObjectId
@@ -33,13 +35,17 @@ import kotlin.reflect.KClassifier
3335
import kotlin.test.assertEquals
3436
import kotlin.test.assertTrue
3537

38+
/**
39+
* These tests should validate:
40+
* - [x] Adapter with a non-realm type should fail
41+
* - [x] Adapter annotation on unsupported types: delegate, function etc
42+
* - [ ] Adapters type supportness
43+
* - [ ] Instanced and singleton adapters
44+
*/
3645
class TypeAdaptersTests {
37-
// TODO: Add tests to validate type adapter definitions
38-
// TODO: Q. Shall we fail with declaring type adapters or when we apply them?
39-
40-
46+
// TODO: Can we make it fail when declaring type adapters rather than when we apply them?
4147
@Test
42-
fun nonRealmTypesThrow() {
48+
fun `adapters don't support R-types that are not Realm types`() {
4349
val result = compileFromSource(
4450
plugins = listOf(io.realm.kotlin.compiler.Registrar()),
4551
source = SourceFile.kotlin(
@@ -68,8 +74,125 @@ class TypeAdaptersTests {
6874
)
6975
)
7076
assertEquals(KotlinCompilation.ExitCode.COMPILATION_ERROR, result.exitCode, result.messages)
71-
assertTrue(result.messages.contains("Invalid type parameter, only Realm types are supported"), result.messages)
77+
assertTrue(
78+
result.messages.contains("Invalid type parameter 'NonRealmType', only Realm types are supported"),
79+
result.messages
80+
)
81+
}
82+
83+
@Test
84+
fun `applying adapter on backlinked property should fail`() {
85+
val result = compileFromSource(
86+
plugins = listOf(io.realm.kotlin.compiler.Registrar()),
87+
source = SourceFile.kotlin(
88+
"typeAdapter_on_backlinks_fail.kt",
89+
"""
90+
import io.realm.kotlin.ext.backlinks
91+
import io.realm.kotlin.types.RealmInstant
92+
import io.realm.kotlin.types.RealmObject
93+
import io.realm.kotlin.types.RealmTypeAdapter
94+
import io.realm.kotlin.types.annotations.TypeAdapter
95+
96+
class UserType
97+
98+
class TestObject1: RealmObject {
99+
var myObject: TestObject2 = TestObject2()
100+
}
101+
102+
class TestObject2 : RealmObject {
103+
@TypeAdapter(adapter = ValidRealmTypeAdapter::class)
104+
val userType by backlinks(TestObject1::myObject)
105+
}
106+
107+
object ValidRealmTypeAdapter : RealmTypeAdapter<String, UserType> {
108+
override fun fromRealm(realmValue: String): UserType = TODO()
109+
110+
override fun toRealm(value: UserType): String = TODO()
111+
}
112+
""".trimIndent()
113+
)
114+
)
115+
assertEquals(KotlinCompilation.ExitCode.COMPILATION_ERROR, result.exitCode, result.messages)
116+
assertTrue(
117+
result.messages.contains("Invalid type parameter, only Realm types are supported"),
118+
result.messages
119+
)
72120
}
73121

74-
// TODO: What happens if we apply the annotation to: Delegates backlinks
122+
@Test
123+
fun `type adapters supportness`() {
124+
val defaults = mapOf<KClassifier, Any>(
125+
Boolean::class to true,
126+
Byte::class to "1",
127+
Char::class to "\'c\'",
128+
Short::class to "1",
129+
Int::class to "1",
130+
Long::class to "1",
131+
Float::class to "1.4f",
132+
Double::class to "1.4",
133+
Decimal128::class to "BsonDecimal128(\"1.4E100\")",
134+
String::class to "\"Realm\"",
135+
RealmInstant::class to "RealmInstant.from(42, 420)",
136+
ObjectId::class to "ObjectId.create()",
137+
BsonObjectId::class to "BsonObjectId()",
138+
RealmUUID::class to "RealmUUID.random()",
139+
ByteArray::class to "byteArrayOf(42)",
140+
MutableRealmInt::class to "MutableRealmInt.create(42)"
141+
)
142+
143+
allFieldTypes
144+
.filter { type: TypeDescriptor.RealmFieldType ->
145+
// TODO at some point test collections
146+
type.collectionType == CollectionType.RLM_COLLECTION_TYPE_NONE
147+
}
148+
.filterNot { type ->
149+
// TODO tidy list unsupported types in TypeDescriptor
150+
type.elementType.classifier == MutableRealmInt::class ||
151+
type.elementType.classifier == RealmObject::class
152+
}
153+
.forEach { type ->
154+
val elementType = type.elementType
155+
val default = if (!elementType.nullable) defaults[elementType.classifier]
156+
?: error("unmapped default") else null
157+
158+
val kotlinLiteral = type.toKotlinLiteral()
159+
160+
val result = compileFromSource(
161+
plugins = listOf(io.realm.kotlin.compiler.Registrar()),
162+
source = SourceFile.kotlin(
163+
"typeadapter_supportness_$kotlinLiteral.kt",
164+
"""
165+
import io.realm.kotlin.types.RealmAny
166+
import io.realm.kotlin.types.RealmInstant
167+
import io.realm.kotlin.types.MutableRealmInt
168+
import io.realm.kotlin.types.RealmObject
169+
import io.realm.kotlin.types.RealmTypeAdapter
170+
import io.realm.kotlin.types.RealmUUID
171+
import io.realm.kotlin.types.annotations.TypeAdapter
172+
import io.realm.kotlin.types.ObjectId
173+
import org.mongodb.kbson.BsonDecimal128
174+
import org.mongodb.kbson.BsonObjectId
175+
176+
class UserType
177+
178+
class NonRealmType
179+
180+
class TestObject : RealmObject {
181+
@TypeAdapter(adapter = ValidRealmTypeAdapter::class)
182+
var userType: UserType = UserType()
183+
}
184+
185+
object ValidRealmTypeAdapter : RealmTypeAdapter<$kotlinLiteral, UserType> {
186+
override fun fromRealm(realmValue: $kotlinLiteral): UserType = TODO()
187+
188+
override fun toRealm(value: UserType): $kotlinLiteral = TODO()
189+
}
190+
""".trimIndent()
191+
)
192+
)
193+
assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode, result.messages)
194+
// assertTrue(result.messages.contains("Invalid type parameter, only Realm types are supported"), result.messages)
195+
}
196+
197+
}
75198
}

0 commit comments

Comments
 (0)