summaryrefslogtreecommitdiff
path: root/formats/json-tests/jsTest/src/kotlinx/serialization/json/DynamicToLongTest.kt
diff options
context:
space:
mode:
Diffstat (limited to 'formats/json-tests/jsTest/src/kotlinx/serialization/json/DynamicToLongTest.kt')
-rw-r--r--formats/json-tests/jsTest/src/kotlinx/serialization/json/DynamicToLongTest.kt60
1 files changed, 60 insertions, 0 deletions
diff --git a/formats/json-tests/jsTest/src/kotlinx/serialization/json/DynamicToLongTest.kt b/formats/json-tests/jsTest/src/kotlinx/serialization/json/DynamicToLongTest.kt
new file mode 100644
index 00000000..2daf0bb2
--- /dev/null
+++ b/formats/json-tests/jsTest/src/kotlinx/serialization/json/DynamicToLongTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.serialization.json
+
+import kotlinx.serialization.*
+import kotlin.test.*
+
+/**
+ * [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER]
+ */
+internal const val MAX_SAFE_INTEGER: Double = 9007199254740991.toDouble() // 2^53 - 1
+
+class DynamicToLongTest {
+
+ @Serializable
+ data class HasLong(val l: Long)
+
+ private fun test(dynamic: dynamic, expectedResult: Result<Long>) {
+ val parsed = kotlin.runCatching { Json.decodeFromDynamic(HasLong.serializer(), dynamic).l }
+ assertEquals(expectedResult.isSuccess, parsed.isSuccess, "Results are different")
+ parsed.onSuccess { assertEquals(expectedResult.getOrThrow(), it) }
+ // to compare without message
+ parsed.onFailure { assertSame(expectedResult.exceptionOrNull()!!::class, it::class) }
+ }
+
+ private fun shouldFail(dynamic: dynamic) = test(dynamic, Result.failure(SerializationException("")))
+
+ @Test
+ fun canParseNotSoBigLongs() {
+ test(js("{l:1}"), Result.success(1))
+ test(js("{l:0}"), Result.success(0))
+ test(js("{l:-1}"), Result.success(-1))
+ }
+
+ @Test
+ fun ignoresIncorrectValues() {
+ shouldFail(js("{l:0.5}"))
+ shouldFail(js("{l: Math.PI}"))
+ shouldFail(js("{l: NaN}"))
+ shouldFail(js("""{l: "a string"}"""))
+ shouldFail(js("{l:Infinity}"))
+ shouldFail(js("{l:+Infinity}"))
+ shouldFail(js("{l:-Infinity}"))
+ }
+
+ @Test
+ fun handlesEdgyValues() {
+ test(js("{l:Number.MAX_SAFE_INTEGER}"), Result.success(MAX_SAFE_INTEGER.toLong()))
+ test(js("{l:Number.MAX_SAFE_INTEGER - 1}"), Result.success(MAX_SAFE_INTEGER.toLong() - 1))
+ test(js("{l:-Number.MAX_SAFE_INTEGER}"), Result.success(-MAX_SAFE_INTEGER.toLong()))
+ shouldFail(js("{l: Number.MAX_SAFE_INTEGER + 1}"))
+ shouldFail(js("{l: Number.MAX_SAFE_INTEGER + 2}"))
+ shouldFail(js("{l: -Number.MAX_SAFE_INTEGER - 1}"))
+ shouldFail(js("{l: 2e100}"))
+ shouldFail(js("{l: 2e100 + 1}"))
+ test(js("{l: Math.pow(2, 53) - 1}"), Result.success(MAX_SAFE_INTEGER.toLong()))
+ }
+}