+#define UTEST(x, fmt, ...)\
+{\
+ if(!(x)){\
+ LOGLINEF(LMT_ERROR, "Test (%s) failed: " fmt, #x, ##__VA_ARGS__);\
+ test_failed = true;\
+ }\
+}
+
+#define UASSERT(x) UTEST(x, "UASSERT")
+
+/*
+ A few item and node definitions for those tests that need them
+*/
+
+static content_t CONTENT_STONE;
+static content_t CONTENT_GRASS;
+static content_t CONTENT_TORCH;
+
+void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *ndef)
+{
+ ItemDefinition itemdef;
+ ContentFeatures f;
+
+ /*
+ Stone
+ */
+ itemdef = ItemDefinition();
+ itemdef.type = ITEM_NODE;
+ itemdef.name = "default:stone";
+ itemdef.description = "Stone";
+ itemdef.groups["cracky"] = 3;
+ itemdef.inventory_image = "[inventorycube"
+ "{default_stone.png"
+ "{default_stone.png"
+ "{default_stone.png";
+ f = ContentFeatures();
+ f.name = itemdef.name;
+ for(int i = 0; i < 6; i++)
+ f.tiledef[i].name = "default_stone.png";
+ f.is_ground_content = true;
+ idef->registerItem(itemdef);
+ CONTENT_STONE = ndef->set(f.name, f);
+
+ /*
+ Grass
+ */
+ itemdef = ItemDefinition();
+ itemdef.type = ITEM_NODE;
+ itemdef.name = "default:dirt_with_grass";
+ itemdef.description = "Dirt with grass";
+ itemdef.groups["crumbly"] = 3;
+ itemdef.inventory_image = "[inventorycube"
+ "{default_grass.png"
+ "{default_dirt.png&default_grass_side.png"
+ "{default_dirt.png&default_grass_side.png";
+ f = ContentFeatures();
+ f.name = itemdef.name;
+ f.tiledef[0].name = "default_grass.png";
+ f.tiledef[1].name = "default_dirt.png";
+ for(int i = 2; i < 6; i++)
+ f.tiledef[i].name = "default_dirt.png^default_grass_side.png";
+ f.is_ground_content = true;
+ idef->registerItem(itemdef);
+ CONTENT_GRASS = ndef->set(f.name, f);
+
+ /*
+ Torch (minimal definition for lighting tests)
+ */
+ itemdef = ItemDefinition();
+ itemdef.type = ITEM_NODE;
+ itemdef.name = "default:torch";
+ f = ContentFeatures();
+ f.name = itemdef.name;
+ f.param_type = CPT_LIGHT;
+ f.light_propagates = true;
+ f.sunlight_propagates = true;
+ f.light_source = LIGHT_MAX-1;
+ idef->registerItem(itemdef);
+ CONTENT_TORCH = ndef->set(f.name, f);
+}
+
+struct TestBase
+{
+ bool test_failed;
+ TestBase():
+ test_failed(false)
+ {}
+};
+
+struct TestUtilities: public TestBase
+{
+ void Run()
+ {
+ /*infostream<<"wrapDegrees(100.0) = "<<wrapDegrees(100.0)<<std::endl;
+ infostream<<"wrapDegrees(720.5) = "<<wrapDegrees(720.5)<<std::endl;
+ infostream<<"wrapDegrees(-0.5) = "<<wrapDegrees(-0.5)<<std::endl;*/
+ UASSERT(fabs(wrapDegrees(100.0) - 100.0) < 0.001);
+ UASSERT(fabs(wrapDegrees(720.5) - 0.5) < 0.001);
+ UASSERT(fabs(wrapDegrees(-0.5) - (-0.5)) < 0.001);
+ UASSERT(fabs(wrapDegrees(-365.5) - (-5.5)) < 0.001);
+ UASSERT(lowercase("Foo bAR") == "foo bar");
+ UASSERT(trim("\n \t\r Foo bAR \r\n\t\t ") == "Foo bAR");
+ UASSERT(trim("\n \t\r \r\n\t\t ") == "");
+ UASSERT(is_yes("YeS") == true);
+ UASSERT(is_yes("") == false);
+ UASSERT(is_yes("FAlse") == false);
+ UASSERT(is_yes("-1") == true);
+ UASSERT(is_yes("0") == false);
+ UASSERT(is_yes("1") == true);
+ UASSERT(is_yes("2") == true);
+ const char *ends[] = {"abc", "c", "bc", "", NULL};
+ UASSERT(removeStringEnd("abc", ends) == "");
+ UASSERT(removeStringEnd("bc", ends) == "b");
+ UASSERT(removeStringEnd("12c", ends) == "12");
+ UASSERT(removeStringEnd("foo", ends) == "");
+ UASSERT(urlencode("\"Aardvarks lurk, OK?\"")
+ == "%22Aardvarks%20lurk%2C%20OK%3F%22");
+ UASSERT(urldecode("%22Aardvarks%20lurk%2C%20OK%3F%22")
+ == "\"Aardvarks lurk, OK?\"");
+ UASSERT(padStringRight("hello", 8) == "hello ");
+ UASSERT(str_equal(narrow_to_wide("abc"), narrow_to_wide("abc")));
+ UASSERT(str_equal(narrow_to_wide("ABC"), narrow_to_wide("abc"), true));
+ UASSERT(trim(" a") == "a");
+ UASSERT(trim(" a ") == "a");
+ UASSERT(trim("a ") == "a");
+ UASSERT(trim("") == "");
+ UASSERT(mystoi("123", 0, 1000) == 123);
+ UASSERT(mystoi("123", 0, 10) == 10);
+ std::string test_str;
+ test_str = "Hello there";
+ str_replace(test_str, "there", "world");
+ UASSERT(test_str == "Hello world");
+ test_str = "ThisAisAaAtest";
+ str_replace_char(test_str, 'A', ' ');
+ UASSERT(test_str == "This is a test");
+ UASSERT(string_allowed("hello", "abcdefghijklmno") == true);
+ UASSERT(string_allowed("123", "abcdefghijklmno") == false);
+ UASSERT(string_allowed_blacklist("hello", "123") == true);
+ UASSERT(string_allowed_blacklist("hello123", "123") == false);
+ UASSERT(wrap_rows("12345678",4) == "1234\n5678");
+ UASSERT(is_number("123") == true);
+ UASSERT(is_number("") == false);
+ UASSERT(is_number("123a") == false);
+ UASSERT(is_power_of_two(0) == false);
+ UASSERT(is_power_of_two(1) == true);
+ UASSERT(is_power_of_two(2) == true);
+ UASSERT(is_power_of_two(3) == false);
+ for (int exponent = 2; exponent <= 31; ++exponent) {
+ UASSERT(is_power_of_two((1 << exponent) - 1) == false);
+ UASSERT(is_power_of_two((1 << exponent)) == true);
+ UASSERT(is_power_of_two((1 << exponent) + 1) == false);
+ }
+ UASSERT(is_power_of_two((u32)-1) == false);
+ }
+};
+
+struct TestPath: public TestBase
+{
+ // adjusts a POSIX path to system-specific conventions
+ // -> changes '/' to DIR_DELIM
+ // -> absolute paths start with "C:\\" on windows
+ std::string p(std::string path)
+ {
+ for(size_t i = 0; i < path.size(); ++i){
+ if(path[i] == '/'){
+ path.replace(i, 1, DIR_DELIM);
+ i += std::string(DIR_DELIM).size() - 1; // generally a no-op
+ }
+ }
+
+ #ifdef _WIN32
+ if(path[0] == '\\')
+ path = "C:" + path;
+ #endif
+
+ return path;
+ }
+
+ void Run()
+ {
+ std::string path, result, removed;
+
+ /*
+ Test fs::IsDirDelimiter
+ */
+ UASSERT(fs::IsDirDelimiter('/') == true);
+ UASSERT(fs::IsDirDelimiter('A') == false);
+ UASSERT(fs::IsDirDelimiter(0) == false);
+ #ifdef _WIN32
+ UASSERT(fs::IsDirDelimiter('\\') == true);
+ #else
+ UASSERT(fs::IsDirDelimiter('\\') == false);
+ #endif
+
+ /*
+ Test fs::PathStartsWith
+ */
+ {
+ const int numpaths = 12;
+ std::string paths[numpaths] = {
+ "",
+ p("/"),
+ p("/home/user/minetest"),
+ p("/home/user/minetest/bin"),
+ p("/home/user/.minetest"),
+ p("/tmp/dir/file"),
+ p("/tmp/file/"),
+ p("/tmP/file"),
+ p("/tmp"),
+ p("/tmp/dir"),
+ p("/home/user2/minetest/worlds"),
+ p("/home/user2/minetest/world"),
+ };
+ /*
+ expected fs::PathStartsWith results
+ 0 = returns false
+ 1 = returns true
+ 2 = returns false on windows, false elsewhere
+ 3 = returns true on windows, true elsewhere
+ 4 = returns true if and only if
+ FILESYS_CASE_INSENSITIVE is true
+ */
+ int expected_results[numpaths][numpaths] = {
+ {1,2,0,0,0,0,0,0,0,0,0,0},
+ {1,1,0,0,0,0,0,0,0,0,0,0},
+ {1,1,1,0,0,0,0,0,0,0,0,0},
+ {1,1,1,1,0,0,0,0,0,0,0,0},
+ {1,1,0,0,1,0,0,0,0,0,0,0},
+ {1,1,0,0,0,1,0,0,1,1,0,0},
+ {1,1,0,0,0,0,1,4,1,0,0,0},
+ {1,1,0,0,0,0,4,1,4,0,0,0},
+ {1,1,0,0,0,0,0,0,1,0,0,0},
+ {1,1,0,0,0,0,0,0,1,1,0,0},
+ {1,1,0,0,0,0,0,0,0,0,1,0},
+ {1,1,0,0,0,0,0,0,0,0,0,1},
+ };
+
+ for (int i = 0; i < numpaths; i++)
+ for (int j = 0; j < numpaths; j++){
+ /*verbosestream<<"testing fs::PathStartsWith(\""
+ <<paths[i]<<"\", \""
+ <<paths[j]<<"\")"<<std::endl;*/
+ bool starts = fs::PathStartsWith(paths[i], paths[j]);
+ int expected = expected_results[i][j];
+ if(expected == 0){
+ UASSERT(starts == false);
+ }
+ else if(expected == 1){
+ UASSERT(starts == true);
+ }
+ #ifdef _WIN32
+ else if(expected == 2){
+ UASSERT(starts == false);
+ }
+ else if(expected == 3){
+ UASSERT(starts == true);
+ }
+ #else
+ else if(expected == 2){
+ UASSERT(starts == true);
+ }
+ else if(expected == 3){
+ UASSERT(starts == false);
+ }
+ #endif
+ else if(expected == 4){
+ UASSERT(starts == (bool)FILESYS_CASE_INSENSITIVE);
+ }
+ }
+ }
+
+ /*
+ Test fs::RemoveLastPathComponent
+ */
+ UASSERT(fs::RemoveLastPathComponent("") == "");
+ path = p("/home/user/minetest/bin/..//worlds/world1");
+ result = fs::RemoveLastPathComponent(path, &removed, 0);
+ UASSERT(result == path);
+ UASSERT(removed == "");
+ result = fs::RemoveLastPathComponent(path, &removed, 1);
+ UASSERT(result == p("/home/user/minetest/bin/..//worlds"));
+ UASSERT(removed == p("world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 2);
+ UASSERT(result == p("/home/user/minetest/bin/.."));
+ UASSERT(removed == p("worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 3);
+ UASSERT(result == p("/home/user/minetest/bin"));
+ UASSERT(removed == p("../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 4);
+ UASSERT(result == p("/home/user/minetest"));
+ UASSERT(removed == p("bin/../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 5);
+ UASSERT(result == p("/home/user"));
+ UASSERT(removed == p("minetest/bin/../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 6);
+ UASSERT(result == p("/home"));
+ UASSERT(removed == p("user/minetest/bin/../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 7);
+ #ifdef _WIN32
+ UASSERT(result == "C:");
+ #else
+ UASSERT(result == "");
+ #endif
+ UASSERT(removed == p("home/user/minetest/bin/../worlds/world1"));
+
+ /*
+ Now repeat the test with a trailing delimiter
+ */
+ path = p("/home/user/minetest/bin/..//worlds/world1/");
+ result = fs::RemoveLastPathComponent(path, &removed, 0);
+ UASSERT(result == path);
+ UASSERT(removed == "");
+ result = fs::RemoveLastPathComponent(path, &removed, 1);
+ UASSERT(result == p("/home/user/minetest/bin/..//worlds"));
+ UASSERT(removed == p("world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 2);
+ UASSERT(result == p("/home/user/minetest/bin/.."));
+ UASSERT(removed == p("worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 3);
+ UASSERT(result == p("/home/user/minetest/bin"));
+ UASSERT(removed == p("../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 4);
+ UASSERT(result == p("/home/user/minetest"));
+ UASSERT(removed == p("bin/../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 5);
+ UASSERT(result == p("/home/user"));
+ UASSERT(removed == p("minetest/bin/../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 6);
+ UASSERT(result == p("/home"));
+ UASSERT(removed == p("user/minetest/bin/../worlds/world1"));
+ result = fs::RemoveLastPathComponent(path, &removed, 7);
+ #ifdef _WIN32
+ UASSERT(result == "C:");
+ #else
+ UASSERT(result == "");
+ #endif
+ UASSERT(removed == p("home/user/minetest/bin/../worlds/world1"));
+
+ /*
+ Test fs::RemoveRelativePathComponent
+ */
+ path = p("/home/user/minetest/bin");
+ result = fs::RemoveRelativePathComponents(path);
+ UASSERT(result == path);
+ path = p("/home/user/minetest/bin/../worlds/world1");
+ result = fs::RemoveRelativePathComponents(path);
+ UASSERT(result == p("/home/user/minetest/worlds/world1"));
+ path = p("/home/user/minetest/bin/../worlds/world1/");
+ result = fs::RemoveRelativePathComponents(path);
+ UASSERT(result == p("/home/user/minetest/worlds/world1"));
+ path = p(".");
+ result = fs::RemoveRelativePathComponents(path);
+ UASSERT(result == "");
+ path = p("./subdir/../..");
+ result = fs::RemoveRelativePathComponents(path);
+ UASSERT(result == "");
+ path = p("/a/b/c/.././../d/../e/f/g/../h/i/j/../../../..");
+ result = fs::RemoveRelativePathComponents(path);
+ UASSERT(result == p("/a/e"));
+ }
+};
+
+#define TEST_CONFIG_TEXT_BEFORE \
+ "leet = 1337\n" \
+ "leetleet = 13371337\n" \
+ "leetleet_neg = -13371337\n" \
+ "floaty_thing = 1.1\n" \
+ "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n" \
+ "coord = (1, 2, 4.5)\n" \
+ " # this is just a comment\n" \
+ "this is an invalid line\n" \
+ "asdf = {\n" \
+ " a = 5\n" \
+ " bb = 2.5\n" \
+ " ccc = \"\"\"\n" \
+ "testy\n" \
+ " testa \n" \
+ "\"\"\"\n" \
+ "\n" \
+ "}\n" \
+ "blarg = \"\"\" \n" \
+ "some multiline text\n" \
+ " with leading whitespace!\n" \
+ "\"\"\"\n" \
+ "np_terrain = 5, 40, (250, 250, 250), 12341, 5, 0.7, 2.4\n" \
+ "zoop = true"
+
+#define TEST_CONFIG_TEXT_AFTER \
+ "leet = 1337\n" \
+ "leetleet = 13371337\n" \
+ "leetleet_neg = -13371337\n" \
+ "floaty_thing = 1.1\n" \
+ "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n" \
+ "coord = (1, 2, 4.5)\n" \
+ " # this is just a comment\n" \
+ "this is an invalid line\n" \
+ "asdf = {\n" \
+ " a = 5\n" \
+ " bb = 2.5\n" \
+ " ccc = \"\"\"\n" \
+ "testy\n" \
+ " testa \n" \
+ "\"\"\"\n" \
+ "\n" \
+ "}\n" \
+ "blarg = \"\"\" \n" \
+ "some multiline text\n" \
+ " with leading whitespace!\n" \
+ "\"\"\"\n" \
+ "np_terrain = {\n" \
+ " flags = defaults\n" \
+ " lacunarity = 2.4\n" \
+ " octaves = 6\n" \
+ " offset = 3.5\n" \
+ " persistence = 0.7\n" \
+ " scale = 40\n" \
+ " seed = 12341\n" \
+ " spread = (250,250,250)\n" \
+ "}\n" \
+ "zoop = true\n" \
+ "coord2 = (1,2,3.3)\n" \
+ "floaty_thing_2 = 1.2\n" \
+ "groupy_thing = {\n" \
+ " animals = cute\n" \
+ " num_apples = 4\n" \
+ " num_oranges = 53\n" \
+ "}\n"
+
+struct TestSettings: public TestBase
+{
+ void Run()
+ {
+ try {
+ Settings s;
+
+ // Test reading of settings
+ std::istringstream is(TEST_CONFIG_TEXT_BEFORE);
+ s.parseConfigLines(is);
+
+ UASSERT(s.getS32("leet") == 1337);
+ UASSERT(s.getS16("leetleet") == 32767);
+ UASSERT(s.getS16("leetleet_neg") == -32768);
+
+ // Not sure if 1.1 is an exact value as a float, but doesn't matter
+ UASSERT(fabs(s.getFloat("floaty_thing") - 1.1) < 0.001);
+ UASSERT(s.get("stringy_thing") == "asd /( ¤%&(/\" BLÖÄRP");
+ UASSERT(fabs(s.getV3F("coord").X - 1.0) < 0.001);
+ UASSERT(fabs(s.getV3F("coord").Y - 2.0) < 0.001);
+ UASSERT(fabs(s.getV3F("coord").Z - 4.5) < 0.001);
+
+ // Test the setting of settings too
+ s.setFloat("floaty_thing_2", 1.2);
+ s.setV3F("coord2", v3f(1, 2, 3.3));
+ UASSERT(s.get("floaty_thing_2").substr(0,3) == "1.2");
+ UASSERT(fabs(s.getFloat("floaty_thing_2") - 1.2) < 0.001);
+ UASSERT(fabs(s.getV3F("coord2").X - 1.0) < 0.001);
+ UASSERT(fabs(s.getV3F("coord2").Y - 2.0) < 0.001);
+ UASSERT(fabs(s.getV3F("coord2").Z - 3.3) < 0.001);
+
+ // Test settings groups
+ Settings *group = s.getGroup("asdf");
+ UASSERT(group != NULL);
+ UASSERT(s.getGroupNoEx("zoop", group) == false);
+ UASSERT(group->getS16("a") == 5);
+ UASSERT(fabs(group->getFloat("bb") - 2.5) < 0.001);
+
+ Settings *group3 = new Settings;
+ group3->set("cat", "meow");
+ group3->set("dog", "woof");
+
+ Settings *group2 = new Settings;
+ group2->setS16("num_apples", 4);
+ group2->setS16("num_oranges", 53);
+ group2->setGroup("animals", group3);
+ group2->set("animals", "cute"); //destroys group 3
+ s.setGroup("groupy_thing", group2);
+
+ // Test set failure conditions
+ UASSERT(s.set("Zoop = Poop\nsome_other_setting", "false") == false);
+ UASSERT(s.set("sneaky", "\"\"\"\njabberwocky = false") == false);
+ UASSERT(s.set("hehe", "asdfasdf\n\"\"\"\nsomething = false") == false);
+
+ // Test multiline settings
+ UASSERT(group->get("ccc") == "testy\n testa ");
+
+ UASSERT(s.get("blarg") ==
+ "some multiline text\n"
+ " with leading whitespace!");
+
+ // Test NoiseParams
+ UASSERT(s.getEntry("np_terrain").is_group == false);
+
+ NoiseParams np;
+ UASSERT(s.getNoiseParams("np_terrain", np) == true);
+ UASSERT(fabs(np.offset - 5) < 0.001);
+ UASSERT(fabs(np.scale - 40) < 0.001);
+ UASSERT(fabs(np.spread.X - 250) < 0.001);
+ UASSERT(fabs(np.spread.Y - 250) < 0.001);
+ UASSERT(fabs(np.spread.Z - 250) < 0.001);
+ UASSERT(np.seed == 12341);
+ UASSERT(np.octaves == 5);
+ UASSERT(fabs(np.persist - 0.7) < 0.001);
+
+ np.offset = 3.5;
+ np.octaves = 6;
+ s.setNoiseParams("np_terrain", np);
+
+ UASSERT(s.getEntry("np_terrain").is_group == true);
+
+ // Test writing
+ std::ostringstream os(std::ios_base::binary);
+ is.clear();
+ is.seekg(0);
+
+ UASSERT(s.updateConfigObject(is, os, "", 0) == true);
+ //printf(">>>> expected config:\n%s\n", TEST_CONFIG_TEXT_AFTER);
+ //printf(">>>> actual config:\n%s\n", os.str().c_str());
+ UASSERT(os.str() == TEST_CONFIG_TEXT_AFTER);
+ } catch (SettingNotFoundException &e) {
+ UASSERT(!"Setting not found!");
+ }
+ }
+};
+
+struct TestSerialization: public TestBase
+{
+ // To be used like this:
+ // mkstr("Some\0string\0with\0embedded\0nuls")
+ // since std::string("...") doesn't work as expected in that case.
+ template<size_t N> std::string mkstr(const char (&s)[N])
+ {
+ return std::string(s, N - 1);
+ }
+
+ void Run()
+ {
+ // Tests some serialization primitives
+
+ UASSERT(serializeString("") == mkstr("\0\0"));
+ UASSERT(serializeWideString(L"") == mkstr("\0\0"));
+ UASSERT(serializeLongString("") == mkstr("\0\0\0\0"));
+ UASSERT(serializeJsonString("") == "\"\"");
+
+ std::string teststring = "Hello world!";
+ UASSERT(serializeString(teststring) ==
+ mkstr("\0\14Hello world!"));
+ UASSERT(serializeWideString(narrow_to_wide(teststring)) ==
+ mkstr("\0\14\0H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!"));
+ UASSERT(serializeLongString(teststring) ==
+ mkstr("\0\0\0\14Hello world!"));
+ UASSERT(serializeJsonString(teststring) ==
+ "\"Hello world!\"");
+
+ std::string teststring2;
+ std::wstring teststring2_w;
+ std::string teststring2_w_encoded;
+ {
+ std::ostringstream tmp_os;
+ std::wostringstream tmp_os_w;
+ std::ostringstream tmp_os_w_encoded;
+ for(int i = 0; i < 256; i++)
+ {
+ tmp_os<<(char)i;
+ tmp_os_w<<(wchar_t)i;
+ tmp_os_w_encoded<<(char)0<<(char)i;
+ }
+ teststring2 = tmp_os.str();
+ teststring2_w = tmp_os_w.str();
+ teststring2_w_encoded = tmp_os_w_encoded.str();
+ }
+ UASSERT(serializeString(teststring2) ==
+ mkstr("\1\0") + teststring2);
+ UASSERT(serializeWideString(teststring2_w) ==
+ mkstr("\1\0") + teststring2_w_encoded);
+ UASSERT(serializeLongString(teststring2) ==
+ mkstr("\0\0\1\0") + teststring2);
+ // MSVC fails when directly using "\\\\"
+ std::string backslash = "\\";
+ UASSERT(serializeJsonString(teststring2) ==
+ mkstr("\"") +
+ "\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007" +
+ "\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f" +
+ "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" +
+ "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f" +
+ " !\\\"" + teststring2.substr(0x23, 0x2f-0x23) +
+ "\\/" + teststring2.substr(0x30, 0x5c-0x30) +
+ backslash + backslash + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" +
+ "\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087" +
+ "\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f" +
+ "\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" +
+ "\\u0098\\u0099\\u009a\\u009b\\u009c\\u009d\\u009e\\u009f" +
+ "\\u00a0\\u00a1\\u00a2\\u00a3\\u00a4\\u00a5\\u00a6\\u00a7" +
+ "\\u00a8\\u00a9\\u00aa\\u00ab\\u00ac\\u00ad\\u00ae\\u00af" +
+ "\\u00b0\\u00b1\\u00b2\\u00b3\\u00b4\\u00b5\\u00b6\\u00b7" +
+ "\\u00b8\\u00b9\\u00ba\\u00bb\\u00bc\\u00bd\\u00be\\u00bf" +
+ "\\u00c0\\u00c1\\u00c2\\u00c3\\u00c4\\u00c5\\u00c6\\u00c7" +
+ "\\u00c8\\u00c9\\u00ca\\u00cb\\u00cc\\u00cd\\u00ce\\u00cf" +
+ "\\u00d0\\u00d1\\u00d2\\u00d3\\u00d4\\u00d5\\u00d6\\u00d7" +
+ "\\u00d8\\u00d9\\u00da\\u00db\\u00dc\\u00dd\\u00de\\u00df" +
+ "\\u00e0\\u00e1\\u00e2\\u00e3\\u00e4\\u00e5\\u00e6\\u00e7" +
+ "\\u00e8\\u00e9\\u00ea\\u00eb\\u00ec\\u00ed\\u00ee\\u00ef" +
+ "\\u00f0\\u00f1\\u00f2\\u00f3\\u00f4\\u00f5\\u00f6\\u00f7" +
+ "\\u00f8\\u00f9\\u00fa\\u00fb\\u00fc\\u00fd\\u00fe\\u00ff" +
+ "\"");
+
+ {
+ std::istringstream is(serializeString(teststring2), std::ios::binary);
+ UASSERT(deSerializeString(is) == teststring2);
+ UASSERT(!is.eof());
+ is.get();
+ UASSERT(is.eof());
+ }
+ {
+ std::istringstream is(serializeWideString(teststring2_w), std::ios::binary);
+ UASSERT(deSerializeWideString(is) == teststring2_w);
+ UASSERT(!is.eof());
+ is.get();
+ UASSERT(is.eof());
+ }
+ {
+ std::istringstream is(serializeLongString(teststring2), std::ios::binary);
+ UASSERT(deSerializeLongString(is) == teststring2);
+ UASSERT(!is.eof());
+ is.get();
+ UASSERT(is.eof());
+ }
+ {
+ std::istringstream is(serializeJsonString(teststring2), std::ios::binary);
+ //dstream<<serializeJsonString(deSerializeJsonString(is));
+ UASSERT(deSerializeJsonString(is) == teststring2);
+ UASSERT(!is.eof());
+ is.get();
+ UASSERT(is.eof());
+ }
+ }
+};
+
+struct TestNodedefSerialization: public TestBase