Skip to content

Commit

Permalink
Tests for serializable sealed interfaces (#1754)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandwwraith committed Jun 21, 2022
1 parent 6a5ebd5 commit bb18d62
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 5 deletions.
21 changes: 17 additions & 4 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

import java.util.*
import java.io.FileInputStream

Expand All @@ -7,12 +11,21 @@ plugins {

repositories {
mavenCentral()
mavenLocal()
}

val kotlinVersion = FileInputStream(file("../gradle.properties")).use { propFile ->
val ver = Properties().apply { load(propFile) }["kotlin.version"]
require(ver is String) { "kotlin.version must be string in ../gradle.properties, got $ver instead" }
ver
val kotlinVersion = run {
if (project.hasProperty("build_snapshot_train")) {
val ver = project.properties["kotlin_snapshot_version"] as? String
require(!ver.isNullOrBlank()) {"kotlin_snapshot_version must be present if build_snapshot_train is used" }
return@run ver
}
val targetProp = if (project.hasProperty("bootstrap")) "kotlin.version.snapshot" else "kotlin.version"
FileInputStream(file("../gradle.properties")).use { propFile ->
val ver = Properties().apply { load(propFile) }[targetProp]
require(ver is String) { "$targetProp must be string in ../gradle.properties, got $ver instead" }
ver
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

@file:Suppress("SERIALIZER_TYPE_INCOMPATIBLE")

package kotlinx.serialization.features

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.test.*
import kotlin.test.Test
import kotlin.test.assertEquals


class SealedInterfacesSerializationTest {
interface A

sealed interface B

@Serializable
sealed interface C

@Serializable(DummySerializer::class)
sealed interface D

@Serializable(DummySerializer::class)
interface E

@Serializable
@Polymorphic
sealed interface F

@Serializable
class ImplA : A, B, C, D, E, F

@Serializable
class ImplB : A, B, C, D, E, F

@Serializable
class Holder(
val a: A,
val b: B,
val c: C,
val d: D,
val e: E,
@Polymorphic val polyC: C,
val f: F
)

class DummySerializer : KSerializer<Any> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Dummy")

override fun serialize(encoder: Encoder, value: Any) {
error("serialize")
}

override fun deserialize(decoder: Decoder): Any {
error("deserialize")
}
}

private fun SerialDescriptor.haveSealedSubclasses() {
assertEquals(PolymorphicKind.SEALED, kind)
val subclasses = getElementDescriptor(1).elementDescriptors.map { it.serialName.substringAfterLast('.') }
assertEquals(listOf("ImplA", "ImplB"), subclasses)
}

private fun SerialDescriptor.isDummy() = serialName == "Dummy"

private fun SerialDescriptor.isPolymorphic() = kind == PolymorphicKind.OPEN

operator fun SerialDescriptor.get(i: Int) = getElementDescriptor(i)

@Test
fun testInHolder() {
val desc = Holder.serializer().descriptor
desc[0].isPolymorphic()
desc[1].isPolymorphic()
desc[2].haveSealedSubclasses()
desc[3].isDummy()
desc[4].isDummy()
desc[5].isPolymorphic()
desc[6].isPolymorphic()
}

@Test
fun testGenerated() {
C.serializer().descriptor.haveSealedSubclasses()
}

@Test
fun testResolved() = noJsLegacy {
serializer<C>().descriptor.haveSealedSubclasses()
}


}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.internal
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.features.sealed

import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.test.*
import kotlin.test.*

class SealedInterfacesJsonSerializationTest : JsonTestBase() {
@Serializable
sealed interface I

@Serializable
sealed class Response: I {
@Serializable
@SerialName("ResponseInt")
data class ResponseInt(val i: Int): Response()

@Serializable
@SerialName("ResponseString")
data class ResponseString(val s: String): Response()
}

@Serializable
@SerialName("NoResponse")
object NoResponse: I

@Test
fun testSealedInterfaceJson() = noLegacyJs {
val messages = listOf(Response.ResponseInt(10), NoResponse, Response.ResponseString("foo"))
assertJsonFormAndRestored(
serializer(),
messages,
"""[{"type":"ResponseInt","i":10},{"type":"NoResponse"},{"type":"ResponseString","s":"foo"}]"""
)
}
}

0 comments on commit bb18d62

Please sign in to comment.