summaryrefslogtreecommitdiff
path: root/runtime/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt')
-rw-r--r--runtime/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt136
1 files changed, 136 insertions, 0 deletions
diff --git a/runtime/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt b/runtime/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt
new file mode 100644
index 00000000..5cec49b4
--- /dev/null
+++ b/runtime/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2017-2019 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 kotlinx.serialization.json.internal.*
+import kotlinx.serialization.modules.*
+import kotlin.test.assertEquals
+
+abstract class JsonTestBase {
+ protected val strict = Json(JsonConfiguration.Default)
+ protected val unquoted = Json { unquoted = true }
+ protected val nonStrict = Json { strictMode = false }
+
+ @ImplicitReflectionSerializer
+ internal inline fun <reified T : Any> Json.stringify(value: T, useStreaming: Boolean): String {
+ val serializer = context.getContextualOrDefault(T::class)
+ return stringify(serializer, value, useStreaming)
+ }
+
+ internal fun <T> Json.stringify(serializer: SerializationStrategy<T>, value: T, useStreaming: Boolean): String {
+ return if (useStreaming) {
+ stringify(serializer, value)
+ } else {
+ val tree = writeJson(value, serializer)
+ // kotlinx.serialization/issues/277
+ stringify(JsonElementSerializer, tree)
+ }
+ }
+
+ @ImplicitReflectionSerializer
+ inline fun <reified T : Any> Json.stringify(list: List<T>, useStreaming: Boolean): String {
+ return if (useStreaming) {
+ // Overload to test public list extension
+ stringify(list)
+ } else {
+ stringify(context.getContextualOrDefault(T::class).list, list)
+ }
+ }
+
+ @ImplicitReflectionSerializer
+ inline fun <reified K : Any, reified V : Any> Json.stringify(map: Map<K, V>, useStreaming: Boolean): String {
+ return if (useStreaming) {
+ // Overload to test public map extension
+ stringify(map)
+ } else {
+ stringify((context.getContextualOrDefault(K::class) to context.getContextualOrDefault(V::class)).map, map)
+ }
+ }
+
+ @ImplicitReflectionSerializer
+ internal inline fun <reified T : Any> Json.parse(source: String, useStreaming: Boolean): T {
+ val deserializer = context.getContextualOrDefault(T::class)
+ return parse(deserializer, source, useStreaming)
+ }
+
+ internal fun <T> Json.parse(deserializer: DeserializationStrategy<T>, source: String, useStreaming: Boolean): T {
+ return if (useStreaming) {
+ parse(deserializer, source)
+ } else {
+ val parser = JsonReader(source)
+ val input = StreamingJsonInput(this, WriteMode.OBJ, parser)
+ val tree = input.decodeJson()
+ readJson(tree, deserializer)
+ }
+ }
+
+ @ImplicitReflectionSerializer
+ internal inline fun <reified T : Any> Json.parseList(content: String, useStreaming: Boolean): List<T> {
+ return if (useStreaming) {
+ // Overload to test public list extension
+ parseList(content)
+ } else {
+ parse(context.getContextualOrDefault(T::class).list, content, useStreaming)
+ }
+ }
+
+ @ImplicitReflectionSerializer
+ internal inline fun <reified K : Any, reified V : Any> Json.parseMap(
+ content: String,
+ useStreaming: Boolean
+ ): Map<K, V> {
+ return if (useStreaming) {
+ // Overload to test public map extension
+ parseMap(content)
+ } else {
+ parse((context.getContextualOrDefault(K::class) to context.getContextualOrDefault(V::class)).map, content, useStreaming)
+ }
+ }
+
+ protected fun parametrizedTest(test: (Boolean) -> Unit) {
+ val streamingResult = kotlin.runCatching { test(true) }
+ val treeResult = kotlin.runCatching { test(false) }
+ processResults(streamingResult, treeResult)
+ }
+
+ private inner class DualFormat(
+ val json: Json,
+ val useStreaming: Boolean,
+ override val context: SerialModule = EmptyModule
+ ) : StringFormat {
+ override fun <T> stringify(serializer: SerializationStrategy<T>, obj: T): String {
+ return json.stringify(serializer, obj, useStreaming)
+ }
+
+ override fun <T> parse(deserializer: DeserializationStrategy<T>, string: String): T {
+ return json.parse(deserializer, string, useStreaming)
+ }
+ }
+
+ protected fun parametrizedTest(json: Json, test: StringFormat.(StringFormat) -> Unit) {
+ val streamingResult = kotlin.runCatching { json.test(DualFormat(json, true)) }
+ val treeResult = kotlin.runCatching { json.test(DualFormat(json, false)) }
+ processResults(streamingResult, treeResult)
+ }
+
+ private fun processResults(streamingResult: Result<*>, treeResult: Result<*>) {
+ val results = listOf(streamingResult, treeResult)
+ results.forEachIndexed { index, result ->
+ if (result.isFailure)
+ throw Exception("Failed ${if (index == 0) "streaming" else "tree"} test", result.exceptionOrNull()!!)
+ }
+ assertEquals(streamingResult.getOrNull()!!, treeResult.getOrNull()!!)
+ }
+
+ internal fun <T: Any> parametrizedTest(serializer: KSerializer<T>, data: T, expected: String, json: Json = unquoted) {
+ parametrizedTest { useStreaming ->
+ val serialized = json.stringify(serializer, data, useStreaming)
+ assertEquals(expected, serialized)
+ val deserialized: T = json.parse(serializer, serialized, useStreaming)
+ assertEquals(data, deserialized)
+ }
+ }
+}