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