1 /* 2 * Copyright 2017-2019 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 kotlin.test.* 9 10 class SerialDescriptorAnnotationsTest { 11 12 @SerialInfo 13 @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) 14 annotation class CustomAnnotation(val value: String) 15 16 @Serializable 17 @SerialName("MyClass") 18 @CustomAnnotation("onClass") 19 data class WithNames( 20 val a: Int, 21 @CustomAnnotationWithDefault @CustomAnnotation("onProperty") val veryLongName: String 22 ) 23 24 @SerialInfo 25 @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) 26 annotation class CustomAnnotationWithDefault(val value: String = "default_annotation_value") 27 28 @SerialInfo 29 @Target(AnnotationTarget.PROPERTY) 30 public annotation class JShort(val order: SByteOrder = SByteOrder.BE, val mod: SByteMod = SByteMod.Add) 31 32 public enum class SByteOrder { 33 BE, LE 34 } 35 36 public enum class SByteMod { 37 None, Add 38 } 39 40 @Serializable 41 public class Foo( 42 @JShort(SByteOrder.LE, SByteMod.None) public val bar: Short, 43 @JShort public val baz: Short 44 ) 45 46 47 @Test testSerialNameOnClassnull48 fun testSerialNameOnClass() { 49 val desc = WithNames.serializer().descriptor 50 val name = desc.serialName 51 assertEquals("MyClass", name) 52 } 53 54 @Test testCustomSerialAnnotationOnPropertynull55 fun testCustomSerialAnnotationOnProperty() { 56 val desc: SerialDescriptor = WithNames.serializer().descriptor 57 val b = desc.getElementAnnotations(1).getCustom() 58 assertEquals("onProperty", b) 59 } 60 61 @Test testCustomSerialAnnotationOnClassnull62 fun testCustomSerialAnnotationOnClass() { 63 val desc: SerialDescriptor = WithNames.serializer().descriptor 64 val name = desc.annotations.getCustom() 65 assertEquals("onClass", name) 66 } 67 68 @Test testCustomAnnotationWithDefaultValuenull69 fun testCustomAnnotationWithDefaultValue() { 70 val value = 71 WithNames.serializer().descriptor 72 .getElementAnnotations(1).filterIsInstance<CustomAnnotationWithDefault>().single() 73 assertEquals("default_annotation_value", value.value) 74 } 75 76 @Test testAnnotationWithMultipleArgsnull77 fun testAnnotationWithMultipleArgs() { 78 fun SerialDescriptor.getValues(i: Int) = getElementAnnotations(i).filterIsInstance<JShort>().single().run { order to mod } 79 assertEquals(SByteOrder.LE to SByteMod.None, Foo.serializer().descriptor.getValues(0)) 80 assertEquals(SByteOrder.BE to SByteMod.Add, Foo.serializer().descriptor.getValues(1)) 81 } 82 Listnull83 private fun List<Annotation>.getCustom() = filterIsInstance<CustomAnnotation>().single().value 84 85 @Serializable 86 @CustomAnnotation("sealed") 87 sealed class Result { 88 @Serializable class OK(val s: String): Result() 89 } 90 91 @Serializable 92 @CustomAnnotation("abstract") 93 abstract class AbstractResult { 94 var result: String = "" 95 } 96 97 @Serializable 98 @CustomAnnotation("object") 99 object ObjectResult {} 100 101 @Serializable 102 class Holder(val r: Result, val a: AbstractResult, val o: ObjectResult, @Contextual val names: WithNames) 103 doTestnull104 private fun doTest(position: Int, expected: String) { 105 val desc = Holder.serializer().descriptor.getElementDescriptor(position) 106 assertEquals(expected, desc.annotations.getCustom()) 107 } 108 109 @Test testCustomAnnotationOnSealedClassnull110 fun testCustomAnnotationOnSealedClass() = doTest(0, "sealed") 111 112 @Test 113 fun testCustomAnnotationOnPolymorphicClass() = doTest(1, "abstract") 114 115 @Test 116 fun testCustomAnnotationOnObject() = doTest(2, "object") 117 118 @Test 119 fun testCustomAnnotationTransparentForContextual() = doTest(3, "onClass") 120 } 121