summaryrefslogtreecommitdiff
path: root/core/commonTest/src/kotlinx/serialization/SerializersModuleTest.kt
blob: 9e255f27566e86aa180a4d8c2bd0696fdde21e7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.serialization

import kotlinx.serialization.builtins.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.modules.*
import kotlinx.serialization.test.*
import kotlin.reflect.*
import kotlin.test.*

class SerializersModuleTest {
    @Serializable
    object Object

    @Serializable
    sealed class SealedParent {
        @Serializable
        data class Child(val i: Int) : SealedParent()
    }

    @Serializable
    abstract class Abstract

    @Serializable
    enum class SerializableEnum { A, B }

    @Serializable(CustomSerializer::class)
    class WithCustomSerializer(val i: Int)

    @Serializer(forClass = WithCustomSerializer::class)
    object CustomSerializer

    @Serializable
    class Parametrized<T : Any>(val a: T)

    @Serializable
    class ParametrizedOfNullable<T>(val a: T)

    class ContextualType(val i: Int)

    @Serializer(forClass = ContextualType::class)
    object ContextualSerializer

    @Serializable
    class ContextualHolder(@Contextual val contextual: ContextualType)

    @Test
    fun testCompiled() {
        assertSame<KSerializer<*>>(Object.serializer(), serializer(Object::class, emptyList(), false))
        assertSame<KSerializer<*>>(SealedParent.serializer(), serializer(SealedParent::class, emptyList(), false))
        assertSame<KSerializer<*>>(
            SealedParent.Child.serializer(),
            serializer(SealedParent.Child::class, emptyList(), false)
        )

        assertSame<KSerializer<*>>(Abstract.serializer(), serializer(Abstract::class, emptyList(), false))
        assertSame<KSerializer<*>>(SerializableEnum.serializer(), serializer(SerializableEnum::class, emptyList(), false))
    }

    @Test
    fun testBuiltIn() {
        assertSame<KSerializer<*>>(Int.serializer(), serializer(Int::class, emptyList(), false))
    }

    @Test
    fun testCustom() {
        val m = SerializersModule { }
        assertSame<KSerializer<*>>(CustomSerializer, m.serializer(WithCustomSerializer::class, emptyList(), false))
    }

    @Test
    fun testParametrized() {
        val serializer = serializer(Parametrized::class, listOf(Int.serializer()), false)
        assertEquals<KClass<*>>(Parametrized.serializer(Int.serializer())::class, serializer::class)
        assertEquals(PrimitiveKind.INT, serializer.descriptor.getElementDescriptor(0).kind)

        val mapSerializer = serializer(Map::class, listOf(String.serializer(), Int.serializer()), false)
        assertIs<MapLikeSerializer<*, *, *, *>>(mapSerializer)
        assertEquals(PrimitiveKind.STRING, mapSerializer.descriptor.getElementDescriptor(0).kind)
        assertEquals(PrimitiveKind.INT, mapSerializer.descriptor.getElementDescriptor(1).kind)
    }

    @Suppress("UNCHECKED_CAST")
    @Test
    fun testNothingAndParameterizedOfNothing() {
        assertEquals(NothingSerializer, Nothing::class.serializer())
        //assertEquals(NothingSerializer, serializer<Nothing>()) // prohibited by compiler
        assertEquals(NothingSerializer, serializer(Nothing::class, emptyList(), false) as KSerializer<Nothing>)
        //assertEquals(NullableSerializer(NothingSerializer), serializer<Nothing?>()) // prohibited by compiler
        assertEquals(
            NullableSerializer(NothingSerializer),
            serializer(Nothing::class, emptyList(), true) as KSerializer<Nothing?>
        )

        val parameterizedNothingSerializer = serializer<Parametrized<Nothing>>()
        val nothingDescriptor = parameterizedNothingSerializer.descriptor.getElementDescriptor(0)
        assertEquals(NothingSerialDescriptor, nothingDescriptor)

        val parameterizedNullableNothingSerializer = serializer<ParametrizedOfNullable<Nothing?>>()
        val nullableNothingDescriptor = parameterizedNullableNothingSerializer.descriptor.getElementDescriptor(0)
        assertEquals(SerialDescriptorForNullable(NothingSerialDescriptor), nullableNothingDescriptor)
    }

    @Test
    fun testUnsupportedArray() {
        assertFails {
            serializer(Array::class, listOf(Int.serializer()), false)
        }
    }

    @Suppress("UNCHECKED_CAST")
    @Test
    fun testContextual() {
        val m = SerializersModule {
            contextual<ContextualType>(ContextualSerializer)
            contextual(ContextualGenericsTest.ThirdPartyBox::class) { args -> ContextualGenericsTest.ThirdPartyBoxSerializer(args[0]) }
        }

        val contextualSerializer = m.serializer(ContextualType::class, emptyList(), false)
        assertSame<KSerializer<*>>(ContextualSerializer, contextualSerializer)

        val boxSerializer = m.serializer(ContextualGenericsTest.ThirdPartyBox::class, listOf(Int.serializer()), false)
        assertIs<ContextualGenericsTest.ThirdPartyBoxSerializer<Int>>(boxSerializer)
        assertEquals(PrimitiveKind.INT, boxSerializer.descriptor.getElementDescriptor(0).kind)

        val holderSerializer = m.serializer(ContextualHolder::class, emptyList(), false)
        assertSame<KSerializer<*>>(ContextualHolder.serializer(), holderSerializer)
    }

}