• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package kotlinx.serialization
2 
3 import kotlinx.serialization.builtins.ListSerializer
4 import kotlinx.serialization.builtins.MapSerializer
5 import kotlinx.serialization.descriptors.PrimitiveKind
6 import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
7 import kotlinx.serialization.encoding.Decoder
8 import kotlinx.serialization.encoding.Encoder
9 import kotlinx.serialization.json.*
10 import org.junit.Test
11 import java.math.BigDecimal
12 
13 private typealias BigDecimalKxs = @Serializable(with = BigDecimalNumericSerializer::class) BigDecimal
14 
15 class BigDecimalTest : JsonTestBase() {
16 
<lambda>null17     private val json = Json {
18         prettyPrint = true
19     }
20 
assertBigDecimalJsonFormAndRestorednull21     private inline fun <reified T> assertBigDecimalJsonFormAndRestored(
22         expected: String,
23         actual: T,
24         serializer: KSerializer<T> = serializer(),
25     ) = assertJsonFormAndRestored(
26         serializer,
27         actual,
28         expected,
29         json
30     )
31 
32     @Test
33     fun bigDecimal() {
34         fun test(expected: String, actual: BigDecimal) =
35             assertBigDecimalJsonFormAndRestored(expected, actual, BigDecimalNumericSerializer)
36 
37         test("0", BigDecimal.ZERO)
38         test("1", BigDecimal.ONE)
39         test("-1", BigDecimal("-1"))
40         test("10", BigDecimal.TEN)
41         test(bdExpected1, bdActual1)
42         test(bdExpected2, bdActual2)
43         test(bdExpected3, bdActual3)
44         test(bdExpected4, bdActual4)
45         test(bdExpected5, bdActual5)
46         test(bdExpected6, bdActual6)
47     }
48 
49     @Test
bigDecimalListnull50     fun bigDecimalList() {
51 
52         val bdList: List<BigDecimal> = listOf(
53             bdActual1,
54             bdActual2,
55             bdActual3,
56             bdActual4,
57             bdActual5,
58             bdActual6,
59         )
60 
61         val expected =
62             """
63                 [
64                     $bdExpected1,
65                     $bdExpected2,
66                     $bdExpected3,
67                     $bdExpected4,
68                     $bdExpected5,
69                     $bdExpected6
70                 ]
71             """.trimIndent()
72 
73         assertJsonFormAndRestored(
74             ListSerializer(BigDecimalNumericSerializer),
75             bdList,
76             expected,
77             json,
78         )
79     }
80 
81     @Test
bigDecimalMapnull82     fun bigDecimalMap() {
83         val bdMap: Map<BigDecimal, BigDecimal> = mapOf(
84             bdActual1 to bdActual2,
85             bdActual3 to bdActual4,
86             bdActual5 to bdActual6,
87         )
88 
89         val expected =
90             """
91                 {
92                     "$bdExpected1": $bdExpected2,
93                     "$bdExpected3": $bdExpected4,
94                     "$bdExpected5": $bdExpected6
95                 }
96             """.trimIndent()
97 
98         assertJsonFormAndRestored(
99             MapSerializer(BigDecimalNumericSerializer, BigDecimalNumericSerializer),
100             bdMap,
101             expected,
102             json,
103         )
104     }
105 
106     @Test
bigDecimalHoldernull107     fun bigDecimalHolder() {
108         val bdHolder = BigDecimalHolder(
109             bd = bdActual1,
110             bdList = listOf(
111                 bdActual1,
112                 bdActual2,
113                 bdActual3,
114             ),
115             bdMap = mapOf(
116                 bdActual1 to bdActual2,
117                 bdActual3 to bdActual4,
118                 bdActual5 to bdActual6,
119             ),
120         )
121 
122         val expected =
123             """
124                 {
125                     "bd": $bdExpected1,
126                     "bdList": [
127                         $bdExpected1,
128                         $bdExpected2,
129                         $bdExpected3
130                     ],
131                     "bdMap": {
132                         "$bdExpected1": $bdExpected2,
133                         "$bdExpected3": $bdExpected4,
134                         "$bdExpected5": $bdExpected6
135                     }
136                 }
137             """.trimIndent()
138 
139         assertBigDecimalJsonFormAndRestored(
140             expected,
141             bdHolder,
142         )
143     }
144 
145     companion object {
146 
147         // test data
148         private val bdActual1 = BigDecimal("725345854747326287606413621318.311864440287151714280387858224")
149         private val bdActual2 = BigDecimal("336052472523017262165484244513.836582112201211216526831524328")
150         private val bdActual3 = BigDecimal("211054843014778386028147282517.011200287614476453868782405400")
151         private val bdActual4 = BigDecimal("364751025728628060231208776573.207325218263752602211531367642")
152         private val bdActual5 = BigDecimal("508257556021513833656664177125.824502734715222686411316853148")
153         private val bdActual6 = BigDecimal("127134584027580606401102614002.366672301517071543257300444000")
154 
155         private const val bdExpected1 = "725345854747326287606413621318.311864440287151714280387858224"
156         private const val bdExpected2 = "336052472523017262165484244513.836582112201211216526831524328"
157         private const val bdExpected3 = "211054843014778386028147282517.011200287614476453868782405400"
158         private const val bdExpected4 = "364751025728628060231208776573.207325218263752602211531367642"
159         private const val bdExpected5 = "508257556021513833656664177125.824502734715222686411316853148"
160         private const val bdExpected6 = "127134584027580606401102614002.366672301517071543257300444000"
161     }
162 
163 }
164 
165 @Serializable
166 private data class BigDecimalHolder(
167     val bd: BigDecimalKxs,
168     val bdList: List<BigDecimalKxs>,
169     val bdMap: Map<BigDecimalKxs, BigDecimalKxs>,
170 )
171 
172 private object BigDecimalNumericSerializer : KSerializer<BigDecimal> {
173 
174     override val descriptor = PrimitiveSerialDescriptor("java.math.BigDecimal", PrimitiveKind.DOUBLE)
175 
deserializenull176     override fun deserialize(decoder: Decoder): BigDecimal {
177         return if (decoder is JsonDecoder) {
178             BigDecimal(decoder.decodeJsonElement().jsonPrimitive.content)
179         } else {
180             BigDecimal(decoder.decodeString())
181         }
182     }
183 
serializenull184     override fun serialize(encoder: Encoder, value: BigDecimal) {
185         val bdString = value.toPlainString()
186 
187         if (encoder is JsonEncoder) {
188             encoder.encodeJsonElement(JsonUnquotedLiteral(bdString))
189         } else {
190             encoder.encodeString(bdString)
191         }
192     }
193 }
194