Complete tests for all prim array types

Remove the case for bytes as those do work with the existing code
This commit is contained in:
Katelyn Baker 2017-07-25 10:17:57 +01:00
parent f8116febad
commit c63ed76a66
3 changed files with 141 additions and 40 deletions

View File

@ -15,9 +15,9 @@ open class ArraySerializer(override val type: Type, factory: SerializerFactory)
}
}
override val typeDescriptor = "$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}"
internal val elementType: Type = type.componentType()
internal open val typeName = type.typeName
override val typeDescriptor by lazy { "$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}" }
internal val elementType: Type by lazy { type.componentType() }
internal open val typeName by lazy { type.typeName }
internal val typeNotation: TypeNotation by lazy {
RestrictedType(typeName, null, emptyList(), "list", Descriptor(typeDescriptor, null), emptyList())
@ -49,7 +49,6 @@ open class ArraySerializer(override val type: Type, factory: SerializerFactory)
open fun <T> List<T>.toArrayOfType(type: Type): Any {
val elementType = type.asClass() ?: throw NotSerializableException("Unexpected array element type $type")
val list = this
println ("toArrayOfType - $elementType")
return java.lang.reflect.Array.newInstance(elementType, this.size).apply {
(0..lastIndex).forEach { java.lang.reflect.Array.set(this, it, list[it]) }
}
@ -75,6 +74,8 @@ class CharArraySerializer(factory: SerializerFactory) : ArraySerializer(Array<Ch
*/
abstract class PrimArraySerializer (type: Type, factory: SerializerFactory) : ArraySerializer(type, factory) {
companion object {
// We don't need to handle the unboxed byte type as that is coercible to a byte array, but
// the other 7 primitive types we do
val primTypes: Map<Type, (SerializerFactory) -> PrimArraySerializer> = mapOf(
IntArray::class.java to { f -> PrimIntArraySerializer(f, "int[p]") },
CharArray::class.java to { f -> PrimCharArraySerializer(f, "char[p]") },
@ -82,7 +83,6 @@ abstract class PrimArraySerializer (type: Type, factory: SerializerFactory) : Ar
FloatArray::class.java to { f -> PrimFloatArraySerializer(f, "float[p]") },
ShortArray::class.java to { f -> PrimShortArraySerializer(f, "short[p]") },
DoubleArray::class.java to { f -> PrimDoubleArraySerializer(f, "double[p]") },
ByteArray::class.java to { f -> PrimByteArraySerializer(f, "byte[p]") },
LongArray::class.java to { f -> PrimLongArraySerializer(f, "long[p]") }
)
@ -145,16 +145,9 @@ class PrimShortArraySerializer(factory: SerializerFactory, override val typeName
}
}
class PrimByteArraySerializer(factory: SerializerFactory, override val typeName: String) :
PrimArraySerializer(ByteArray::class.java, factory) {
override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) {
localWriteObject(data) { (obj as ByteArray).forEach { output.writeObjectOrNull(it, data, elementType) } }
}
}
class PrimLongArraySerializer(factory: SerializerFactory, override val typeName: String) :
PrimArraySerializer(LongArray::class.java, factory) {
override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) {
localWriteObject(data) { (obj as FloatArray).forEach { output.writeObjectOrNull(it, data, elementType) } }
localWriteObject(data) { (obj as LongArray).forEach { output.writeObjectOrNull(it, data, elementType) } }
}
}

View File

@ -203,20 +203,9 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
} else {
findCustomSerializer(clazz, declaredType) ?: run {
if (type.isArray()) {
println ("Array: ${type.componentType()}, ${type.componentType()::class.java}")
println (clazz)
println (declaredType)
println ("${clazz.componentType.isPrimitive()}")
if (clazz.componentType.isPrimitive) {
println ("primitive array")
whitelisted(type.componentType())
PrimArraySerializer.make(type, this)
}
else {
println ("non primitive array")
whitelisted(type.componentType())
ArraySerializer.make (type, this)
}
if (clazz.componentType.isPrimitive) PrimArraySerializer.make(type, this)
else ArraySerializer.make (type, this)
} else if (clazz.kotlin.objectInstance != null) {
whitelisted(clazz)
SingletonSerializer(clazz, clazz.kotlin.objectInstance!!, this)
@ -304,21 +293,17 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
private val namesOfPrimitiveTypes: Map<String, Class<*>> = primitiveTypeNames.map { it.value to it.key }.toMap()
fun nameForType(type: Type) : String {
println ("nameForType $type - ${(type as Class<*>).isArray} - ${type?.componentType?.isPrimitive}")
val result = when (type) {
is Class<*> -> primitiveTypeName(type) ?: if (type.isArray) {
if (type.componentType.isPrimitive) "${nameForType(type.componentType)}[p]" else "${nameForType(type.componentType)}[]"
fun nameForType(type: Type) : String = when (type) {
is Class<*> -> {
primitiveTypeName(type) ?: if (type.isArray) {
"${nameForType(type.componentType)}${if(type.componentType.isPrimitive)"[p]" else "[]"}"
} else type.name
}
is ParameterizedType -> "${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>"
is GenericArrayType -> "${nameForType(type.genericComponentType)}[]"
else -> throw NotSerializableException("Unable to render type $type to a string.")
}
println ("nameForType = $result")
return result
}
private fun typeForName(name: String): Type {
return if (name.endsWith("[]")) {
val elementType = typeForName(name.substring(0, name.lastIndex - 1))
@ -337,7 +322,6 @@ class SerializerFactory(val whitelist: ClassWhitelist = AllWhitelist) {
"float[p]" -> FloatArray::class.java
"double[p]" -> DoubleArray::class.java
"short[p]" -> ShortArray::class.java
"byte[p]" -> ByteArray::class.java
"long[p]" -> LongArray::class.java
else -> throw NotSerializableException("Not able to deserialize array type: $name")
}

View File

@ -53,7 +53,6 @@ class DeserializeSimpleTypesTests {
@Test
fun testArrayOfInt() {
class IA(val ia: Array<Int>)
val ia = IA(arrayOf(1, 2, 3))
assertEquals("class [Ljava.lang.Integer;", ia.ia::class.java.toString())
@ -182,52 +181,177 @@ class DeserializeSimpleTypesTests {
@Test
fun testArrayOfByte() {
class C(val c: Array<Byte>)
class C (val c: Array<Byte>)
val c = C(arrayOf (0b0001, 0b0101, 0b1111))
assertEquals("class [Ljava.lang.Byte;", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "byte[]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testByteArray() {
class C(val c: ByteArray)
val c = C(ByteArray(3))
c.c[0] = 0b0001; c.c[1] = 0b0101; c.c[2] = 0b1111
assertEquals("class [B", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "binary")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testArrayOfShort() {
class C(val c: Array<Short>)
val c = C(arrayOf (1, 2, 3))
assertEquals("class [Ljava.lang.Short;", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "short[]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testShortArray() {
class C(val c: ShortArray)
val c = C(ShortArray(3))
c.c[0] = 1; c.c[1] = 2; c.c[2] = 5
assertEquals("class [S", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "short[p]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testArrayOfLong() {
class C(val c: Array<Long>)
val c = C(arrayOf (2147483650, -2147483800, 10))
assertEquals("class [Ljava.lang.Long;", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "long[]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testLongArray() {
class C(val c: LongArray)
val c = C(LongArray(3))
c.c[0] = 2147483650; c.c[1] = -2147483800; c.c[2] = 10
assertEquals("class [J", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "long[p]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testArrayOfFloat() {
class C(val c: Array<Float>)
val c = C(arrayOf(10F, 100.023232F, -1455.433400F))
assertEquals("class [Ljava.lang.Float;", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "float[]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testFloatArray() {
class C(val c: FloatArray)
val c = C(FloatArray(3))
c.c[0] = 10F; c.c[1] = 100.023232F; c.c[2] = -1455.433400F
assertEquals("class [F", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "float[p]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testArrayOfDouble() {
class C(val c: Array<Double>)
val c = C(arrayOf(10.0, 100.2, -1455.2))
assertEquals("class [Ljava.lang.Double;", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "double[]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
@Test
fun testDoubleArray() {
class C(val c: DoubleArray)
val c = C(DoubleArray(3))
c.c[0] = 10.0; c.c[1] = 100.2; c.c[2] = -1455.2
assertEquals("class [D", c.c::class.java.toString())
assertEquals(SerializerFactory.nameForType(c.c::class.java), "double[p]")
val serialisedC = TestSerializationOutput(VERBOSE, sf).serialize(c)
val deserializedC = DeserializationInput(sf).deserialize(serialisedC)
assertEquals(c.c.size, deserializedC.c.size)
assertEquals(c.c[0], deserializedC.c[0])
assertEquals(c.c[1], deserializedC.c[1])
assertEquals(c.c[2], deserializedC.c[2])
}
}