summaryrefslogtreecommitdiff
path: root/formats/json/jvmTest/src/kotlinx/serialization/features/JsonJvmStreamsTest.kt
blob: b576a2c1ba35fda3e67ae5abbc9d1516e9a40be7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.serialization.features

import kotlinx.serialization.SerializationException
import kotlinx.serialization.StringData
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.*
import kotlinx.serialization.json.internal.BATCH_SIZE
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)
            }
        }
    }

}