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(readF1000(is) == 53.534f);
300 UASSERT(readF1000(is) == -300000.32f);
301 UASSERT(readF1000(is) == F1000_MIN);
302 UASSERT(readF1000(is) == F1000_MAX);
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));
310 UASSERT(readV2F1000(is) == v2f(500.656f, 350.345f));
312 UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455");
314 UASSERT(readV3F1000(is) == v3f(500, 10024.2f, -192.54f));
315 UASSERT(readARGB8(is) == video::SColor(255, 128, 50, 128));
317 UASSERT(deSerializeLongString(is) == "some longer string here");
319 UASSERT(is.rdbuf()->in_avail() == 2);
320 UASSERT(readU16(is) == 0xF00D);
321 UASSERT(is.rdbuf()->in_avail() == 0);
325 void TestSerialization::testStreamWrite()
327 std::ostringstream os(std::ios_base::binary);
331 writeU16(os, 0x2233);
332 writeU32(os, 0x44556677);
333 writeU64(os, 0x8899AABBCCDDEEFF);
340 writeF1000(os, 53.53467f);
341 writeF1000(os, -300000.32f);
342 writeF1000(os, F1000_MIN);
343 writeF1000(os, F1000_MAX);
345 os << serializeString("foobar!");
348 UASSERT(data.size() < sizeof(test_serialized_data));
349 UASSERT(!memcmp(&data[0], test_serialized_data, data.size()));
351 writeV2S16(os, v2s16(500, 500));
352 writeV3S16(os, v3s16(4207, 604, -30));
353 writeV2S32(os, v2s32(1920, 1080));
354 writeV3S32(os, v3s32(-400, 6400054, 290549855));
355 writeV2F1000(os, v2f(500.65661f, 350.34567f));
357 os << serializeWideString(L"\x02~woof~\x5455");
359 writeV3F1000(os, v3f(500, 10024.2f, -192.54f));
360 writeARGB8(os, video::SColor(255, 128, 50, 128));
362 os << serializeLongString("some longer string here");
364 writeU16(os, 0xF00D);
367 UASSERT(data.size() == sizeof(test_serialized_data));
368 UASSERT(!memcmp(&data[0], test_serialized_data, sizeof(test_serialized_data)));
372 const u8 TestSerialization::test_serialized_data[12 * 13] = {
373 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
374 0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff,
375 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e,
376 0x5b, 0xc0, 0x80, 0x00, 0x02, 0x80, 0x7F, 0xFF, 0xFD, 0x80, 0x00, 0x07,
377 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10,
378 0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04,
379 0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70,
380 0x5f, 0x00, 0x07, 0xa3, 0xb0, 0x00, 0x05, 0x58, 0x89, 0x00, 0x08, 0x00,
381 0x02, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x66, 0x00,
382 0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff,
383 0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73,
384 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73,
385 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0xF0, 0x0D,