1 @file:Suppress("MayBeConstant")
2 
3 package kotlinx.serialization.features
4 
5 import kotlinx.serialization.*
6 import kotlinx.serialization.json.Json
7 import kotlin.test.Test
8 import kotlin.test.assertEquals
9 
10 internal val globalVar: Int = 4
11 
globalFunnull12 internal fun globalFun(): Int {
13     return 7
14 }
15 
16 internal const val PROPERTY_INITIALIZER_JSON = """{
17     "valProperty": 1,
18     "varProperty": 2,
19     "literalConst": 3,
20     "globalVarRef": 4,
21     "computed": 5,
22     "doubleRef": 6,
23     "globalFun": 7,
24     "globalFunExpr": 8,
25     "itExpr": 9,
26     "transientRefFromProp": 10,
27     "bodyProp": 11,
28     "dependBodyProp": 12,
29     "getterDepend": 13
30 }"""
31 
32 @Suppress("MemberVisibilityCanBePrivate", "unused", "ComplexRedundantLet")
33 class PropertyInitializerTest {
34     @Serializable
35     data class InternalClass(
36         val valProperty: Int,
37         var varProperty: Int,
38         val literalConst: Int = 3,
39         val globalVarRef: Int = globalVar,
40         val computed: Int = valProperty + varProperty + 2,
41         val doubleRef: Int = literalConst + literalConst,
42         var globalFun: Int = globalFun(),
43         var globalFunExpr: Int = globalFun() + 1,
<lambda>null44         val itExpr: Int = literalConst.let { it + 6 },
45         @Transient val constTransient: Int = 6,
46         @Transient val serializedRefTransient: Int = varProperty + 1,
47         @Transient val refTransient: Int = serializedRefTransient,
48         val transientRefFromProp: Int = constTransient + 4,
49     ) {
50         val valGetter: Int get() { return 5 }
51         var bodyProp: Int = 11
52         var dependBodyProp: Int = bodyProp + 1
53         var getterDepend: Int = valGetter + 8
54     }
55 
<lambda>null56     private val format = Json { encodeDefaults = true; prettyPrint = true }
57 
58     data class ExternalClass(
59         val valProperty: Int,
60         var varProperty: Int,
61         val literalConst: Int = 3,
62         val globalVarRef: Int = globalVar,
63         val computed: Int = valProperty + varProperty + 2,
64         val doubleRef: Int = literalConst + literalConst,
65         var globalFun: Int = globalFun(),
66         var globalFunExpr: Int = globalFun() + 1,
<lambda>null67         val itExpr: Int = literalConst.let { it + 6 },
68         @Transient val constTransient: Int = 6,
69         @Transient val serializedRefTransient: Int = varProperty + 1,
70         @Transient val refTransient: Int = serializedRefTransient,
71         val transientRefFromProp: Int = constTransient + 4,
72     ) {
73         val valGetter: Int get() { return 5 }
74         var bodyProp: Int = 11
75         var dependBodyProp: Int = bodyProp + 1
76         var getterDepend: Int = valGetter + 8
77     }
78 
79     @Serializer(ExternalClass::class)
80     object ExternalSerializer
81 
82     @Test
testInternalSerializeDefaultnull83     fun testInternalSerializeDefault() {
84         val encoded = format.encodeToString(InternalClass(1, 2))
85         assertEquals(PROPERTY_INITIALIZER_JSON, encoded)
86     }
87 
88     @Test
testInternalDeserializeDefaultnull89     fun testInternalDeserializeDefault() {
90         val decoded = format.decodeFromString<InternalClass>("""{"valProperty": 5, "varProperty": 6}""")
91         assertEquals(InternalClass(5, 6), decoded)
92     }
93 
94     @Test
testExternalSerializeDefaultnull95     fun testExternalSerializeDefault() {
96         val encoded = format.encodeToString(ExternalSerializer, ExternalClass(1, 2))
97         assertEquals(PROPERTY_INITIALIZER_JSON, encoded)
98     }
99 
100     @Test
testExternalDeserializeDefaultnull101     fun testExternalDeserializeDefault() {
102         val decoded = format.decodeFromString(ExternalSerializer,"""{"valProperty": 5, "varProperty": 6}""")
103         assertEquals(ExternalClass(5, 6), decoded)
104     }
105 }
106