blob: 524dd0e0dac0cecd1868f8057d926cfead92b999 [file] [log] [blame]
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers.kotlin
import com.google.flatbuffers.kotlin.FlexBuffersBuilder.Companion.SHARE_NONE
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
class FlexBuffersTest {
@Test
fun testWriteInt() {
val values = listOf(
Byte.MAX_VALUE.toLong() to 3,
Short.MAX_VALUE.toLong() to 4,
Int.MAX_VALUE.toLong() to 6,
Long.MAX_VALUE to 10
)
val builder = FlexBuffersBuilder()
values.forEach {
builder.clear()
builder.put(it.first)
val data = builder.finish()
val ref = getRoot(data)
// although we put a long, it is shrink to a byte
assertEquals(it.second, data.limit)
assertEquals(it.first, ref.toLong())
}
}
@Test
fun testWriteUInt() {
val values = listOf(
UByte.MAX_VALUE.toULong() to 3,
UShort.MAX_VALUE.toULong() to 4,
UInt.MAX_VALUE.toULong() to 6,
ULong.MAX_VALUE to 10
)
val builder = FlexBuffersBuilder()
values.forEach {
builder.clear()
builder.put(it.first)
val data = builder.finish()
val ref = getRoot(data)
// although we put a long, it is shrink to a byte
assertEquals(it.second, data.limit)
assertEquals(it.first, ref.toULong())
}
}
@Test
fun testWriteString() {
val text = "Ḧ̵̘́ȩ̵̐l̶̿͜l̶͚͝o̷̦̚ ̷̫̊w̴̤͊ö̸̞́r̴͎̾l̷͚̐d̶̰̍"
val builder = FlexBuffersBuilder()
builder.put(text)
val data = builder.finish()
val ref = getRoot(data)
assertEquals(text, ref.toString())
}
@Test
fun testInt8Array() {
val ary = intArrayOf(1, 2, 3, 4)
val builder = FlexBuffersBuilder()
builder.put(intArrayOf(1, 2, 3, 4))
val data = builder.finish()
val ref = getRoot(data)
// although we put a long, it is shrink to a byte
assertEquals(8, data.limit)
assertArrayEquals(ary, ref.toIntArray())
}
@Test
fun testShortArray() {
val builder = FlexBuffersBuilder(ArrayReadWriteBuffer(20))
val numbers = ShortArray(10) { it.toShort() }
builder.put(numbers)
val data = builder.finish()
val ref = getRoot(data)
assertArrayEquals(numbers, ref.toShortArray())
}
@Test
fun testHugeArray() {
val builder = FlexBuffersBuilder()
val numbers = IntArray(1024) { it }
builder.put(numbers)
val data = builder.finish()
val ref = getRoot(data)
assertArrayEquals(numbers, ref.toIntArray())
}
@Test
fun testFloatArray() {
val builder = FlexBuffersBuilder()
val numbers = FloatArray(1024) { it * 0.05f }
builder.put(numbers)
val data = builder.finish()
val ref = getRoot(data)
assertArrayEquals(numbers, ref.toFloatArray())
}
@Test
fun testDoubleArray() {
val builder = FlexBuffersBuilder()
val numbers = DoubleArray(1024) { it * 0.0005 }
builder.put(numbers)
val data = builder.finish()
val ref = getRoot(data)
assertArrayEquals(numbers, ref.toDoubleArray())
}
@Test
fun testLongArray() {
val ary: LongArray = longArrayOf(0, Short.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong(), Long.MAX_VALUE)
val builder = FlexBuffersBuilder()
builder.put(ary)
val data = builder.finish()
val ref = getRoot(data)
// although we put a long, it is shrink to a byte
assertArrayEquals(ary, ref.toLongArray())
}
@Test
fun testStringArray() {
val ary = Array(5) { "Hello world number: $it" }
val builder = FlexBuffersBuilder(ArrayReadWriteBuffer(20), SHARE_NONE)
builder.putVector {
ary.forEach { put(it) }
}
val data = builder.finish()
val vec = getRoot(data).toVector()
// although we put a long, it is shrink to a byte
assertEquals(5, vec.size)
val stringAry = vec.map { it.toString() }.toTypedArray()
// although we put a long, it is shrink to a byte
assertArrayEquals(ary, stringAry)
}
@Test
fun testBlobArray() {
val ary = ByteArray(1000) { Random.nextInt().toByte() }
val builder = FlexBuffersBuilder()
builder.put(ary)
val data = builder.finish()
val blob = getRoot(data).toBlob()
// although we put a long, it is shrink to a byte
assertArrayEquals(ary, blob.toByteArray())
for (i in 0 until blob.size) {
assertEquals(ary[i], blob[i])
}
}
@Test
fun testArrays() {
val builder = FlexBuffersBuilder()
val ary: Array<String> = Array(5) { "Hello world number: $it" }
val numbers = IntArray(10) { it }
val doubles = DoubleArray(10) { it * 0.35 }
// add 3 level array of arrays in the following way
// [ [ "..", ...] [ "..", ..., [ "..", ...] ] ]
val vec = builder.startVector()
// [0, 1, 2, 3 ,4 ,5 ,6 ,7 ,8, 9]
val vec1 = builder.startVector()
numbers.forEach { builder.put(it) }
builder.endTypedVector(vec1)
// [0, 2, 4, 6 , 8, 10, 12, 14, 16, 18]
builder.putTypedVector { doubles.forEach { put(it) } }
// nested array
// [ "He..", "He..", "He..", "He..", "He..", [ "He..", "He..", "He..", "He..", "He.." ] ]
val vec3 = builder.startVector()
ary.forEach { builder.put(it) }
builder.putVector { ary.forEach { put("inner: $it") } }
builder.endVector(vec3)
builder.endVector(vec)
val data = builder.finish()
val ref = getRoot(data)
val vecRef = getRoot(data).toVector()
// although we put a long, it is shrink to a byte
assertEquals(3, vecRef.size)
assertArrayEquals(numbers, vecRef[0].toVector().map { it.toInt() }.toIntArray())
assertArrayEquals(doubles, ref[1].toDoubleArray())
assertEquals("Hello world number: 4", vecRef[2][4].toString())
assertEquals("inner: Hello world number: 4", vecRef[2][5][4].toString())
assertEquals("inner: Hello world number: 4", ref[2][5][4].toString())
}
@Test
fun testMap() {
val builder = FlexBuffersBuilder(shareFlag = FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
builder.putVector {
put(10)
putMap {
this["chello"] = "world"
this["aint"] = 10
this["bfloat"] = 12.3
}
put("aString")
}
val ref = getRoot(builder.finish())
val map = ref.toVector()
assertEquals(3, map.size)
assertEquals(10, map[0].toInt())
assertEquals("aString", map[2].toString())
assertEquals("world", map[1]["chello"].toString())
assertEquals(10, map[1]["aint"].toInt())
assertEquals(12.3, map[1]["bfloat"].toDouble())
}
@Test
fun testMultiMap() {
val builder = FlexBuffersBuilder(shareFlag = FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
builder.putMap {
this["hello"] = "world"
this["int"] = 10
this["float"] = 12.3
this["intarray"] = intArrayOf(1, 2, 3, 4, 5)
this.putMap("myMap") {
this["cool"] = "beans"
}
}
val ref = getRoot(builder.finish())
val map = ref.toMap()
assertEquals(5, map.size)
assertEquals("world", map["hello"].toString())
assertEquals(10, map["int"].toInt())
assertEquals(12.3, map["float"].toDouble())
assertArrayEquals(intArrayOf(1, 2, 3, 4, 5), map["intarray"].toIntArray())
assertEquals("beans", ref["myMap"]["cool"].toString())
assertEquals(true, "myMap" in map)
assertEquals(true, "cool" in map["myMap"].toMap())
// testing null values
assertEquals(true, ref["invalid_key"].isNull)
val keys = map.keys.toTypedArray()
arrayOf("hello", "int", "float", "intarray", "myMap").sortedArray().forEachIndexed { i: Int, it: String ->
assertEquals(it, keys[i].toString())
}
}
@Test
fun testBigStringMap() {
val builder = FlexBuffersBuilder(shareFlag = FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
val stringKey = Array(10000) { "Ḧ̵̘́ȩ̵̐myFairlyBigKey$it" }
val stringValue = Array(10000) { "Ḧ̵̘́ȩ̵̐myFairlyBigValue$it" }
val hashMap = mutableMapOf<String, String>()
val pos = builder.startMap()
for (i in stringKey.indices) {
builder[stringKey[i]] = stringValue[i]
hashMap[stringKey[i]] = stringValue[i]
}
builder.endMap(pos)
val ref = getRoot(builder.finish())
val map = ref.toMap()
val sortedKeys = stringKey.sortedArray()
val size = map.size
for (i in 0 until size) {
assertEquals(sortedKeys[i], map.keyAsString(i))
assertEquals(sortedKeys[i], map.keyAt(i).toString())
assertEquals(hashMap[sortedKeys[i]], map[map.keyAt(i)].toString())
}
}
@Test
fun testKeysAccess() {
for (i in 1 until 1000) {
val utf8String = "ሰማይ አይታረስ ንጉሥ አይከሰስ።$i"
val bytes = ByteArray(Utf8.encodedLength(utf8String))
val pos = Utf8.encodeUtf8Array(utf8String, bytes)
val key = Key(ArrayReadWriteBuffer(bytes), 0, pos)
assertEquals(utf8String.length, key.sizeInChars)
for (j in utf8String.indices) {
assertEquals(utf8String[j], key[j])
}
}
}
}