blob: 02161b5ef093dec65d4b4e6b48b520e8b6eaaa31 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.v23.vdl;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import junit.framework.TestCase;
import io.v.v23.vdl.VdlType.Builder;
import io.v.v23.vdl.VdlType.PendingType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Tests methods on VDL Types.
*/
public class TypeTest extends TestCase {
@GeneratedFromVdl(name = "MyBool")
private static final class MyBool extends VdlBool {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyByte")
private static final class MyByte extends VdlByte {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyUint16")
private static final class MyUint16 extends VdlUint16 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyUint32")
private static final class MyUint32 extends VdlUint32 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyUint64")
private static final class MyUint64 extends VdlUint64 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyInt16")
private static final class MyInt16 extends VdlInt16 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyInt32")
private static final class MyInt32 extends VdlInt32 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyInt64")
private static final class MyInt64 extends VdlInt64 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyFloat32")
private static final class MyFloat32 extends VdlFloat32 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyFloat64")
private static final class MyFloat64 extends VdlFloat64 {
private static final long serialVersionUID = 1L;
}
@GeneratedFromVdl(name = "MyString")
private static final class MyString extends VdlString {
private static final long serialVersionUID = 1L;
}
@SuppressWarnings("unused")
@GeneratedFromVdl(name = "MyUnion")
private static class MyUnion extends VdlUnion {
private static final long serialVersionUID = 1L;
@GeneratedFromVdl(name = "A", index = 0)
public static class A extends MyUnion {
private static final long serialVersionUID = 1L;
private MyInt16 elem;
}
@GeneratedFromVdl(name = "B", index = 1)
public static class B extends MyUnion {
private static final long serialVersionUID = 1L;
private VdlInt32 elem;
}
@GeneratedFromVdl(name = "C", index = 2)
public static class C extends MyUnion {
private static final long serialVersionUID = 1L;
private Long elem;
}
private MyUnion() {
super(Types.getVdlTypeFromReflect(MyUnion.class), 0, null);
}
}
@GeneratedFromVdl(name = "MyEnum")
private static final class MyEnum extends VdlEnum {
private static final long serialVersionUID = 1L;
@GeneratedFromVdl(name = "LABEL1", index = 0)
public static final MyEnum LABEL1 = new MyEnum("LABEL1");
@GeneratedFromVdl(name = "LABEL2", index = 1)
public static final MyEnum LABEL2 = new MyEnum("LABEL2");
@GeneratedFromVdl(name = "LABEL3", index = 2)
public static final MyEnum LABEL3 = new MyEnum("LABEL3");
private MyEnum(String name) {
super(Types.getVdlTypeFromReflect(MyEnum.class), name);
}
}
@GeneratedFromVdl(name = "MyArray12")
@ArrayLength(12)
private static final class MyArray12 extends VdlArray<Set<MyUnion>> {
private static final long serialVersionUID = 1L;
public MyArray12(Set<MyUnion>[] value) {
super(Types.getVdlTypeFromReflect(MyArray12.class), value);
}
}
@GeneratedFromVdl(name = "MyList")
private static final class MyList extends VdlList<List<MyArray12>> {
private static final long serialVersionUID = 1L;
public MyList(List<List<MyArray12>> impl) {
super(Types.getVdlTypeFromReflect(MyList.class), impl);
}
}
@GeneratedFromVdl(name = "MySet")
private static final class MySet extends VdlSet<Set<MyList>> {
private static final long serialVersionUID = 1L;
public MySet(Set<Set<MyList>> impl) {
super(Types.getVdlTypeFromReflect(MySet.class), impl);
}
}
@GeneratedFromVdl(name = "MyMap")
private static final class MyMap extends VdlMap<MyEnum, Map<MySet, MySet>> {
private static final long serialVersionUID = 1L;
public MyMap(Map<MyEnum, Map<MySet, MySet>> impl) {
super(Types.getVdlTypeFromReflect(MyMap.class), impl);
}
}
@GeneratedFromVdl(name = "MyStruct")
private static final class MyStruct extends AbstractVdlStruct {
private static final long serialVersionUID = 1L;
@GeneratedFromVdl(name = "ByteArray", index = 0)
private byte[][] byteArray;
@GeneratedFromVdl(name = "Set", index = 1)
private Set<MyMap> set;
@GeneratedFromVdl(name = "Cycle", index = 2)
private List<MyStruct> cycle;
public MyStruct() {
super(Types.getVdlTypeFromReflect(MyStruct.class));
}
}
private static final Map<VdlType, Type> myTypes;
static {
VdlType myBool = Types.named("MyBool", Types.BOOL);
VdlType myByte = Types.named("MyByte", Types.BYTE);
VdlType myUint16 = Types.named("MyUint16", Types.UINT16);
VdlType myUint32 = Types.named("MyUint32", Types.UINT32);
VdlType myUint64 = Types.named("MyUint64", Types.UINT64);
VdlType myInt16 = Types.named("MyInt16", Types.INT16);
VdlType myInt32 = Types.named("MyInt32", Types.INT32);
VdlType myInt64 = Types.named("MyInt64", Types.INT64);
VdlType myFloat32 = Types.named("MyFloat32", Types.FLOAT32);
VdlType myFloat64 = Types.named("MyFloat64", Types.FLOAT64);
VdlType myString = Types.named("MyString", Types.STRING);
VdlType myUnion = Types.named("MyUnion", Types.unionOf(new VdlField("A", myInt16),
new VdlField("B", Types.INT32), new VdlField("C", Types.INT64)));
VdlType myEnum = Types.named("MyEnum", Types.enumOf("LABEL1", "LABEL2", "LABEL3"));
VdlType myArray12 = Types.named("MyArray12", Types.arrayOf(12, Types.setOf(myUnion)));
VdlType myList = Types.named("MyList", Types.listOf(Types.listOf(myArray12)));
VdlType mySet = Types.named("MySet", Types.setOf(Types.setOf(myList)));
VdlType myMap = Types.named("MyMap", Types.mapOf(myEnum, Types.mapOf(mySet, mySet)));
Builder builder = new Builder();
PendingType pendingStruct = builder.newPending(Kind.STRUCT).setName("MyStruct");
pendingStruct.addField("ByteArray", Types.listOf(Types.listOf(Types.BYTE)))
.addField("Set", Types.setOf(myMap))
.addField("Cycle", builder.listOf(pendingStruct));
builder.build();
VdlType myStruct = pendingStruct.built();
VdlType myOptional = Types.optionalOf(myStruct);
myTypes = new ImmutableMap.Builder<VdlType, Type>()
.put(myBool, MyBool.class)
.put(myByte, MyByte.class)
.put(myUint16, MyUint16.class)
.put(myUint32, MyUint32.class)
.put(myUint64, MyUint64.class)
.put(myInt16, MyInt16.class)
.put(myInt32, MyInt32.class)
.put(myInt64, MyInt64.class)
.put(myFloat32, MyFloat32.class)
.put(myFloat64, MyFloat64.class)
.put(myString, MyString.class)
.put(myUnion, MyUnion.class)
.put(myEnum, MyEnum.class)
.put(myArray12, MyArray12.class)
.put(myList, MyList.class)
.put(mySet, MySet.class)
.put(myMap, MyMap.class)
.put(myStruct, MyStruct.class)
.put(myOptional, new TypeToken<VdlOptional<MyStruct>>(){}.getType())
.build();
}
public void testGetVdlTypeFromReflection() {
for (Map.Entry<VdlType, Type> entry : myTypes.entrySet()) {
assertEquals("VDL type for reflect type: " + entry.getValue(),
entry.getKey(), Types.getVdlTypeFromReflect(entry.getValue()));
}
}
public void testTypeString() {
String myInt16 = "MyInt16 int16";
String myUnion = String.format("MyUnion union{A %s;B int32;C int64}", myInt16);
String myEnum = "MyEnum enum{LABEL1;LABEL2;LABEL3}";
String myArray12 = String.format("MyArray12 [12]set[%s]", myUnion);
String myList = String.format("MyList [][]%s", myArray12);
String mySet = String.format("MySet set[set[%s]]", myList);
String myMap = String.format("MyMap map[%s]map[%s]MySet", myEnum, mySet);
String myStruct = String.format("MyStruct struct{ByteArray [][]byte;Set set[%s];"
+ "Cycle []MyStruct}", myMap);
String myOptional = "?" + myStruct;
assertEquals(myUnion, Types.getVdlTypeFromReflect(MyUnion.class).toString());
assertEquals(myEnum, Types.getVdlTypeFromReflect(MyEnum.class).toString());
assertEquals(myArray12, Types.getVdlTypeFromReflect(MyArray12.class).toString());
assertEquals(myList, Types.getVdlTypeFromReflect(MyList.class).toString());
assertEquals(mySet, Types.getVdlTypeFromReflect(MySet.class).toString());
assertEquals(myMap, Types.getVdlTypeFromReflect(MyMap.class).toString());
assertEquals(myStruct, Types.getVdlTypeFromReflect(MyStruct.class).toString());
assertEquals(myOptional, Types.getVdlTypeFromReflect(
new TypeToken<VdlOptional<MyStruct>>(){}.getType()).toString());
}
public void testEquals() {
VdlType.Builder builder = new Builder();
VdlType primitive = Types.UINT32;
VdlType list = Types.listOf(primitive);
PendingType recursiveSet = builder.newPending(Kind.SET).setName("recursiveSet");
recursiveSet.setKey(recursiveSet);
PendingType recursiveList = builder.newPending(Kind.LIST);
PendingType recursiveStruct = builder.newPending(Kind.STRUCT).setName("recursiveStruct");
recursiveList.setElem(recursiveStruct);
recursiveStruct.addField("rec", recursiveSet);
recursiveStruct.addField("rec2", recursiveList);
builder.build();
VdlType[] types = new VdlType[] {
primitive, list, recursiveSet.built(),
recursiveStruct.built(), recursiveList.built()
};
for (VdlType type : types) {
for (VdlType other : types) {
if (type == other) {
assertEquals(type, other);
} else {
assertFalse(type.equals(other));
}
}
}
}
private void verifyReflectType(VdlType vdlType, Class<?> ... classes) {
Type reflectType = Types.getReflectTypeForVdl(vdlType);
for (int i = 0; i < classes.length; i++) {
if (i < classes.length - 1) {
assertEquals(classes[i], ((ParameterizedType) reflectType).getRawType());
reflectType = ((ParameterizedType) reflectType).getActualTypeArguments()[0];
} else {
assertEquals(classes[i], reflectType);
}
}
}
public void testGetReflectTypeForVdl() {
verifyReflectType(Types.listOf(Types.STRING), VdlList.class, String.class);
verifyReflectType(Types.setOf(Types.INT32), VdlSet.class, Integer.class);
try {
Types.getReflectTypeForVdl(Types.arrayOf(2, Types.INT16));
fail("Reflect type should not be constructed for VDL type [2]int16");
} catch (IllegalArgumentException expected) {
}
try {
Types.getReflectTypeForVdl(Types.structOf(new VdlField("a", Types.BOOL)));
fail("Reflect type should not be constructed for VDL type struct{a bool}");
} catch (IllegalArgumentException expected) {
}
}
public void testTypesUnique() {
VdlType.Builder builder = new VdlType.Builder();
PendingType p1 = builder.newPending(Kind.STRUCT);
builder.build();
VdlType t1 = p1.built();
builder = new VdlType.Builder();
PendingType p2 = builder.newPending(Kind.STRUCT);
PendingType p3 = builder.newPending(Kind.STRUCT);
p2.addField("SameAsT1", p3);
builder.build();
VdlType t2 = p2.built();
assertEquals(t1, t2.getFields().get(0).getType());
}
}