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 }