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
|
/*
* Copyright 2017-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.serialization
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.test.isJsLegacy
import kotlin.test.*
class SerialDescriptorAnnotationsTest {
@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class CustomAnnotation(val value: String)
@Serializable
@SerialName("MyClass")
@CustomAnnotation("onClass")
data class WithNames(
val a: Int,
@CustomAnnotationWithDefault @CustomAnnotation("onProperty") val veryLongName: String
)
@SerialInfo
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class CustomAnnotationWithDefault(val value: String = "default_annotation_value")
@SerialInfo
@Target(AnnotationTarget.PROPERTY)
public annotation class JShort(val order: SByteOrder = SByteOrder.BE, val mod: SByteMod = SByteMod.Add)
public enum class SByteOrder {
BE, LE
}
public enum class SByteMod {
None, Add
}
@Serializable
public class Foo(
@JShort(SByteOrder.LE, SByteMod.None) public val bar: Short,
@JShort public val baz: Short
)
@Test
fun testSerialNameOnClass() {
val desc = WithNames.serializer().descriptor
val name = desc.serialName
assertEquals("MyClass", name)
}
@Test
fun testCustomSerialAnnotationOnProperty() {
val desc: SerialDescriptor = WithNames.serializer().descriptor
val b = desc.getElementAnnotations(1).getCustom()
assertEquals("onProperty", b)
}
@Test
fun testCustomSerialAnnotationOnClass() {
val desc: SerialDescriptor = WithNames.serializer().descriptor
val name = desc.annotations.getCustom()
assertEquals("onClass", name)
}
@Test
fun testCustomAnnotationWithDefaultValue() {
val value =
WithNames.serializer().descriptor
.getElementAnnotations(1).filterIsInstance<CustomAnnotationWithDefault>().single()
assertEquals("default_annotation_value", value.value)
}
@Test
fun testAnnotationWithMultipleArgs() {
fun SerialDescriptor.getValues(i: Int) = getElementAnnotations(i).filterIsInstance<JShort>().single().run { order to mod }
assertEquals(SByteOrder.LE to SByteMod.None, Foo.serializer().descriptor.getValues(0))
assertEquals(SByteOrder.BE to SByteMod.Add, Foo.serializer().descriptor.getValues(1))
}
private fun List<Annotation>.getCustom() = filterIsInstance<CustomAnnotation>().single().value
@Serializable
@CustomAnnotation("sealed")
sealed class Result {
@Serializable class OK(val s: String): Result()
}
@Serializable
@CustomAnnotation("abstract")
abstract class AbstractResult {
var result: String = ""
}
@Serializable
@CustomAnnotation("object")
object ObjectResult {}
@Serializable
class Holder(val r: Result, val a: AbstractResult, val o: ObjectResult, @Contextual val names: WithNames)
private fun doTest(position: Int, expected: String) {
if (isJsLegacy()) return // Unsupported
val desc = Holder.serializer().descriptor.getElementDescriptor(position)
assertEquals(expected, desc.annotations.getCustom())
}
@Test
fun testCustomAnnotationOnSealedClass() = doTest(0, "sealed")
@Test
fun testCustomAnnotationOnPolymorphicClass() = doTest(1, "abstract")
@Test
fun testCustomAnnotationOnObject() = doTest(2, "object")
@Test
fun testCustomAnnotationTransparentForContextual() = doTest(3, "onClass")
}
|