3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "util/string.h"
23 #include "util/serialize.h"
25 class TestSerialization : public TestBase {
27 TestSerialization() { TestManager::registerTestModule(this); }
28 const char *getName() { return "TestSerialization"; }
30 void runTests(IGameDef *gamedef);
31 void buildTestStrings();
33 void testSerializeString();
34 void testSerializeWideString();
35 void testSerializeLongString();
36 void testSerializeJsonString();
37 void testSerializeHex();
38 void testDeSerializeString();
39 void testDeSerializeWideString();
40 void testDeSerializeLongString();
41 void testStreamRead();
42 void testStreamWrite();
44 std::string teststring2;
45 std::wstring teststring2_w;
46 std::string teststring2_w_encoded;
48 static const u8 test_serialized_data[12 * 13];
51 static TestSerialization g_test_instance;
53 void TestSerialization::runTests(IGameDef *gamedef)
57 TEST(testSerializeString);
58 TEST(testDeSerializeString);
59 TEST(testSerializeWideString);
60 TEST(testDeSerializeWideString);
61 TEST(testSerializeLongString);
62 TEST(testDeSerializeLongString);
63 TEST(testSerializeJsonString);
64 TEST(testSerializeHex);
66 TEST(testStreamWrite);
69 ////////////////////////////////////////////////////////////////////////////////
71 // To be used like this:
72 // mkstr("Some\0string\0with\0embedded\0nuls")
73 // since std::string("...") doesn't work as expected in that case.
74 template<size_t N> std::string mkstr(const char (&s)[N])
76 return std::string(s, N - 1);
79 void TestSerialization::buildTestStrings()
81 std::ostringstream tmp_os;
82 std::wostringstream tmp_os_w;
83 std::ostringstream tmp_os_w_encoded;
84 for (int i = 0; i < 256; i++) {
86 tmp_os_w << (wchar_t)i;
87 tmp_os_w_encoded << (char)0 << (char)i;
89 teststring2 = tmp_os.str();
90 teststring2_w = tmp_os_w.str();
91 teststring2_w_encoded = tmp_os_w_encoded.str();
94 void TestSerialization::testSerializeString()
97 UASSERT(serializeString("") == mkstr("\0\0"));
100 UASSERT(serializeString("Hello world!") == mkstr("\0\14Hello world!"));
102 // Test character range
103 UASSERT(serializeString(teststring2) == mkstr("\1\0") + teststring2);
106 void TestSerialization::testDeSerializeString()
110 std::istringstream is(serializeString(teststring2), std::ios::binary);
111 UASSERT(deSerializeString(is) == teststring2);
117 // Test deserialize an incomplete length specifier
119 std::istringstream is(mkstr("\x53"), std::ios::binary);
120 EXCEPTION_CHECK(SerializationError, deSerializeString(is));
123 // Test deserialize a string with incomplete data
125 std::istringstream is(mkstr("\x00\x55 abcdefg"), std::ios::binary);
126 EXCEPTION_CHECK(SerializationError, deSerializeString(is));
130 void TestSerialization::testSerializeWideString()
133 UASSERT(serializeWideString(L"") == mkstr("\0\0"));
136 UASSERT(serializeWideString(utf8_to_wide("Hello world!")) ==
137 mkstr("\0\14\0H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!"));
139 // Test character range
140 UASSERT(serializeWideString(teststring2_w) ==
141 mkstr("\1\0") + teststring2_w_encoded);
144 void TestSerialization::testDeSerializeWideString()
148 std::istringstream is(serializeWideString(teststring2_w), std::ios::binary);
149 UASSERT(deSerializeWideString(is) == teststring2_w);
155 // Test deserialize an incomplete length specifier
157 std::istringstream is(mkstr("\x53"), std::ios::binary);
158 EXCEPTION_CHECK(SerializationError, deSerializeWideString(is));
161 // Test deserialize a string with an incomplete character
163 std::istringstream is(mkstr("\x00\x07\0a\0b\0c\0d\0e\0f\0"), std::ios::binary);
164 EXCEPTION_CHECK(SerializationError, deSerializeWideString(is));
167 // Test deserialize a string with incomplete data
169 std::istringstream is(mkstr("\x00\x08\0a\0b\0c\0d\0e\0f"), std::ios::binary);
170 EXCEPTION_CHECK(SerializationError, deSerializeWideString(is));
174 void TestSerialization::testSerializeLongString()
177 UASSERT(serializeLongString("") == mkstr("\0\0\0\0"));
180 UASSERT(serializeLongString("Hello world!") == mkstr("\0\0\0\14Hello world!"));
182 // Test character range
183 UASSERT(serializeLongString(teststring2) == mkstr("\0\0\1\0") + teststring2);
186 void TestSerialization::testDeSerializeLongString()
190 std::istringstream is(serializeLongString(teststring2), std::ios::binary);
191 UASSERT(deSerializeLongString(is) == teststring2);
197 // Test deserialize an incomplete length specifier
199 std::istringstream is(mkstr("\x53"), std::ios::binary);
200 EXCEPTION_CHECK(SerializationError, deSerializeLongString(is));
203 // Test deserialize a string with incomplete data
205 std::istringstream is(mkstr("\x00\x00\x00\x05 abc"), std::ios::binary);
206 EXCEPTION_CHECK(SerializationError, deSerializeLongString(is));
209 // Test deserialize a string with a length too large
211 std::istringstream is(mkstr("\xFF\xFF\xFF\xFF blah"), std::ios::binary);
212 EXCEPTION_CHECK(SerializationError, deSerializeLongString(is));
217 void TestSerialization::testSerializeJsonString()
220 UASSERT(serializeJsonString("") == "\"\"");
223 UASSERT(serializeJsonString("Hello world!") == "\"Hello world!\"");
225 // MSVC fails when directly using "\\\\"
226 std::string backslash = "\\";
227 UASSERT(serializeJsonString(teststring2) ==
229 "\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007" +
230 "\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f" +
231 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" +
232 "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f" +
233 " !\\\"" + teststring2.substr(0x23, 0x2f-0x23) +
234 "\\/" + teststring2.substr(0x30, 0x5c-0x30) +
235 backslash + backslash + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" +
236 "\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087" +
237 "\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f" +
238 "\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" +
239 "\\u0098\\u0099\\u009a\\u009b\\u009c\\u009d\\u009e\\u009f" +
240 "\\u00a0\\u00a1\\u00a2\\u00a3\\u00a4\\u00a5\\u00a6\\u00a7" +
241 "\\u00a8\\u00a9\\u00aa\\u00ab\\u00ac\\u00ad\\u00ae\\u00af" +
242 "\\u00b0\\u00b1\\u00b2\\u00b3\\u00b4\\u00b5\\u00b6\\u00b7" +
243 "\\u00b8\\u00b9\\u00ba\\u00bb\\u00bc\\u00bd\\u00be\\u00bf" +
244 "\\u00c0\\u00c1\\u00c2\\u00c3\\u00c4\\u00c5\\u00c6\\u00c7" +
245 "\\u00c8\\u00c9\\u00ca\\u00cb\\u00cc\\u00cd\\u00ce\\u00cf" +
246 "\\u00d0\\u00d1\\u00d2\\u00d3\\u00d4\\u00d5\\u00d6\\u00d7" +
247 "\\u00d8\\u00d9\\u00da\\u00db\\u00dc\\u00dd\\u00de\\u00df" +
248 "\\u00e0\\u00e1\\u00e2\\u00e3\\u00e4\\u00e5\\u00e6\\u00e7" +
249 "\\u00e8\\u00e9\\u00ea\\u00eb\\u00ec\\u00ed\\u00ee\\u00ef" +
250 "\\u00f0\\u00f1\\u00f2\\u00f3\\u00f4\\u00f5\\u00f6\\u00f7" +
251 "\\u00f8\\u00f9\\u00fa\\u00fb\\u00fc\\u00fd\\u00fe\\u00ff" +
255 std::istringstream is(serializeJsonString(teststring2), std::ios::binary);
256 UASSERT(deSerializeJsonString(is) == teststring2);
262 void TestSerialization::testSerializeHex()
265 UASSERT(serializeHexString("") == "");
266 UASSERT(serializeHexString("", true) == "");
269 UASSERT(serializeHexString("Hello world!") ==
270 "48656c6c6f20776f726c6421");
271 UASSERT(serializeHexString("Hello world!", true) ==
272 "48 65 6c 6c 6f 20 77 6f 72 6c 64 21");
274 // Test binary string
275 UASSERT(serializeHexString(mkstr("\x00\x0a\xb0\x63\x1f\x00\xff")) ==
277 UASSERT(serializeHexString(mkstr("\x00\x0a\xb0\x63\x1f\x00\xff"), true) ==
278 "00 0a b0 63 1f 00 ff");
282 void TestSerialization::testStreamRead()
285 (const char *)test_serialized_data,
286 sizeof(test_serialized_data));
287 std::istringstream is(datastr, std::ios_base::binary);
289 UASSERT(readU8(is) == 0x11);
290 UASSERT(readU16(is) == 0x2233);
291 UASSERT(readU32(is) == 0x44556677);
292 UASSERT(readU64(is) == 0x8899AABBCCDDEEFF);
294 UASSERT(readS8(is) == -128);
295 UASSERT(readS16(is) == 30000);
296 UASSERT(readS32(is) == -6);
297 UASSERT(readS64(is) == -43);
299 UASSERT(fabs(readF1000(is) - 53.534f) < 0.005);
300 UASSERT(fabs(readF1000(is) - -300000.32f) < 0.05);
301 UASSERT(fabs(readF1000(is) - -2147483.f) < 0.05);
302 UASSERT(fabs(readF1000(is) - 2147483.f) < 0.05);
304 UASSERT(deSerializeString(is) == "foobar!");
306 UASSERT(readV2S16(is) == v2s16(500, 500));
307 UASSERT(readV3S16(is) == v3s16(4207, 604, -30));
308 UASSERT(readV2S32(is) == v2s32(1920, 1080));
309 UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855));
311 v2f vec2 = readV2F1000(is);
312 UASSERT(fabs(vec2.X - 500.656f) < 0.005);
313 UASSERT(fabs(vec2.Y - 350.345f) < 0.005);
315 UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455");
317 v3f vec3 = readV3F1000(is);
318 UASSERT(fabs(vec3.X - 500.f) < 0.005);
319 UASSERT(fabs(vec3.Y - 10024.2f) < 0.005);
320 UASSERT(fabs(vec3.Z - -192.54f) < 0.005);
322 UASSERT(readARGB8(is) == video::SColor(255, 128, 50, 128));
324 UASSERT(deSerializeLongString(is) == "some longer string here");
326 UASSERT(is.rdbuf()->in_avail() == 2);
327 UASSERT(readU16(is) == 0xF00D);
328 UASSERT(is.rdbuf()->in_avail() == 0);
332 void TestSerialization::testStreamWrite()
334 std::ostringstream os(std::ios_base::binary);
338 writeU16(os, 0x2233);
339 writeU32(os, 0x44556677);
340 writeU64(os, 0x8899AABBCCDDEEFF);
347 writeF1000(os, 53.53467f);
348 writeF1000(os, -300000.32f);
349 writeF1000(os, -2147483.f);
350 writeF1000(os, 2147483.f);
352 os << serializeString("foobar!");
355 UASSERT(data.size() < sizeof(test_serialized_data));
356 UASSERT(!memcmp(&data[0], test_serialized_data, data.size()));
358 writeV2S16(os, v2s16(500, 500));
359 writeV3S16(os, v3s16(4207, 604, -30));
360 writeV2S32(os, v2s32(1920, 1080));
361 writeV3S32(os, v3s32(-400, 6400054, 290549855));
362 writeV2F1000(os, v2f(500.65661f, 350.34567f));
364 os << serializeWideString(L"\x02~woof~\x5455");
366 writeV3F1000(os, v3f(500, 10024.2f, -192.54f));
367 writeARGB8(os, video::SColor(255, 128, 50, 128));
369 os << serializeLongString("some longer string here");
371 writeU16(os, 0xF00D);
374 UASSERT(data.size() == sizeof(test_serialized_data));
375 UASSERT(!memcmp(&data[0], test_serialized_data, sizeof(test_serialized_data)));
379 const u8 TestSerialization::test_serialized_data[12 * 13] = {
380 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
381 0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff,
382 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e,
383 0x5b, 0xc0, 0x80, 0x00, 0x02, 0x80, 0x7F, 0xFF, 0xFD, 0x80, 0x00, 0x07,
384 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10,
385 0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04,
386 0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70,
387 0x5f, 0x00, 0x07, 0xa3, 0xb0, 0x00, 0x05, 0x58, 0x89, 0x00, 0x08, 0x00,
388 0x02, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x66, 0x00,
389 0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff,
390 0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73,
391 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73,
392 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0xF0, 0x0D,