• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.serialization.json
6 
7 import kotlinx.serialization.*
8 import kotlin.test.*
9 
10 /**
11  * [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER]
12  */
13 internal const val MAX_SAFE_INTEGER: Double = 9007199254740991.toDouble() // 2^53 - 1
14 
15 class DynamicToLongTest {
16 
17     @Serializable
18     data class HasLong(val l: Long)
19 
testnull20     private fun test(dynamic: dynamic, expectedResult: Result<Long>) {
21         val parsed = kotlin.runCatching { Json.decodeFromDynamic(HasLong.serializer(), dynamic).l }
22         assertEquals(expectedResult.isSuccess, parsed.isSuccess, "Results are different")
23         parsed.onSuccess { assertEquals(expectedResult.getOrThrow(), it) }
24         // to compare without message
25         parsed.onFailure { assertSame(expectedResult.exceptionOrNull()!!::class, it::class) }
26     }
27 
shouldFailnull28     private fun shouldFail(dynamic: dynamic) = test(dynamic,  Result.failure(SerializationException("")))
29 
30     @Test
31     fun canParseNotSoBigLongs() {
32         test(js("{l:1}"), Result.success(1))
33         test(js("{l:0}"), Result.success(0))
34         test(js("{l:-1}"), Result.success(-1))
35     }
36 
37     @Test
ignoresIncorrectValuesnull38     fun ignoresIncorrectValues() {
39         shouldFail(js("{l:0.5}"))
40         shouldFail(js("{l: Math.PI}"))
41         shouldFail(js("{l: NaN}"))
42         shouldFail(js("""{l: "a string"}"""))
43         shouldFail(js("{l:Infinity}"))
44         shouldFail(js("{l:+Infinity}"))
45         shouldFail(js("{l:-Infinity}"))
46     }
47 
48     @Test
handlesEdgyValuesnull49     fun handlesEdgyValues() {
50         test(js("{l:Number.MAX_SAFE_INTEGER}"), Result.success(MAX_SAFE_INTEGER.toLong()))
51         test(js("{l:Number.MAX_SAFE_INTEGER - 1}"), Result.success(MAX_SAFE_INTEGER.toLong() - 1))
52         test(js("{l:-Number.MAX_SAFE_INTEGER}"), Result.success(-MAX_SAFE_INTEGER.toLong()))
53         shouldFail(js("{l: Number.MAX_SAFE_INTEGER + 1}"))
54         shouldFail(js("{l: Number.MAX_SAFE_INTEGER + 2}"))
55         shouldFail(js("{l: -Number.MAX_SAFE_INTEGER - 1}"))
56         shouldFail(js("{l: 2e100}"))
57         shouldFail(js("{l: 2e100 + 1}"))
58         test(js("{l: Math.pow(2, 53) - 1}"), Result.success(MAX_SAFE_INTEGER.toLong()))
59     }
60 }
61