• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 @file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
6 
7 package kotlinx.serialization.features
8 
9 import kotlinx.serialization.*
10 import kotlinx.serialization.builtins.serializer
11 import kotlinx.serialization.json.*
12 import kotlinx.serialization.json.internal.BATCH_SIZE
13 import kotlinx.serialization.modules.*
14 import kotlinx.serialization.test.*
15 import org.junit.Test
16 import java.io.ByteArrayInputStream
17 import java.io.ByteArrayOutputStream
18 import kotlin.test.assertEquals
19 import kotlin.test.assertFailsWith
20 
21 class JsonJvmStreamsTest {
22     private val strLen = BATCH_SIZE * 2 + 42
23 
24     @Test
testParsesStringsLongerThanBuffernull25     fun testParsesStringsLongerThanBuffer() {
26         val str = "a".repeat(strLen)
27         val input = """{"data":"$str"}"""
28         assertEquals(input, Json.encodeViaStream(StringData.serializer(), StringData(str)))
29         assertEquals(str, Json.decodeViaStream(StringData.serializer(), input).data)
30         assertEquals(str, Json.decodeViaStream(String.serializer(), "\"$str\""))
31     }
32 
33     @Test
testSkipsWhitespacesLongerThanBuffernull34     fun testSkipsWhitespacesLongerThanBuffer() {
35         val str = "a".repeat(strLen)
36         val ws = " ".repeat(strLen)
37         val input = """{"data":$ws"$str"}"""
38         assertEquals("""{"data":"$str"}""", Json.encodeViaStream(StringData.serializer(), StringData(str)))
39         assertEquals(str, Json.decodeViaStream(StringData.serializer(), input).data)
40     }
41 
42     @Test
testHandlesEscapesLongerThanBuffernull43     fun testHandlesEscapesLongerThanBuffer() {
44         val str = "\\t".repeat(strLen)
45         val expected = "\t".repeat(strLen)
46         val input = """{"data":"$str"}"""
47         assertEquals(input, Json.encodeViaStream(StringData.serializer(), StringData(expected)))
48         assertEquals(expected, Json.decodeViaStream(StringData.serializer(), input).data)
49     }
50 
51     @Test
testHandlesLongLenientStringsnull52     fun testHandlesLongLenientStrings() {
53         val str = "a".repeat(strLen)
54         val input = """{"data":$str}"""
55         val json = Json { isLenient = true }
56         assertEquals(str, json.decodeViaStream(StringData.serializer(), input).data)
57         assertEquals(str, json.decodeViaStream(String.serializer(), str))
58     }
59 
60     @Test
testThrowsCorrectExceptionOnEofnull61     fun testThrowsCorrectExceptionOnEof() {
62         assertFailsWith<SerializationException> {
63             Json.decodeViaStream(StringData.serializer(), """{"data":""")
64         }
65         assertFailsWith<SerializationException> {
66             Json.decodeViaStream(StringData.serializer(), "")
67         }
68         assertFailsWith<SerializationException> {
69             Json.decodeViaStream(String.serializer(), "\"")
70         }
71     }
72 
73     @Test
testRandomEscapeSequencesnull74     fun testRandomEscapeSequences()  {
75         repeat(1000) {
76             val s = generateRandomUnicodeString(strLen)
77             try {
78                 val serializer = String.serializer()
79                 val b = ByteArrayOutputStream()
80                 Json.encodeToStream(serializer, s, b)
81                 val restored = Json.decodeFromStream(serializer, ByteArrayInputStream(b.toByteArray()))
82                 assertEquals(s, restored)
83             } catch (e: Throwable) {
84                 // Not assertion error to preserve cause
85                 throw IllegalStateException("Unexpectedly failed test, cause string: $s", e)
86             }
87         }
88     }
89 
90     interface Poly
91 
92     @Serializable
93     @SerialName("Impl")
94     data class Impl(val str: String) : Poly
95 
96     @Test
testPolymorphismWhenCrossingBatchSizeNonLeadingKeynull97     fun testPolymorphismWhenCrossingBatchSizeNonLeadingKey() {
98         val json = Json {
99             serializersModule = SerializersModule {
100                 polymorphic(Poly::class) {
101                     subclass(Impl::class, Impl.serializer())
102                 }
103             }
104         }
105 
106         val longString = "a".repeat(BATCH_SIZE - 5)
107         val string = """{"str":"$longString", "type":"Impl"}"""
108         val golden = Impl(longString)
109 
110         val deserialized = json.decodeViaStream(serializer<Poly>(), string)
111         assertEquals(golden, deserialized as Impl)
112     }
113 
114     @Test
testPolymorphismWhenCrossingBatchSizenull115     fun testPolymorphismWhenCrossingBatchSize() {
116         val json = Json {
117             serializersModule = SerializersModule {
118                 polymorphic(Poly::class) {
119                     subclass(Impl::class, Impl.serializer())
120                 }
121             }
122         }
123 
124         val aLotOfWhiteSpaces = " ".repeat(BATCH_SIZE - 5)
125         val string = """{$aLotOfWhiteSpaces"type":"Impl", "str":"value"}"""
126         val golden = Impl("value")
127 
128         val deserialized = json.decodeViaStream(serializer<Poly>(), string)
129         assertEquals(golden, deserialized as Impl)
130     }
131 }
132