1 /* 2 * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.serialization 6 7 import kotlinx.serialization.descriptors.* 8 import kotlinx.serialization.encoding.* 9 import kotlinx.serialization.json.JsonTestBase 10 import kotlinx.serialization.test.* 11 import kotlin.test.* 12 13 class EnumSerializationTest : JsonTestBase() { 14 15 @Serializable 16 enum class RegularEnum { 17 VALUE 18 } 19 20 @Serializable 21 data class Regular(val a: RegularEnum) 22 23 @Serializable 24 data class RegularNullable(val a: RegularEnum?) 25 26 @Serializable 27 @SerialName("custom_enum") 28 private enum class CustomEnum { 29 @SerialName("foo_a") 30 FooA, 31 32 @SerialName("foo_b") 33 @Id(10) 34 FooB 35 } 36 37 @Serializable 38 private data class WithCustomEnum(val c: CustomEnum) 39 40 @Serializable(CustomEnumSerializer::class) 41 private enum class WithCustom { 42 @SerialName("1") 43 ONE, 44 @SerialName("2") 45 TWO 46 } 47 48 private class CustomEnumSerializer : KSerializer<WithCustom> { <lambda>null49 override val descriptor: SerialDescriptor = buildSerialDescriptor("WithCustom", SerialKind.ENUM) { 50 element("1", buildSerialDescriptor("WithCustom.1", StructureKind.OBJECT)) 51 element("2", buildSerialDescriptor("WithCustom.2", StructureKind.OBJECT)) 52 } 53 serializenull54 override fun serialize(encoder: Encoder, value: WithCustom) { 55 encoder.encodeInt(value.ordinal + 1) 56 } 57 deserializenull58 override fun deserialize(decoder: Decoder): WithCustom { 59 return WithCustom.values()[decoder.decodeInt() - 1] 60 } 61 } 62 63 @Serializable 64 private data class CustomInside(val inside: WithCustom) 65 66 @Test testEnumSerializationnull67 fun testEnumSerialization() = 68 assertJsonFormAndRestored( 69 WithCustomEnum.serializer(), 70 WithCustomEnum(CustomEnum.FooB), 71 """{"c":"foo_b"}""", 72 default 73 ) 74 75 @Test 76 fun testEnumWithCustomSerializers() = 77 assertJsonFormAndRestored( 78 CustomInside.serializer(), 79 CustomInside(WithCustom.TWO), """{"inside":2}""" 80 ) 81 82 83 @Test 84 fun testHasMeaningfulToString() { 85 val regular = Regular.serializer().descriptor.toString() 86 assertEquals( 87 "kotlinx.serialization.EnumSerializationTest.Regular(a: kotlinx.serialization.EnumSerializationTest.RegularEnum)", 88 regular 89 ) 90 val regularNullable = RegularNullable.serializer().descriptor.toString() 91 assertEquals( 92 "kotlinx.serialization.EnumSerializationTest.RegularNullable(a: kotlinx.serialization.EnumSerializationTest.RegularEnum?)", 93 regularNullable 94 ) 95 // slightly differs from previous one 96 val regularNullableJoined = RegularNullable.serializer().descriptor.elementDescriptors.joinToString() 97 assertEquals("kotlinx.serialization.EnumSerializationTest.RegularEnum(VALUE)?", regularNullableJoined) 98 99 val regularEnum = RegularEnum.serializer().descriptor.toString() 100 assertEquals("kotlinx.serialization.EnumSerializationTest.RegularEnum(VALUE)", regularEnum) 101 } 102 103 104 @Test testHasMeaningfulHashCodenull105 fun testHasMeaningfulHashCode() { 106 val a = Regular.serializer().descriptor.hashCode() 107 val b = RegularNullable.serializer().descriptor.hashCode() 108 val c = RegularEnum.serializer().descriptor.hashCode() 109 assertTrue(setOf(a, b, c).size == 3, ".hashCode must give different result for different descriptors") 110 } 111 112 enum class MyEnum { 113 A, B, C; 114 } 115 116 @Serializable 117 @SerialName("kotlinx.serialization.EnumSerializationTest.MyEnum") 118 enum class MyEnum2 { 119 A, B, C; 120 } 121 122 @Serializable 123 class Wrapper(val a: MyEnum) 124 125 @Test testStructurallyEqualDescriptorsnull126 fun testStructurallyEqualDescriptors() { 127 val libraryGenerated = Wrapper.serializer().descriptor.getElementDescriptor(0) 128 val codeGenerated = MyEnum2.serializer().descriptor 129 assertEquals(libraryGenerated::class, codeGenerated::class) 130 libraryGenerated.assertDescriptorEqualsTo(codeGenerated) 131 } 132 } 133