summaryrefslogtreecommitdiff
path: root/formats/json-tests/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt
diff options
context:
space:
mode:
Diffstat (limited to 'formats/json-tests/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt')
-rw-r--r--formats/json-tests/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt131
1 files changed, 131 insertions, 0 deletions
diff --git a/formats/json-tests/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt b/formats/json-tests/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt
new file mode 100644
index 00000000..7019edae
--- /dev/null
+++ b/formats/json-tests/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
+
+package kotlinx.serialization.features
+
+import kotlinx.serialization.*
+import kotlinx.serialization.builtins.serializer
+import kotlinx.serialization.json.*
+import kotlinx.serialization.json.internal.BATCH_SIZE
+import kotlinx.serialization.modules.*
+import kotlinx.serialization.test.*
+import org.junit.Test
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class JsonJvmStreamsTest {
+ private val strLen = BATCH_SIZE * 2 + 42
+
+ @Test
+ fun testParsesStringsLongerThanBuffer() {
+ val str = "a".repeat(strLen)
+ val input = """{"data":"$str"}"""
+ assertEquals(input, Json.encodeViaStream(StringData.serializer(), StringData(str)))
+ assertEquals(str, Json.decodeViaStream(StringData.serializer(), input).data)
+ assertEquals(str, Json.decodeViaStream(String.serializer(), "\"$str\""))
+ }
+
+ @Test
+ fun testSkipsWhitespacesLongerThanBuffer() {
+ val str = "a".repeat(strLen)
+ val ws = " ".repeat(strLen)
+ val input = """{"data":$ws"$str"}"""
+ assertEquals("""{"data":"$str"}""", Json.encodeViaStream(StringData.serializer(), StringData(str)))
+ assertEquals(str, Json.decodeViaStream(StringData.serializer(), input).data)
+ }
+
+ @Test
+ fun testHandlesEscapesLongerThanBuffer() {
+ val str = "\\t".repeat(strLen)
+ val expected = "\t".repeat(strLen)
+ val input = """{"data":"$str"}"""
+ assertEquals(input, Json.encodeViaStream(StringData.serializer(), StringData(expected)))
+ assertEquals(expected, Json.decodeViaStream(StringData.serializer(), input).data)
+ }
+
+ @Test
+ fun testHandlesLongLenientStrings() {
+ val str = "a".repeat(strLen)
+ val input = """{"data":$str}"""
+ val json = Json { isLenient = true }
+ assertEquals(str, json.decodeViaStream(StringData.serializer(), input).data)
+ assertEquals(str, json.decodeViaStream(String.serializer(), str))
+ }
+
+ @Test
+ fun testThrowsCorrectExceptionOnEof() {
+ assertFailsWith<SerializationException> {
+ Json.decodeViaStream(StringData.serializer(), """{"data":""")
+ }
+ assertFailsWith<SerializationException> {
+ Json.decodeViaStream(StringData.serializer(), "")
+ }
+ assertFailsWith<SerializationException> {
+ Json.decodeViaStream(String.serializer(), "\"")
+ }
+ }
+
+ @Test
+ fun testRandomEscapeSequences() {
+ repeat(1000) {
+ val s = generateRandomUnicodeString(strLen)
+ try {
+ val serializer = String.serializer()
+ val b = ByteArrayOutputStream()
+ Json.encodeToStream(serializer, s, b)
+ val restored = Json.decodeFromStream(serializer, ByteArrayInputStream(b.toByteArray()))
+ assertEquals(s, restored)
+ } catch (e: Throwable) {
+ // Not assertion error to preserve cause
+ throw IllegalStateException("Unexpectedly failed test, cause string: $s", e)
+ }
+ }
+ }
+
+ interface Poly
+
+ @Serializable
+ @SerialName("Impl")
+ data class Impl(val str: String) : Poly
+
+ @Test
+ fun testPolymorphismWhenCrossingBatchSizeNonLeadingKey() {
+ val json = Json {
+ serializersModule = SerializersModule {
+ polymorphic(Poly::class) {
+ subclass(Impl::class, Impl.serializer())
+ }
+ }
+ }
+
+ val longString = "a".repeat(BATCH_SIZE - 5)
+ val string = """{"str":"$longString", "type":"Impl"}"""
+ val golden = Impl(longString)
+
+ val deserialized = json.decodeViaStream(serializer<Poly>(), string)
+ assertEquals(golden, deserialized as Impl)
+ }
+
+ @Test
+ fun testPolymorphismWhenCrossingBatchSize() {
+ val json = Json {
+ serializersModule = SerializersModule {
+ polymorphic(Poly::class) {
+ subclass(Impl::class, Impl.serializer())
+ }
+ }
+ }
+
+ val aLotOfWhiteSpaces = " ".repeat(BATCH_SIZE - 5)
+ val string = """{$aLotOfWhiteSpaces"type":"Impl", "str":"value"}"""
+ val golden = Impl("value")
+
+ val deserialized = json.decodeViaStream(serializer<Poly>(), string)
+ assertEquals(golden, deserialized as Impl)
+ }
+}