1 module tests.encode; 2 3 import unit_threaded; 4 import cerealed.cerealiser; 5 6 7 void testEncodeBool() { 8 auto cereal = Cerealiser(); 9 cereal.write(false); 10 cereal.write(true); 11 cereal.write(false); 12 cereal.bytes.shouldEqual([ 0x0, 0x1, 0x0 ]); 13 14 cereal ~= true; 15 cereal.bytes.shouldEqual([ 0x0, 0x1, 0x0, 0x1 ]); 16 } 17 18 void testEncodeByte() { 19 auto cereal = Cerealiser(); 20 byte[] ins = [ 1, 3, -2, 5, -4]; 21 foreach(i; ins) cereal.write(i); 22 cereal.bytes.shouldEqual([ 0x1, 0x3, 0xfe, 0x5, 0xfc ]); 23 } 24 25 void testEncodeUByte() { 26 auto cereal = Cerealiser(); 27 ubyte[] ins = [ 2, 3, 12, 10]; 28 foreach(i; ins) cereal ~= i; 29 cereal.bytes.shouldEqual([ 0x2, 0x3, 0xc, 0xa ]); 30 } 31 32 void testEncodeShort() { 33 auto cereal = Cerealiser(); 34 short[] ins = [ -2, 3, -32767, 0]; 35 foreach(i; ins) cereal ~= i; 36 cereal.bytes.shouldEqual([ 0xff, 0xfe, 0x0, 0x3, 0x80, 0x01, 0x0, 0x0 ]); 37 } 38 39 void testEncodeUShort() { 40 auto cereal = Cerealiser(); 41 ushort[] ins = [ 2, 3, cast(short)65535, 0]; 42 foreach(i; ins) cereal ~= i; 43 cereal.bytes.shouldEqual([ 0x0, 0x2, 0x0, 0x3, 0xff, 0xff, 0x0, 0x0 ]); 44 } 45 46 void testEncodeInt() { 47 auto cereal = Cerealiser(); 48 int[] ins = [ 3, -1_000_000]; 49 foreach(i; ins) cereal ~= i; 50 cereal.bytes.shouldEqual([ 0x0, 0x0, 0x0, 0x3, 0xff, 0xf0, 0xbd, 0xc0 ]); 51 } 52 53 void testEncodeUInt() { 54 auto cereal = Cerealiser(); 55 uint[] ins = [ 1_000_000, 0]; 56 foreach(i; ins) cereal ~= i; 57 cereal.bytes.shouldEqual([ 0x0, 0x0f, 0x42, 0x40, 0x0, 0x0, 0x0, 0x0 ]); 58 } 59 60 void testEncodeLong() { 61 auto cereal = Cerealiser(); 62 long[] ins = [1, 2]; 63 foreach(i; ins) cereal ~= i; 64 cereal.bytes.shouldEqual([ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2]); 65 } 66 67 void testEncodeULong() { 68 auto cereal = Cerealiser(); 69 cereal ~= 45L; 70 cereal.bytes.shouldEqual([ 0, 0, 0, 0, 0, 0, 0, 45 ]); 71 72 cereal = Cerealiser(); 73 cereal ~= 42L; 74 cereal.bytes.shouldEqual([ 0, 0, 0, 0, 0, 0, 0, 42 ]); 75 } 76 77 void testEncodeBigULong() { 78 ulong val = 0xd8bfc7cd2d9ba1b1; 79 auto enc = Cerealiser(); 80 enc ~= val; 81 enc.bytes.shouldEqual([0xd8, 0xbf, 0xc7, 0xcd, 0x2d, 0x9b, 0xa1, 0xb1]); 82 } 83 84 void testEncodeFloat() { 85 auto cereal = Cerealiser(); 86 cereal ~= 1.0f; 87 } 88 89 void testEncodeDouble() { 90 auto cereal = Cerealiser(); 91 cereal ~= 1.0; 92 } 93 94 void testEncodeChars() { 95 auto cereal = Cerealiser(); 96 char c; cereal ~= c; 97 wchar w; cereal ~= w; 98 dchar d; cereal ~= d; 99 cereal.bytes.shouldEqual([ 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff]); 100 } 101 102 void testEncodeArray() { 103 auto cereal = Cerealiser(); 104 const ints = [ 2, 6, 9]; 105 cereal ~= ints; 106 //encoding should be a short with the length, plus payload 107 cereal.bytes.shouldEqual([ 0, 3, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 9]); 108 } 109 110 void testEncodeAssocArray() { 111 import std.algorithm; 112 113 auto cereal = Cerealiser(); 114 const intToInt = [ 1:2, 3:6]; 115 import std.traits; 116 import std.range; 117 cereal ~= intToInt; 118 //short with length, then payload 119 cereal.bytes[0..2].shouldEqual([0, 2]); 120 cereal.bytes.length.shouldEqual(18); //ushort length, 4 bytes each for each int 121 cereal.bytes.canFind([0, 0, 0, 1, /*:*/ 0, 0, 0, 2,]).shouldBeTrue; 122 cereal.bytes.canFind([0, 0, 0, 3, /*:*/ 0, 0, 0, 6,]).shouldBeTrue; 123 } 124 125 void testEncodeString() { 126 auto cereal = Cerealiser(); 127 const str = "foobarbaz"; 128 cereal ~= str; 129 //short with length, then payload 130 cereal.bytes.shouldEqual([ 0, 9, 'f', 'o', 'o', 'b', 'a', 'r', 'b', 'a', 'z' ]); 131 } 132 133 void testEncodeNibble() { 134 auto cereal = Cerealiser(); 135 cereal.writeBits(0x4, 4); 136 cereal.writeBits(0xf, 4); 137 cereal.bytes.shouldEqual([ 0x4f ]); 138 } 139 140 void testEncodeSubByte() { 141 auto cereal = Cerealiser(); 142 cereal.writeBits(1, 1); 143 cereal.writeBits(3, 2); 144 cereal.writeBits(0, 1); 145 cereal.writeBits(5, 3); 146 cereal.writeBits(1, 1); 147 cereal.bytes.shouldEqual([ 0xeb]); 148 } 149 150 void testEncodeSubWord() { 151 auto cereal = Cerealiser(); 152 cereal.writeBits(4, 3); 153 cereal.writeBits(7, 3); 154 cereal.writeBits(23, 5); 155 cereal.writeBits(1, 2); 156 cereal.writeBits(2, 3); 157 cereal.bytes.shouldEqual([ 0x9e, 0xea]); 158 } 159 160 void testEncodeMoreThan8Bits() { 161 { 162 auto cereal = Cerealiser(); 163 cereal.writeBits(1, 9); 164 cereal.writeBits(15, 7); 165 cereal.bytes.shouldEqual([ 0x00, 0x8f]); 166 } 167 { 168 auto cereal = Cerealiser(); 169 cereal.writeBits((0x9e << 1) | 1, 9); 170 cereal.writeBits(0xea & 0x7f, 7); 171 cereal.bytes.shouldEqual([ 0x9e, 0xea]); 172 } 173 } 174 175 void testEncodeFailsIfTooBigForBits() { 176 auto cereal = Cerealiser(); 177 shouldNotThrow(cereal.writeBits(1, 1)); 178 shouldThrow(cereal.writeBits(2, 1)); 179 shouldNotThrow(cereal.writeBits(3, 2)); 180 shouldThrow(cereal.writeBits(5, 2)); 181 } 182 183 void testEncodeTwoBytesBits() { 184 auto cereal = Cerealiser(); 185 immutable uint value = 5; 186 cereal.writeBits(3, 4); 187 cereal.writeBits(1, 1); 188 cereal.writeBits(2, 2); 189 cereal.writeBits(0, 1); 190 cereal.writeBits(5, 8); 191 cereal.bytes.shouldEqual([0x3c, 0x05]); 192 } 193 194 195 void testCerealise() { 196 cerealise(4).shouldEqual([0, 0, 0, 4]); 197 cerealize("foo").shouldEqual([0, 3, 'f', 'o', 'o']); 198 }