SubwayTooter-Android-App/app/src/test/java/jp/juggler/subwaytooter/TestJson.kt

188 lines
8.6 KiB
Kotlin

package jp.juggler.subwaytooter
import jp.juggler.util.data.buildJsonArray
import jp.juggler.util.data.buildJsonObject
import jp.juggler.util.data.decodeJsonObject
import jp.juggler.util.data.decodeJsonValue
import jp.juggler.util.data.isDecimalNotation
import jp.juggler.util.data.jsonObjectOf
import jp.juggler.util.data.writeJsonValue
import java.io.StringWriter
import kotlin.test.Test
import kotlin.test.assertEquals
class TestJson {
companion object {
private val epsilon = java.lang.Double.longBitsToDouble(971L shl 52)
fun Any?.encodeSimpleJsonValue(indentFactor: Int): String {
val sw = StringWriter()
synchronized(sw.buffer) {
return sw.writeJsonValue(indentFactor, 0, this, sort = true).toString()
}
}
}
@Suppress("unused")
enum class En {
Aa,
Bb,
Cc
}
@Test
fun encode1() {
assertEquals("null", null.encodeSimpleJsonValue(0))
assertEquals("true", true.encodeSimpleJsonValue(0))
assertEquals("false", false.encodeSimpleJsonValue(0))
assertEquals("0", 0.encodeSimpleJsonValue(0))
assertEquals("1", 1.encodeSimpleJsonValue(0))
assertEquals("-1", (-1).encodeSimpleJsonValue(0))
assertEquals("-2147483648", Int.MIN_VALUE.encodeSimpleJsonValue(0))
assertEquals("2147483647", Int.MAX_VALUE.encodeSimpleJsonValue(0))
assertEquals("0", 0L.encodeSimpleJsonValue(0))
assertEquals("1", 1L.encodeSimpleJsonValue(0))
assertEquals("-1", (-1L).encodeSimpleJsonValue(0))
assertEquals("-9223372036854775808", Long.MIN_VALUE.encodeSimpleJsonValue(0))
assertEquals("9223372036854775807", Long.MAX_VALUE.encodeSimpleJsonValue(0))
assertEquals("0", 0f.encodeSimpleJsonValue(0))
assertEquals("1", 1f.encodeSimpleJsonValue(0))
assertEquals("-1", (-1f).encodeSimpleJsonValue(0))
assertEquals("1.4E-45", Float.MIN_VALUE.encodeSimpleJsonValue(0))
assertEquals("3.4028235E38", Float.MAX_VALUE.encodeSimpleJsonValue(0))
assertEquals("0", 0.0.encodeSimpleJsonValue(0))
assertEquals("1", 1.0.encodeSimpleJsonValue(0))
assertEquals("-1", (-1.0).encodeSimpleJsonValue(0))
assertEquals("4.9E-324", Double.MIN_VALUE.encodeSimpleJsonValue(0))
assertEquals("1.7976931348623157E308", Double.MAX_VALUE.encodeSimpleJsonValue(0))
assertEquals("0", 0.toChar().encodeSimpleJsonValue(0))
assertEquals("1", 1.toChar().encodeSimpleJsonValue(0))
assertEquals("65535", (-1).toChar().encodeSimpleJsonValue(0))
assertEquals("0", Char.MIN_VALUE.encodeSimpleJsonValue(0))
assertEquals("65535", Char.MAX_VALUE.encodeSimpleJsonValue(0))
// 空文字列
assertEquals("\"\"", "".encodeSimpleJsonValue(0))
val escaped = ArrayList<String>()
// Unicode1文字(エスケープのテスト
for (i in 0 until 0x10000) {
val c = i.toChar()
val raw = c.toString()
val encoded = raw.encodeSimpleJsonValue(0)
val decoded = encoded.decodeJsonValue()
assertEquals(raw, decoded)
if (encoded.length > 3) escaped.add(encoded.substring(1, encoded.length - 1))
}
@Suppress("MaxLineLength")
assertEquals(
"""\",\\,\b,\f,\n,\r,\t,\u0000,\u0001,\u0002,\u0003,\u0004,\u0005,\u0006,\u0007,\u000b,\u000e,\u000f,\u0010,\u0011,\u0012,\u0013,\u0014,\u0015,\u0016,\u0017,\u0018,\u0019,\u001a,\u001b,\u001c,\u001d,\u001e,\u001f,\u0080,\u0081,\u0082,\u0083,\u0084,\u0085,\u0086,\u0087,\u0088,\u0089,\u008a,\u008b,\u008c,\u008d,\u008e,\u008f,\u0090,\u0091,\u0092,\u0093,\u0094,\u0095,\u0096,\u0097,\u0098,\u0099,\u009a,\u009b,\u009c,\u009d,\u009e,\u009f,\u2000,\u2001,\u2002,\u2003,\u2004,\u2005,\u2006,\u2007,\u2008,\u2009,\u200a,\u200b,\u200c,\u200d,\u200e,\u200f,\u2010,\u2011,\u2012,\u2013,\u2014,\u2015,\u2016,\u2017,\u2018,\u2019,\u201a,\u201b,\u201c,\u201d,\u201e,\u201f,\u2020,\u2021,\u2022,\u2023,\u2024,\u2025,\u2026,\u2027,\u2028,\u2029,\u202a,\u202b,\u202c,\u202d,\u202e,\u202f,\u2030,\u2031,\u2032,\u2033,\u2034,\u2035,\u2036,\u2037,\u2038,\u2039,\u203a,\u203b,\u203c,\u203d,\u203e,\u203f,\u2040,\u2041,\u2042,\u2043,\u2044,\u2045,\u2046,\u2047,\u2048,\u2049,\u204a,\u204b,\u204c,\u204d,\u204e,\u204f,\u2050,\u2051,\u2052,\u2053,\u2054,\u2055,\u2056,\u2057,\u2058,\u2059,\u205a,\u205b,\u205c,\u205d,\u205e,\u205f,\u2060,\u2061,\u2062,\u2063,\u2064,\u2065,\u2066,\u2067,\u2068,\u2069,\u206a,\u206b,\u206c,\u206d,\u206e,\u206f,\u2070,\u2071,\u2072,\u2073,\u2074,\u2075,\u2076,\u2077,\u2078,\u2079,\u207a,\u207b,\u207c,\u207d,\u207e,\u207f,\u2080,\u2081,\u2082,\u2083,\u2084,\u2085,\u2086,\u2087,\u2088,\u2089,\u208a,\u208b,\u208c,\u208d,\u208e,\u208f,\u2090,\u2091,\u2092,\u2093,\u2094,\u2095,\u2096,\u2097,\u2098,\u2099,\u209a,\u209b,\u209c,\u209d,\u209e,\u209f,\u20a0,\u20a1,\u20a2,\u20a3,\u20a4,\u20a5,\u20a6,\u20a7,\u20a8,\u20a9,\u20aa,\u20ab,\u20ac,\u20ad,\u20ae,\u20af,\u20b0,\u20b1,\u20b2,\u20b3,\u20b4,\u20b5,\u20b6,\u20b7,\u20b8,\u20b9,\u20ba,\u20bb,\u20bc,\u20bd,\u20be,\u20bf,\u20c0,\u20c1,\u20c2,\u20c3,\u20c4,\u20c5,\u20c6,\u20c7,\u20c8,\u20c9,\u20ca,\u20cb,\u20cc,\u20cd,\u20ce,\u20cf,\u20d0,\u20d1,\u20d2,\u20d3,\u20d4,\u20d5,\u20d6,\u20d7,\u20d8,\u20d9,\u20da,\u20db,\u20dc,\u20dd,\u20de,\u20df,\u20e0,\u20e1,\u20e2,\u20e3,\u20e4,\u20e5,\u20e6,\u20e7,\u20e8,\u20e9,\u20ea,\u20eb,\u20ec,\u20ed,\u20ee,\u20ef,\u20f0,\u20f1,\u20f2,\u20f3,\u20f4,\u20f5,\u20f6,\u20f7,\u20f8,\u20f9,\u20fa,\u20fb,\u20fc,\u20fd,\u20fe,\u20ff""",
escaped.sorted().joinToString(",")
)
// enum
assertEquals("\"Aa\"", En.Aa.encodeSimpleJsonValue(0))
// object
val o = buildJsonObject {}
assertEquals("{}", o.encodeSimpleJsonValue(0))
o["a"] = "b"
assertEquals("{\"a\":\"b\"}", o.encodeSimpleJsonValue(0))
// Collection
val a = buildJsonArray {}
assertEquals("[]", a.encodeSimpleJsonValue(0))
a.add("b")
assertEquals("[\"b\"]", a.encodeSimpleJsonValue(0))
a[0] = "c"
assertEquals("[\"c\"]", a.encodeSimpleJsonValue(0))
}
@Test
fun testDecimalNotation() {
fun x(expect: Boolean, n: Number) {
val encoded = n.toString()
val actual = encoded.isDecimalNotation()
assertEquals(
expected = expect,
actual = actual,
message = "${n.javaClass.simpleName} $n",
)
}
// integers and longs
x(false, 0)
x(false, -0)
x(false, Int.MIN_VALUE)
x(false, Int.MAX_VALUE)
x(false, Long.MIN_VALUE)
x(false, Long.MAX_VALUE)
// floats
x(true, 0f) // as "0.0"
x(true, -0f) // as "-0.0"
x(true, 0.5f)
x(true, -0.5f)
x(true, Float.MAX_VALUE)
x(true, Float.MIN_VALUE)
// doubles
x(true, 0.0) // as "0.0"
x(true, -0.0) // as "-0.0"
x(true, 0.5)
x(true, -0.5)
x(true, Double.MAX_VALUE)
x(true, Double.MIN_VALUE)
x(true, epsilon)
}
@Test
fun testNumberEncode() {
fun x(
n: Number,
expectValue: Number = n,
expectClass: Class<*> = expectValue.javaClass,
) {
val encodedObject = jsonObjectOf("n" to n).toString()
val decodedObject = encodedObject.decodeJsonObject()
val decoded = decodedObject["n"]
assertEquals<Class<*>?>(
expected = expectClass,
actual = decoded?.javaClass,
message = "$n type $encodedObject",
)
assertEquals(
expected = expectValue,
actual = decoded,
message = "$n value $encodedObject",
)
}
x(0)
x(0f, expectValue = 0)
x(0.0, expectValue = 0)
x(-0)
x(-0f, expectValue = -0.0)
x(-0.0)
x(0.5f, expectValue = 0.5)
x(0.5)
x(-0.5f, expectValue = -0.5)
x(-0.5)
x(epsilon)
x(Int.MIN_VALUE)
x(Int.MAX_VALUE)
x(Long.MIN_VALUE)
x(Long.MAX_VALUE)
x(Double.MAX_VALUE)
x(Double.MIN_VALUE)
// 誤差が出て上限/下限が合わないので、デコード時にはdouble解釈になる
// x(Float.MAX_VALUE, expectValue = Float.MAX_VALUE.toDouble())
// x(Float.MIN_VALUE, expectValue = Float.MIN_VALUE.toDouble())
}
}