Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failing sealed class list encoding / decoding tests #365

Merged
merged 9 commits into from
May 24, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ import kotlinx.serialization.descriptors.StructureKind

actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor): CompositeDecoder = when(descriptor.kind) {
StructureKind.CLASS, StructureKind.OBJECT, PolymorphicKind.SEALED -> (value as Map<*, *>).let { map ->
FirebaseClassDecoder(map.size, { map.containsKey(it) }) { desc, index -> map[desc.getElementName(index)] }
FirebaseClassDecoder(map.size, { map.containsKey(it) }) { desc, index ->
val elementName = desc.getElementName(index)
if (desc.kind is PolymorphicKind && elementName == "value") {
map
} else {
map[desc.getElementName(index)]
}
}
}
StructureKind.LIST -> (value as List<*>).let {
FirebaseCompositeDecoder(it.size) { _, index -> it[index] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ sealed class TestSealed {
data class ChildClass(val map: Map<String, String>, val bool: Boolean = false): TestSealed()
}

@Serializable
data class TestSealedList(val list: List<TestSealed>)

class EncodersTest {
@Test
fun encodeMap() {
Expand Down Expand Up @@ -74,4 +77,62 @@ class EncodersTest {
val decoded = decode(TestSealed.serializer(), nativeMapOf("type" to "child", "map" to nativeMapOf("key" to "value"), "bool" to true))
assertEquals(TestSealed.ChildClass(mapOf("key" to "value"), true), decoded)
}

@Test
fun encodeSealedClassList() {
val toEncode = TestSealedList(
list = listOf(
TestSealed.ChildClass(
map = mapOf("key" to "value"),
bool = false
)
)
)
val encoded = encode<TestSealedList>(
TestSealedList.serializer(),
toEncode,
shouldEncodeElementDefault = true
)
val expected = nativeMapOf(
"list" to nativeListOf(
nativeMapOf(
"type" to "child",
"map" to nativeMapOf(
"key" to "value"
),
"bool" to false
)
)
)
nativeAssertEquals(expected, encoded)
}

@Test
fun decodeSealedClassList() {
val toDecode = nativeMapOf(
"list" to nativeListOf(
nativeMapOf(
"type" to "child",
"map" to nativeMapOf(
"key" to "value"
),
"bool" to false
)
)
)
val decoded = decode(
TestSealedList.serializer(),
toDecode
)
val expected = TestSealedList(
list = listOf(
TestSealed.ChildClass(
map = mapOf("key" to "value"),
bool = false
)
)
)

assertEquals(expected, decoded)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ import kotlinx.serialization.descriptors.StructureKind

actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor): CompositeDecoder = when(descriptor.kind) {
StructureKind.CLASS, StructureKind.OBJECT, PolymorphicKind.SEALED -> (value as Map<*, *>).let { map ->
FirebaseClassDecoder(map.size, { map.containsKey(it) }) { desc, index -> map[desc.getElementName(index)] }
FirebaseClassDecoder(map.size, { map.containsKey(it) }) { desc, index ->
val elementName = desc.getElementName(index)
if (desc.kind is PolymorphicKind && elementName == "value") {
map
} else {
map[desc.getElementName(index)]
}
}
}
StructureKind.LIST -> (value as List<*>).let {
FirebaseCompositeDecoder(it.size) { _, index -> it[index] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ import kotlin.js.Json
@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE")
actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor): CompositeDecoder = when(descriptor.kind) {
StructureKind.CLASS, StructureKind.OBJECT, PolymorphicKind.SEALED -> (value as Json).let { json ->
FirebaseClassDecoder(js("Object").keys(value).length as Int, { json[it] != undefined }) {
desc, index -> json[desc.getElementName(index)]
FirebaseClassDecoder(js("Object").keys(value).length as Int, { json[it] != undefined }) { desc, index ->
val elementName = desc.getElementName(index)
if (desc.kind is PolymorphicKind && elementName == "value") {
json
} else {
json[desc.getElementName(index)]
}
}
}
StructureKind.LIST -> (value as Array<*>).let {
Expand Down