1 module tests.encode_decode; 2 3 import unit_threaded; 4 import cerealed.cerealiser; 5 import cerealed.decerealiser; 6 import core.exception; 7 8 9 private void implEncDec(T)(T[] values) { 10 auto enc = Cerealiser(); 11 import std.stdio; 12 foreach(b; values) { 13 writelnUt("Encoding ", b); 14 enc ~= b; 15 } 16 auto dec = Decerealiser(enc.bytes); 17 writelnUt("Decoding to match ", values); 18 writelnUt("Bytes: ", enc.bytes); 19 foreach(b; values) shouldEqual(dec.value!T, b); 20 dec.value!ubyte.shouldThrow!RangeError; //no more bytes 21 } 22 23 void testEncDecBool() { 24 implEncDec([ true, true, false, false, true]); 25 } 26 27 28 private void implEncDecValues(T, alias arr)() { 29 T[] values = arr; 30 implEncDec(values); 31 } 32 33 void testEncDecByte() { 34 implEncDecValues!(byte, [ 1, 3, -2, 5, -4 ]); 35 } 36 37 void testEncDecUByte() { 38 implEncDecValues!(ubyte, [ 1, 255, 12 ]); 39 } 40 41 void testEncDecShort() { 42 implEncDecValues!(short, [ 1, -2, -32768, 5 ]); 43 } 44 45 void testEncDecUShort() { 46 implEncDecValues!(short, [ 1, -2, 32767, 5 ]); 47 } 48 49 void testEncDecInt() { 50 implEncDecValues!(int, [ 1, -2, -1_000_000, 2_000_000 ]); 51 } 52 53 void testEncDecUInt() { 54 implEncDecValues!(uint, [ 1, -2, 1_000_000, 2_000_000 ]); 55 } 56 57 void testEncDecLong() { 58 implEncDecValues!(long, [ 5_000_000, 2, -3, -5_000_000_000, 1 ]); 59 } 60 61 void testEncDecULong() { 62 implEncDecValues!(ulong, [ 5_000_000, 2, 7_000_000_000, 1 ]); 63 } 64 65 void testEncDecFloat() { 66 implEncDec([ 2.0f, -4.3f, 3.1415926f ]); //don't add a value without 'f'! 67 } 68 69 void testEncDecDouble() { 70 implEncDec([ 2.0, -9.0 ]); 71 } 72 73 void testEncDecChars() { 74 char c = 5; 75 wchar w = 300; 76 dchar d = 1_000_000; 77 auto enc = Cerealiser(); 78 enc ~= c; enc ~= w; enc ~= d; 79 auto dec = Decerealiser(enc.bytes); 80 dec.value!char.shouldEqual(c); 81 dec.value!wchar.shouldEqual(w); 82 dec.value!dchar.shouldEqual(d); 83 dec.value!ubyte.shouldThrow!RangeError; //no more bytes 84 } 85 86 void testEncDecArray() { 87 auto enc = Cerealiser(); 88 const ints = [ 2, 6, 9]; 89 enc ~= ints; 90 auto dec = Decerealiser(enc.bytes); 91 dec.value!(int[]).shouldEqual(ints); 92 dec.value!ubyte.shouldThrow!RangeError; //no more bytes 93 } 94 95 96 @("struct with @LengthType") unittest { 97 import cerealed.attrs: LengthType; 98 struct Foo { 99 @LengthType!ubyte ushort[] arr; 100 } 101 102 auto enc = Cerealiser(); 103 auto foo = Foo([7, 8, 9]); 104 enc ~= foo; 105 enc.bytes.shouldEqual([3, 0, 7, 0, 8, 0, 9]); 106 auto dec = Decerealiser(enc.bytes); 107 dec.value!Foo.shouldEqual(foo); 108 } 109 110 void testEncDecAssocArray() { 111 auto enc = Cerealiser(); 112 const intToInts = [ 1:2, 3:6, 9:18]; 113 enc ~= intToInts; 114 auto dec = Decerealiser(enc.bytes); 115 dec.value!(int[int]).shouldEqual(intToInts); 116 dec.value!ubyte.shouldThrow!RangeError; //no more bytes 117 }