Test round-trip serialization/deserialization of signed integral types
import mir.ser.msgpack : serializeMsgpack; // Bytes assert(serializeMsgpack(byte.min).deserializeMsgpack!byte == byte.min); assert(serializeMsgpack(byte.max).deserializeMsgpack!byte == byte.max); assert(serializeMsgpack(byte(-32)).deserializeMsgpack!byte == -32); // Shorts assert(serializeMsgpack(short.min).deserializeMsgpack!short == short.min); assert(serializeMsgpack(short.max).deserializeMsgpack!short == short.max); // Integers assert(serializeMsgpack(int.min).deserializeMsgpack!int == int.min); assert(serializeMsgpack(int.max).deserializeMsgpack!int == int.max); // Longs assert(serializeMsgpack(long.min).deserializeMsgpack!long == long.min); assert(serializeMsgpack(long.max).deserializeMsgpack!long == long.max);
Test round-trip serialization/deserialization of unsigned integral types
import mir.ser.msgpack : serializeMsgpack; // Unsigned bytes assert(serializeMsgpack(ubyte.min).deserializeMsgpack!ubyte == ubyte.min); assert(serializeMsgpack(ubyte.max).deserializeMsgpack!ubyte == ubyte.max); // Unsigned shorts assert(serializeMsgpack(ushort.min).deserializeMsgpack!ushort == ushort.min); assert(serializeMsgpack(ushort.max).deserializeMsgpack!ushort == ushort.max); // Unsigned integers assert(serializeMsgpack(uint.min).deserializeMsgpack!uint == uint.min); assert(serializeMsgpack(uint.max).deserializeMsgpack!uint == uint.max); // Unsigned logns assert(serializeMsgpack(ulong.min).deserializeMsgpack!ulong == ulong.min); assert(serializeMsgpack(ulong.max).deserializeMsgpack!ulong == ulong.max); // BigInt import mir.bignum.integer : BigInt; assert(serializeMsgpack(BigInt!2(0xDEADBEEF)).deserializeMsgpack!long == 0xDEADBEEF);
Test round-trip serialization/deserialization of null
import mir.ser.msgpack : serializeMsgpack; assert(serializeMsgpack(null).deserializeMsgpack!(typeof(null)) == null);
Test round-trip serialization/deserialization of booleans
import mir.ser.msgpack : serializeMsgpack; assert(serializeMsgpack(true).deserializeMsgpack!bool == true); assert(serializeMsgpack(false).deserializeMsgpack!bool == false);
Test round-trip serialization/deserialization of strings
import std.array : replicate; import mir.ser.msgpack : serializeMsgpack; import mir.test; assert("foobar".serializeMsgpack.deserializeMsgpack!string == "foobar"); assert("bazfoo".serializeMsgpack.deserializeMsgpack!string == "bazfoo"); { auto str = "a".replicate(32); serializeMsgpack(str).deserializeMsgpack!string.should == str; } { auto str = "a".replicate(ubyte.max); serializeMsgpack(str).deserializeMsgpack!string.should == str; } { auto str = "a".replicate(ubyte.max + 1); serializeMsgpack(str).deserializeMsgpack!string.should == str; } { auto str = "a".replicate(ushort.max); serializeMsgpack(str).deserializeMsgpack!string.should == str; } { auto str = "a".replicate(ushort.max + 1); serializeMsgpack(str).deserializeMsgpack!string.should == str; }
Test round-trip serializing/deserialization blobs / clobs
import mir.lob : Blob, Clob; import mir.ser.msgpack : serializeMsgpack; import std.array : replicate; // Blobs // These need to be trusted because we cast const(char)[] to ubyte[] (which is fine here!) () @trusted { auto de = "\xde".replicate(32); auto blob = Blob(cast(ubyte[])de); assert(serializeMsgpack(blob).deserializeMsgpack!Blob == blob); } (); () @trusted { auto de = "\xde".replicate(ushort.max); auto blob = Blob(cast(ubyte[])de); assert(serializeMsgpack(blob).deserializeMsgpack!Blob == blob); } (); () @trusted { auto de = "\xde".replicate(ushort.max + 1); auto blob = Blob(cast(ubyte[])de); assert(serializeMsgpack(blob).deserializeMsgpack!Blob == blob); } (); // Clobs (serialized just as regular strings here) () @trusted { auto de = "\xde".replicate(32); auto clob = Clob(de); assert(serializeMsgpack(clob).deserializeMsgpack!string == clob.data); } ();
Test round-trip serialization/deserialization of arrays
import mir.ser.msgpack : serializeMsgpack; { auto arr = [["foo"], ["bar"], ["baz"]]; assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr); } { auto arr = [0xDEADBEEF, 0xCAFEBABE, 0xAAAA_AAAA]; assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr); } { auto arr = ["foo", "bar", "baz"]; assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr); } { auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]; assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr); }
Test serializing maps (structs)
import mir.ser.msgpack : serializeMsgpack; static struct Book { string title; bool wouldRecommend; string description; uint numberOfNovellas; double price; float weight; string[] tags; } Book book = Book("A Hero of Our Time", true, "", 5, 7.99, 6.88, ["russian", "novel", "19th century"]); assert(serializeMsgpack(book).deserializeMsgpack!(Book) == book);
Test serializing maps (structs), assuming @nogc
import mir.appender : scopedBuffer; import mir.ser.msgpack : serializeMsgpack; // import mir.small_string; static struct Book { // SmallStrings apparently cannot be serialized // without allocating? // SmallString!64 title; bool wouldRecommend; // SmallString!64 description; uint numberOfNovellas; double price; float weight; } auto buf = scopedBuffer!ubyte(); Book book = Book(true, 5, 7.99, 6.88); serializeMsgpack(buf, book); assert(buf.data.deserializeMsgpack!Book() == book);
Test round-trip serialization/deserialization of a large map
import mir.ser.msgpack : serializeMsgpack; static struct HugeStruct { bool a; bool b; bool c; bool d; bool e; string f; string g; string h; string i; string j; int k; int l; int m; int n; int o; long p; } HugeStruct s = HugeStruct(true, true, true, true, true, "", "", "", "", "", 123, 456, 789, 123, 456, 0xDEADBEEF); assert(serializeMsgpack(s).deserializeMsgpack!HugeStruct == s);
Test excessively large array
import mir.ser.msgpack : serializeMsgpack; static struct HugeArray { ubyte[] arg; void serialize(S)(scope ref S serializer) scope const { auto state = serializer.structBegin(); serializer.putKey("arg"); auto arrayState = serializer.listBegin(); foreach(i; 0 .. (ushort.max + 1)) { serializer.elemBegin; serializer.putValue(ubyte(0)); } serializer.listEnd(arrayState); serializer.structEnd(state); } } auto arr = HugeArray(); assert((serializeMsgpack(arr).deserializeMsgpack!HugeArray).arg.length == ushort.max + 1);
Test excessively large map
import mir.serde : serdeAllowMultiple; import mir.ser.msgpack : serializeMsgpack; static struct BFM // Big Freakin' Map { @serdeAllowMultiple ubyte asdf; void serialize(S)(scope ref S serializer) scope const { auto state = serializer.structBegin(); foreach (i; 0 .. (ushort.max + 1)) { serializer.putKey("asdf"); serializer.putValue(ubyte(0)); } serializer.structEnd(state); } } auto map = BFM(); assert(serializeMsgpack(map).deserializeMsgpack!BFM == map);
Test map with varying key lengths
import mir.ser.msgpack : serializeMsgpack; import std.array : replicate; ubyte[string] map; map["a".replicate(32)] = 0xFF; map["b".replicate(ubyte.max + 1)] = 0xFF; map["c".replicate(ushort.max + 1)] = 0xFF; assert(serializeMsgpack(map).deserializeMsgpack!(typeof(map)) == map);
Test deserializing an extension type
import mir.lob : Blob; { const(ubyte)[] data = [0xc7, 0x01, 0x02, 0xff]; MsgpackExtension ext = MsgpackExtension(Blob([0xff]), 0x02); assert(data.deserializeMsgpack!MsgpackExtension == ext); } { const(ubyte)[] data = [0xc8, 0x00, 0x01, 0x02, 0xff]; MsgpackExtension ext = MsgpackExtension(Blob([0xff]), 0x02); assert(data.deserializeMsgpack!MsgpackExtension == ext); } { const(ubyte)[] data = [0xc9, 0x00, 0x00, 0x00, 0x01, 0x02, 0xff]; MsgpackExtension ext = MsgpackExtension(Blob([0xff]), 0x02); assert(data.deserializeMsgpack!MsgpackExtension == ext); }