summaryrefslogtreecommitdiff
path: root/src/unittests
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2017-07-07 17:05:13 +0300
committerAndrei Karas <akaras@inbox.ru>2017-07-07 17:53:24 +0300
commit130f07fd84bfdf781eb42903b3fcbabc26199a3a (patch)
treee4e560c32177e0a64867c5d1584d9bf64b57bbce /src/unittests
parent9bbd191307c97c7589f93a64a4eb9abf3f11c46b (diff)
downloadmv-130f07fd84bfdf781eb42903b3fcbabc26199a3a.tar.gz
mv-130f07fd84bfdf781eb42903b3fcbabc26199a3a.tar.bz2
mv-130f07fd84bfdf781eb42903b3fcbabc26199a3a.tar.xz
mv-130f07fd84bfdf781eb42903b3fcbabc26199a3a.zip
Move unit tests into unittests directory.
Diffstat (limited to 'src/unittests')
-rw-r--r--src/unittests/configuration_unittest.cc305
-rw-r--r--src/unittests/enums/enums_unittest.cc35
-rw-r--r--src/unittests/enums/render/mockdrawtype.h35
-rw-r--r--src/unittests/fs/files_unittest.cc232
-rw-r--r--src/unittests/fs/virtfs/virtfs1_unittest.cc3507
-rw-r--r--src/unittests/fs/virtfs/virtfs_unittest.cc1054
-rw-r--r--src/unittests/fs/virtfs/zip_unittest.cc304
-rw-r--r--src/unittests/gui/fonts/textchunklist_unittest.cc548
-rw-r--r--src/unittests/gui/widgets/browserbox_unittest.cc211
-rw-r--r--src/unittests/gui/windowmanager_unittest.cc984
-rw-r--r--src/unittests/integrity_unittest.cc366
-rw-r--r--src/unittests/render/mockdrawitem.h60
-rw-r--r--src/unittests/render/mockgraphics.cc301
-rw-r--r--src/unittests/render/mockgraphics.h55
-rw-r--r--src/unittests/resources/dye/dye_unittest.cc2020
-rw-r--r--src/unittests/resources/dye/dyepalette_unittest.cc422
-rw-r--r--src/unittests/resources/map/maplayer_unittest.cc3213
-rw-r--r--src/unittests/resources/map/speciallayer_unittest.cc291
-rw-r--r--src/unittests/resources/mstack_unittest.cc165
-rw-r--r--src/unittests/resources/resourcemanager/resourcemanager_unittest.cc701
-rw-r--r--src/unittests/resources/sdlimagehelper_unittest.cc541
-rw-r--r--src/unittests/resources/sprite/animatedsprite_unittest.cc220
-rw-r--r--src/unittests/unittests.h52
-rw-r--r--src/unittests/utils/chatutils_unittest.cc287
-rw-r--r--src/unittests/utils/checkutils_unittest.cc179
-rw-r--r--src/unittests/utils/dumplibs_unittest.cc145
-rw-r--r--src/unittests/utils/langs_unittest.cc115
-rw-r--r--src/unittests/utils/mathutils_unittest.cc102
-rw-r--r--src/unittests/utils/parameters_unittest.cc327
-rw-r--r--src/unittests/utils/stringutils_unittest.cc1724
-rw-r--r--src/unittests/utils/timer_unittest.cc88
-rw-r--r--src/unittests/utils/translation/poparser_unittest.cc158
-rw-r--r--src/unittests/utils/xml_unittest.cc400
-rw-r--r--src/unittests/utils/xmlutils_unittest.cc203
34 files changed, 19350 insertions, 0 deletions
diff --git a/src/unittests/configuration_unittest.cc b/src/unittests/configuration_unittest.cc
new file mode 100644
index 000000000..58073bbdb
--- /dev/null
+++ b/src/unittests/configuration_unittest.cc
@@ -0,0 +1,305 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "configuration.h"
+#include "configmanager.h"
+#include "dirs.h"
+#include "logger.h"
+
+#include "listeners/configlistener.h"
+
+#include "utils/delete2.h"
+
+#include "debug.h"
+
+namespace
+{
+ int mCalled = 0;
+
+ class TestConfigListener : public ConfigListener
+ {
+ public:
+ void optionChanged(const std::string &name) override final
+ {
+ if (name == "testkey123")
+ mCalled ++;
+ }
+ } testListener;
+} // namespace
+
+TEST_CASE("configuration tests", "configuration")
+{
+ logger = new Logger();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+
+ SECTION("configuration undefined")
+ {
+ const char *const key = "nonsetvalue";
+ REQUIRE(config.getValue(key, "not set") == "not set");
+ REQUIRE(config.getValue(key, 12345) == 12345);
+ REQUIRE(config.getValue(key, 12345U) == 12345U);
+ REQUIRE(config.getValueInt(key, 12345) == 12345);
+ REQUIRE(config.getValueBool(key, false) == false);
+ REQUIRE(config.getValueBool(key, true) == true);
+ REQUIRE(config.getValue(key, -12345) == -12345);
+ REQUIRE(config.getValue(key, 12.345) > 12.3);
+
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key).empty());
+ REQUIRE(config.getBoolValue(key) == false);
+ }
+
+ SECTION("configuration getint default")
+ {
+ const char *const key = "sfxVolume";
+ REQUIRE(config.getIntValue(key) == 100);
+ REQUIRE(config.getFloatValue(key) >= 100.0f);
+ REQUIRE(config.getStringValue(key) == "100");
+ REQUIRE(config.getBoolValue(key) == true);
+ }
+
+ SECTION("configuration getfloat default")
+ {
+ const char *const key = "guialpha";
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.8f);
+ REQUIRE(config.getStringValue(key).substr(0, 3) == "0.8");
+ REQUIRE(config.getBoolValue(key) == false);
+ }
+
+ SECTION("configuration getstring default")
+ {
+ const char *const key = "soundwhisper";
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key) == "newmessage");
+ REQUIRE(config.getBoolValue(key) == true);
+ }
+
+ SECTION("configuration getbool default1")
+ {
+ const char *const key = "showgender";
+ REQUIRE(config.getIntValue(key) == 1);
+ REQUIRE(config.getFloatValue(key) >= 1.0f);
+ REQUIRE(config.getStringValue(key) == "1");
+ REQUIRE(config.getBoolValue(key) == true);
+ }
+
+ SECTION("configuration getbool default2")
+ {
+ const char *const key = "showlevel";
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key) == "0");
+ REQUIRE(config.getBoolValue(key) == false);
+ }
+
+ SECTION("configuration getint set")
+ {
+ const char *const key = "sfxVolume";
+ config.setValue(key, 50);
+ REQUIRE(config.getIntValue(key) == 50);
+ REQUIRE(config.getFloatValue(key) >= 50.0f);
+ REQUIRE(config.getStringValue(key) == "50");
+ REQUIRE(config.getBoolValue(key) == true);
+
+ REQUIRE(config.getValue(key, "not set") == "50");
+ REQUIRE(config.getValue(key, 12345) == 50);
+ REQUIRE(config.getValue(key, 12345U) == 50U);
+ REQUIRE(config.getValueInt(key, 12345) == 50);
+ REQUIRE(config.getValueBool(key, false) == true);
+ REQUIRE(config.getValueBool(key, true) == true);
+ REQUIRE(config.getValue(key, -12345) == 50);
+ REQUIRE(config.getValue(key, 12.345) >= 50.0);
+ }
+
+ SECTION("configuration getfloat set")
+ {
+ const char *const key = "guialpha";
+ config.setValue(key, 50.5);
+ REQUIRE(config.getIntValue(key) == 50);
+ REQUIRE(config.getFloatValue(key) >= 50.4f);
+ REQUIRE(config.getStringValue(key).substr(0, 2) == "50");
+ REQUIRE(config.getBoolValue(key) == true);
+
+ REQUIRE(config.getValue(key, "not set").substr(0, 2) == "50");
+ REQUIRE(config.getValue(key, 12345) == 50);
+ REQUIRE(config.getValue(key, 12345U) == 50U);
+ REQUIRE(config.getValueInt(key, 12345) == 50);
+ REQUIRE(config.getValueBool(key, false) == true);
+ REQUIRE(config.getValueBool(key, true) == true);
+ REQUIRE(config.getValue(key, -12345) == 50);
+ REQUIRE(config.getValue(key, 12.345) >= 50.4);
+ }
+
+ SECTION("configuration getstring set")
+ {
+ const char *const key = "soundwhisper";
+ config.setValue(key, "test line");
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key) == "test line");
+ REQUIRE(config.getBoolValue(key) == false);
+
+ REQUIRE(config.getValue(key, "not set") == "test line");
+ REQUIRE(config.getValue(key, 12345) == 0);
+ REQUIRE(config.getValue(key, 12345U) == 0U);
+ REQUIRE(config.getValueInt(key, 12345) == 0);
+ REQUIRE(config.getValueBool(key, false) == false);
+ REQUIRE(config.getValueBool(key, true) == false);
+ REQUIRE(config.getValue(key, -12345) == 0);
+ REQUIRE(config.getValue(key, 12.345) >= 0.0);
+ }
+
+ SECTION("configuration getbool set1")
+ {
+ const char *const key = "showgender";
+ config.setValue(key, true);
+ REQUIRE(config.getIntValue(key) == 1);
+ REQUIRE(config.getFloatValue(key) >= 1.0f);
+ REQUIRE(config.getStringValue(key) == "1");
+ REQUIRE(config.getBoolValue(key) == true);
+
+ REQUIRE(config.getValue(key, "not set") == "1");
+ REQUIRE(config.getValue(key, 12345) == 1);
+ REQUIRE(config.getValue(key, 12345U) == 1U);
+ REQUIRE(config.getValueInt(key, 12345) == 1);
+ REQUIRE(config.getValueBool(key, false) == true);
+ REQUIRE(config.getValueBool(key, true) == true);
+ REQUIRE(config.getValue(key, -12345) == 1);
+ REQUIRE(config.getValue(key, 12.345) >= 1.0);
+ }
+
+ SECTION("configuration getbool set2")
+ {
+ const char *const key = "showgender";
+ config.setValue(key, false);
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key) == "0");
+ REQUIRE(config.getBoolValue(key) == false);
+
+ REQUIRE(config.getValue(key, "not set") == "0");
+ REQUIRE(config.getValue(key, 12345) == 0);
+ REQUIRE(config.getValue(key, 12345U) == 0U);
+ REQUIRE(config.getValueInt(key, 12345) == 0);
+ REQUIRE(config.getValueBool(key, false) == false);
+ REQUIRE(config.getValueBool(key, true) == false);
+ REQUIRE(config.getValue(key, -12345) == 0);
+ REQUIRE(config.getValue(key, 12.345) >= 0.0);
+ }
+
+ SECTION("configuration deletekey")
+ {
+ const char *const key = "testkey123";
+ config.setValue(key, 123);
+ REQUIRE(config.getValueInt(key, 12345) == 123);
+ config.deleteKey(key);
+ REQUIRE(config.getValueInt(key, 12345) == 12345);
+ }
+
+ SECTION("configuration addlistener")
+ {
+ const char *const key = "testkey123";
+ REQUIRE(mCalled == 0);
+ config.addListener(key, &testListener);
+ REQUIRE(mCalled == 0);
+ config.setValue(key, 123);
+ REQUIRE(mCalled == 1);
+ REQUIRE(config.getValueInt(key, 12345) == 123);
+ REQUIRE(mCalled == 1);
+ config.setValue(key, 123);
+ REQUIRE(mCalled == 2);
+ config.setSilent(key, true);
+ REQUIRE(mCalled == 2);
+ REQUIRE(config.getBoolValue(key) == true);
+ REQUIRE(mCalled == 2);
+ config.setSilent(key, false);
+ REQUIRE(mCalled == 2);
+ REQUIRE(config.getBoolValue(key) == false);
+ REQUIRE(mCalled == 2);
+ config.removeListener(key, &testListener);
+ }
+
+ SECTION("configuration incvalue")
+ {
+ const char *const key = "testkey123";
+ config.setValue(key, 10);
+ REQUIRE(config.getValueInt(key, 12345) == 10);
+ config.incValue(key);
+ REQUIRE(config.getValueInt(key, 12345) == 11);
+ }
+
+ SECTION("configuration resetintvalue")
+ {
+ const char *const key = "sfxVolume";
+ config.setValue(key, 20);
+ REQUIRE(config.getIntValue(key) == 20);
+ REQUIRE(config.getFloatValue(key) >= 20.0f);
+ REQUIRE(config.getStringValue(key) == "20");
+ REQUIRE(config.getBoolValue(key) == true);
+ config.resetIntValue(key);
+ REQUIRE(config.getIntValue(key) == 100);
+ REQUIRE(config.getFloatValue(key) >= 100.0f);
+ REQUIRE(config.getStringValue(key) == "100");
+ REQUIRE(config.getBoolValue(key) == true);
+ }
+
+ SECTION("configuration resetboolvalue1")
+ {
+ const char *const key = "showgender";
+ config.setValue(key, false);
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key) == "0");
+ REQUIRE(config.getBoolValue(key) == false);
+
+ config.resetBoolValue(key);
+ REQUIRE(config.getIntValue(key) == 1);
+ REQUIRE(config.getFloatValue(key) >= 1.0f);
+ REQUIRE(config.getStringValue(key) == "1");
+ REQUIRE(config.getBoolValue(key) == true);
+ }
+
+ SECTION("configuration resetboolvalue2")
+ {
+ const char *const key = "showlevel";
+ config.setValue(key, true);
+ REQUIRE(config.getIntValue(key) == 1);
+ REQUIRE(config.getFloatValue(key) >= 1.0f);
+ REQUIRE(config.getStringValue(key) == "1");
+ REQUIRE(config.getBoolValue(key) == true);
+
+ config.resetBoolValue(key);
+ REQUIRE(config.getIntValue(key) == 0);
+ REQUIRE(config.getFloatValue(key) >= 0.0f);
+ REQUIRE(config.getStringValue(key) == "0");
+ REQUIRE(config.getBoolValue(key) == false);
+ }
+
+ delete2(logger);
+}
diff --git a/src/unittests/enums/enums_unittest.cc b/src/unittests/enums/enums_unittest.cc
new file mode 100644
index 000000000..ebff849d9
--- /dev/null
+++ b/src/unittests/enums/enums_unittest.cc
@@ -0,0 +1,35 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2015-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "enums/being/gender.h"
+
+#include "utils/cast.h"
+
+#include "debug.h"
+
+TEST_CASE("Gender", "Enums")
+{
+ REQUIRE(CAST_S32(Gender::FEMALE) == 1);
+ REQUIRE(Gender::FEMALE == static_cast<GenderT>(1));
+ REQUIRE(CAST_S32(Gender::MALE) == 0);
+ REQUIRE(Gender::MALE == static_cast<GenderT>(0));
+}
diff --git a/src/unittests/enums/render/mockdrawtype.h b/src/unittests/enums/render/mockdrawtype.h
new file mode 100644
index 000000000..7477684d0
--- /dev/null
+++ b/src/unittests/enums/render/mockdrawtype.h
@@ -0,0 +1,35 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ENUMS_RENDER_MOCKDRAWTYPE_H
+#define ENUMS_RENDER_MOCKDRAWTYPE_H
+#ifdef UNITTESTS
+
+#include "enums/simpletypes/enumdefines.h"
+
+enumStart(MockDrawType)
+{
+ DrawImage = 0,
+ DrawPattern = 1
+}
+enumEnd(MockDrawType);
+
+#endif // UNITTESTS
+#endif // ENUMS_RENDER_MOCKDRAWTYPE_H
diff --git a/src/unittests/fs/files_unittest.cc b/src/unittests/fs/files_unittest.cc
new file mode 100644
index 000000000..927891fdd
--- /dev/null
+++ b/src/unittests/fs/files_unittest.cc
@@ -0,0 +1,232 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "logger.h"
+
+#include "fs/files.h"
+
+#include "fs/virtfs/fs.h"
+#include "fs/virtfs/tools.h"
+
+#include "utils/delete2.h"
+#include "utils/stringutils.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "debug.h"
+
+TEST_CASE("Files renameFile", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ const int sz = 1234567;
+ char *buf = new char[sz];
+ for (int f = 0; f < sz; f ++)
+ buf[f] = f;
+
+ const std::string name1 = "file1.test";
+ const std::string name2 = "file2.test";
+ FILE *file = fopen(name1.c_str(), "w+b");
+ fwrite(buf, 1, sz, file);
+ fclose(file);
+
+ REQUIRE(0 == Files::renameFile(name1, name2));
+ char *buf2 = new char[sz];
+ FILE *file2 = fopen(name2.c_str(), "rb");
+ REQUIRE_FALSE(nullptr == file2);
+ fread(buf2, 1, sz, file2);
+ fclose(file2);
+ ::remove(name1.c_str());
+ ::remove(name2.c_str());
+
+ for (int f = 0; f < sz; f ++)
+ REQUIRE(buf[f] == buf2[f]);
+
+ delete [] buf;
+ delete [] buf2;
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files existsLocal", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ REQUIRE(Files::existsLocal(VirtFs::getPath("help/about.txt")) == true);
+ REQUIRE_FALSE(Files::existsLocal(VirtFs::getPath("help/about1.txt")));
+ REQUIRE_FALSE(Files::existsLocal(VirtFs::getPath("help1/about.txt")));
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files loadTextFileString", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ REQUIRE(VirtFs::loadTextFileString("test/simplefile.txt") ==
+ "this is test \nfile.");
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files loadTextFile", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ StringVect lines;
+ VirtFs::loadTextFile("test/simplefile.txt", lines);
+ REQUIRE(lines.size() == 2);
+ REQUIRE(lines[0] == "this is test ");
+ REQUIRE(lines[1] == "file.");
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files saveTextFile", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ const std::string dir = VirtFs::getPath("test");
+ REQUIRE(!dir.empty());
+ Files::saveTextFile(dir, "tempfile.txt", "test line\ntext line2");
+ std::string data = VirtFs::loadTextFileString("test/tempfile.txt");
+ ::remove((dir + "/tempfile.txt").c_str());
+#ifdef WIN32
+ REQUIRE(data == "test line\r\ntext line2\r\n");
+#else // WIN32
+
+ REQUIRE(data == "test line\ntext line2\n");
+#endif // WIN32
+
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files copyFile1", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ const std::string dir = VirtFs::getPath("test");
+ REQUIRE(!dir.empty());
+ SECTION("copy")
+ {
+ REQUIRE(Files::copyFile(pathJoin(dir, "test.txt"),
+ pathJoin(dir, "tempfile.txt")) == 0);
+ std::string data = VirtFs::loadTextFileString("test/tempfile.txt");
+ ::remove((dir + "/tempfile.txt").c_str());
+ REQUIRE(data == "test line 1\ntest line 2");
+ }
+
+ SECTION("errors")
+ {
+ REQUIRE(Files::copyFile(pathJoin(dir, "test_not_exists.txt"),
+ pathJoin(dir, "tempfile.txt")) == -1);
+ REQUIRE(Files::copyFile(pathJoin(dir, "test.txt"),
+ "/nonexist/root/dir123") == -1);
+ }
+
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files loadTextFileLocal", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ const std::string dir = VirtFs::getPath("test");
+ REQUIRE(!dir.empty());
+ Files::saveTextFile(dir, "tempfile.txt", "test line\ntext line2");
+ StringVect lines;
+ REQUIRE(Files::loadTextFileLocal(pathJoin(dir, "tempfile.txt"),
+ lines));
+ ::remove((dir + "/tempfile.txt").c_str());
+ REQUIRE(lines.size() == 2);
+ REQUIRE(lines[0] == "test line");
+ REQUIRE(lines[1] == "text line2");
+
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Files getFilesInDir", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ StringVect list;
+ VirtFs::getFilesInDir("test",
+ list,
+ ".gpl");
+ REQUIRE(list.size() == 1);
+ REQUIRE(list[0] == pathJoin("test", "palette.gpl"));
+
+ list.clear();
+ VirtFs::getFilesInDir("perserver/default",
+ list,
+ ".xml");
+ REQUIRE(list.size() == 5);
+ REQUIRE(list[0] == pathJoin("perserver", "default", "charcreation.xml"));
+ REQUIRE(list[1] == pathJoin("perserver", "default", "deadmessages.xml"));
+ REQUIRE(list[2] ==
+ pathJoin("perserver", "default", "defaultcommands.xml"));
+ REQUIRE(list[3] == pathJoin("perserver", "default", "features.xml"));
+ REQUIRE(list[4] == pathJoin("perserver", "default", "weapons.xml"));
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
diff --git a/src/unittests/fs/virtfs/virtfs1_unittest.cc b/src/unittests/fs/virtfs/virtfs1_unittest.cc
new file mode 100644
index 000000000..687316397
--- /dev/null
+++ b/src/unittests/fs/virtfs/virtfs1_unittest.cc
@@ -0,0 +1,3507 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "fs/files.h"
+
+#include "fs/virtfs/direntry.h"
+#include "fs/virtfs/fs.h"
+#include "fs/virtfs/rwops.h"
+#include "fs/virtfs/list.h"
+
+#include "utils/checkutils.h"
+#include "utils/delete2.h"
+#include "utils/foreach.h"
+#include "utils/stringutils.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#include <SDL_rwops.h>
+PRAGMA48(GCC diagnostic pop)
+
+#ifndef UNITTESTS_CATCH
+#include <algorithm>
+#endif // UNITTESTS_CATCH
+
+#include "debug.h"
+
+TEST_CASE("VirtFs1 getEntries", "")
+{
+ VirtFs::init(".");
+ REQUIRE(VirtFs::getEntries().empty());
+ REQUIRE(VirtFs::searchByRootInternal("test", std::string()) == nullptr);
+ VirtFs::deinit();
+}
+
+TEST_CASE("VirtFs1 getBaseDir", "")
+{
+ VirtFs::init(".");
+ REQUIRE(VirtFs::getBaseDir() != nullptr);
+ VirtFs::deinit();
+}
+
+TEST_CASE("VirtFs1 mountDir", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ SECTION("simple 1")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1") ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("simple 2")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1/",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1") ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1" + sep);
+ }
+
+ SECTION("simple 3")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_false));
+ REQUIRE(VirtFs::mountDirSilentTest("dir2",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1") ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir2");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir1");
+ }
+
+ SECTION("simple 4")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1\\",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir2",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1" + sep);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2");
+ }
+
+ SECTION("simple 5")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir2",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir3/test",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir3" + sep + "test" + sep, std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->root == "dir3" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[2]->subDir.empty());
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[2])->userDir == "dir3" + sep + "test");
+ }
+
+ SECTION("simple 6")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir2",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir3\\test",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir1" + sep + "", std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir2" + sep + "", std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir3" + sep + "test" + sep, std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "test" + sep + "", std::string()) == nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[2]->subDir.empty());
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3" + sep + "test");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir1");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[2])->userDir == "dir2");
+ }
+
+ SECTION("subDir 1")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ dirSeparator,
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("subDir 1.2")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir2",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir2" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir2" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("subDir 2")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1/",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir2" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir2" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1" + sep);
+ }
+
+ SECTION("subDir 3")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir3",
+ Append_false));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir2",
+ "dir4",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir3" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, "dir4" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir3" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir4" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir3" + sep);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir2");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir1");
+ }
+
+ SECTION("subDir 4")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1\\",
+ "dir3",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir2",
+ "dir4",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir3" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, "dir4" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir3" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir4" + sep);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1" + sep);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2");
+ }
+
+ SECTION("subDir 5")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir3",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir2",
+ "dir4",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir3/test",
+ "dir5",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir3" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir2" + sep, "dir4" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir3" + sep + "test" + sep, "dir5" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir3" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->root == "dir3" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir4" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->subDir == "dir5" + sep);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[2])->userDir == "dir3" + sep + "test");
+ }
+
+ SECTION("subDir 6")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir2",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir3\\test",
+ "dir3\\test",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir1" + sep + "", "dir1" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir2" + sep + "", "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "dir3" + sep + "test" + sep,
+ "dir3" + sep + "test" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ "test" + sep + "", "dir1" + sep) == nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->root == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir ==
+ "dir3" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->subDir == "dir2" + sep);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3" + sep + "test");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir1");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[2])->userDir == "dir2");
+ }
+
+ SECTION("subDir 7")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir2" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir2" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir1");
+
+ REQUIRE(VirtFs::unmountDirSilent("dir1"));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("subDir 8")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir2" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, "dir2" + sep) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir1");
+
+ REQUIRE(VirtFs::unmountDirSilent2("dir1", "dir2"));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("subDir 9")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ dirSeparator,
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("dir1" + sep, "dir1") ==
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal("test" + sep, std::string()) ==
+ nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 mountZip", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ const std::string sep = dirSeparator;
+ if (Files::existsLocal(name) == false)
+ prefix = "../";
+
+ SECTION("simple 1")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip", std::string()) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) == nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ }
+
+ SECTION("simple 2")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false));
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ }
+
+ SECTION("simple 3")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_true));
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ }
+
+ SECTION("simple 4")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false));
+ REQUIRE(VirtFs::mountDir(prefix + "data/test",
+ Append_false));
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[2]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[2]->subDir.empty());
+ }
+
+ SECTION("simple 5")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false));
+ REQUIRE(VirtFs::mountDir(prefix + "data/test",
+ Append_false));
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[2]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[2]->subDir.empty());
+ }
+
+ SECTION("subDir 1")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip", "dir1" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) == nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ }
+
+ SECTION("subDir 2")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_false));
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir2",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip", "dir1" + sep) !=
+ nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir1" + sep);
+ }
+
+ SECTION("subDir 3")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ "dir1" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ }
+
+ SECTION("subDir 4")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_false));
+ REQUIRE(VirtFs::mountDir2(prefix + "data/test",
+ "dir2",
+ Append_false));
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir3",
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ "dir1" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir3" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[2]->subDir == "dir1" + sep);
+ }
+
+ SECTION("subDir 5")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_false));
+ REQUIRE(VirtFs::mountDir2(prefix + "data/test",
+ "dir2",
+ Append_false));
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir3",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ "dir1" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir3" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "");
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[2]->subDir == "dir3" + sep);
+ }
+
+ SECTION("subDir 6")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ dirSeparator,
+ Append_false));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) == nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 unmount", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ const std::string sep = dirSeparator;
+ if (Files::existsLocal(name) == false)
+ prefix = "../";
+
+ SECTION("simple 1")
+ {
+ REQUIRE_THROWS(VirtFs::unmountDir("dir1"));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir1/"));
+ }
+
+ SECTION("simple 2")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
+ REQUIRE(VirtFs::unmountDir("dir1"));
+ }
+
+ SECTION("simple 3")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir2//dir3",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir3",
+ Append_false));
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
+ REQUIRE(VirtFs::unmountDir("dir1"));
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3");
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep + "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2" + sep + "dir3");
+ REQUIRE_THROWS(VirtFs::unmountDir("dir1"));
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3");
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep + "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2" + sep + "dir3");
+ REQUIRE(VirtFs::unmountDir("dir2/dir3"));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2/dir3" + sep));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3");
+ }
+
+ SECTION("simple 4")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
+ REQUIRE(VirtFs::unmountDir("dir1"));
+ REQUIRE(VirtFs::getEntries().empty());
+ REQUIRE(VirtFs::mountDirSilentTest("dir1",
+ Append_true));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("simple 5")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_true));
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_true));
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) == nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ }
+
+ SECTION("simple 6")
+ {
+ REQUIRE(VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false));
+ REQUIRE(VirtFs::mountDir(prefix + "data/test",
+ Append_false));
+ REQUIRE(VirtFs::mountZip(prefix + "data\\test/test2.zip",
+ Append_false));
+
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[2]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[2]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
+
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) == nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ std::string()) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ }
+
+ SECTION("subDir 1")
+ {
+ REQUIRE_THROWS(VirtFs::unmountDir2("dir1", "dir1"));
+ REQUIRE_THROWS(VirtFs::unmountDir2("dir1/", "dir1/"));
+ }
+
+ SECTION("subDir 2")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir2",
+ Append_true));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir1"));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
+ REQUIRE(VirtFs::unmountDir2("dir1", "dir2"));
+ }
+
+ SECTION("subDir 3")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest("dir2//dir3",
+ Append_true));
+ REQUIRE(VirtFs::mountDirSilentTest2("dir3",
+ "dir4",
+ Append_false));
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
+ REQUIRE_THROWS(VirtFs::unmountDir2("dir1", "dir1"));
+ REQUIRE(VirtFs::unmountDir2("dir1", "dir2"));
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir4" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3");
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep + "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2" + sep + "dir3");
+ REQUIRE_THROWS(VirtFs::unmountDir("dir1"));
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir4" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3");
+ REQUIRE(VirtFs::getEntries()[1]->root == "dir2" + sep + "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir.empty());
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[1])->userDir == "dir2" + sep + "dir3");
+ REQUIRE(VirtFs::unmountDir("dir2/dir3"));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2/dir3" + sep));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir4" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir3");
+ }
+
+ SECTION("subDir 4")
+ {
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir2",
+ Append_true));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ REQUIRE_THROWS(VirtFs::unmountDir("dir2"));
+ REQUIRE_THROWS(VirtFs::unmountDir("dir1"));
+ REQUIRE(VirtFs::unmountDir2("dir1", "dir2"));
+ REQUIRE(VirtFs::getEntries().empty());
+ REQUIRE(VirtFs::mountDirSilentTest2("dir1",
+ "dir3",
+ Append_true));
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Dir);
+ REQUIRE(static_cast<VirtFs::DirEntry*>(
+ VirtFs::getEntries()[0])->userDir == "dir1");
+ }
+
+ SECTION("subDir 5")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_true));
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir2",
+ Append_true));
+
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ "dir1" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Zip);
+
+ VirtFs::unmountZip2(prefix + "data/test/test.zip",
+ "dir1");
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ std::string()) == nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 1);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ }
+
+ SECTION("subDir 6")
+ {
+ REQUIRE(VirtFs::mountZip2(prefix + "data/test/test.zip",
+ "dir1",
+ Append_false));
+ REQUIRE(VirtFs::mountDir2(prefix + "data/test",
+ "dir2",
+ Append_false));
+ REQUIRE(VirtFs::mountZip2(prefix + "data\\test/test2.zip",
+ "dir3",
+ Append_false));
+
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ "dir1" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir3" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 3);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ REQUIRE(VirtFs::getEntries()[2]->root ==
+ prefix + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getEntries()[2]->subDir == "dir1" + sep);
+ REQUIRE(VirtFs::getEntries()[2]->type == FsEntryType::Zip);
+
+ VirtFs::unmountZip2(prefix + "data/test/test.zip",
+ "dir1");
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test.zip",
+ "dir1" + sep) == nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "test2.zip",
+ "dir3" + sep) != nullptr);
+ REQUIRE(VirtFs::searchByRootInternal(
+ prefix + "data" + sep + "test" + sep + "",
+ "dir2" + sep) != nullptr);
+ REQUIRE(VirtFs::getEntries().size() == 2);
+ REQUIRE(VirtFs::getEntries()[0]->root ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getEntries()[0]->subDir == "dir3" + sep);
+ REQUIRE(VirtFs::getEntries()[0]->type == FsEntryType::Zip);
+ REQUIRE(VirtFs::getEntries()[1]->root ==
+ prefix + "data" + sep + "test" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->subDir == "dir2" + sep);
+ REQUIRE(VirtFs::getEntries()[1]->type == FsEntryType::Dir);
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 exists1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ const bool dir1 = VirtFs::mountDirSilent("data/",
+ Append_false);
+ VirtFs::mountDirSilent("..\\data",
+ Append_false);
+
+ REQUIRE(VirtFs::exists("test"));
+ REQUIRE(VirtFs::exists("test/"));
+ REQUIRE(VirtFs::exists("test/dir1"));
+ REQUIRE(VirtFs::exists("test/dir1/"));
+ REQUIRE(VirtFs::exists("test/dir") == false);
+ REQUIRE(VirtFs::exists("test//units.xml") == true);
+ REQUIRE(VirtFs::exists("test/\\units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml") == false);
+
+ if (dir1 == true)
+ {
+ VirtFs::mountDir("data//test",
+ Append_false);
+ }
+ else
+ {
+ VirtFs::mountDirSilent("..//data\\test",
+ Append_false);
+ }
+
+ REQUIRE(VirtFs::exists("test") == true);
+ REQUIRE(VirtFs::exists("test/dir1"));
+ REQUIRE(VirtFs::exists("test/dir1\\"));
+ REQUIRE(VirtFs::exists("test/dir") == false);
+ REQUIRE(VirtFs::exists("test\\units.xml") == true);
+ REQUIRE(VirtFs::exists("test/units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml") == true);
+ REQUIRE(VirtFs::exists("units.xml/") == false);
+
+ if (dir1 == true)
+ VirtFs::unmountDirSilent("data/test");
+ else
+ VirtFs::unmountDirSilent("../data/test");
+
+ REQUIRE(VirtFs::exists("test") == true);
+ REQUIRE(VirtFs::exists("test/dir1"));
+ REQUIRE(VirtFs::exists("test/dir") == false);
+ REQUIRE(VirtFs::exists("test\\units.xml") == true);
+ REQUIRE(VirtFs::exists("test/units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml/") == false);
+
+ REQUIRE_THROWS(VirtFs::exists("test/../units.xml"));
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 exists2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ const bool dir1 = VirtFs::mountDirSilent2("data/",
+ "test",
+ Append_false);
+ VirtFs::mountDirSilent2("..\\data",
+ "test",
+ Append_false);
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/") == false);
+ REQUIRE(VirtFs::exists("dir1"));
+ REQUIRE(VirtFs::exists("dir1/"));
+ REQUIRE(VirtFs::exists("dir") == false);
+ REQUIRE(VirtFs::exists("units.xml") == true);
+ REQUIRE(VirtFs::exists("units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml"));
+ REQUIRE(VirtFs::exists("file1.txt") == false);
+ REQUIRE(VirtFs::exists("file2.txt") == false);
+
+ if (dir1 == true)
+ {
+ VirtFs::mountDir2("data//test",
+ "dir2",
+ Append_false);
+ }
+ else
+ {
+ VirtFs::mountDirSilent2("..//data\\test",
+ "dir2",
+ Append_false);
+ }
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/") == false);
+ REQUIRE(VirtFs::exists("dir1"));
+ REQUIRE(VirtFs::exists("dir1/"));
+ REQUIRE(VirtFs::exists("dir") == false);
+ REQUIRE(VirtFs::exists("units.xml") == true);
+ REQUIRE(VirtFs::exists("units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml"));
+ REQUIRE(VirtFs::exists("file1.txt"));
+ REQUIRE(VirtFs::exists("file2.txt"));
+
+ if (dir1 == true)
+ VirtFs::unmountDirSilent2("data/test", "dir2");
+ else
+ VirtFs::unmountDirSilent2("../data/test", "dir2");
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/") == false);
+ REQUIRE(VirtFs::exists("dir1"));
+ REQUIRE(VirtFs::exists("dir1/"));
+ REQUIRE(VirtFs::exists("dir") == false);
+ REQUIRE(VirtFs::exists("units.xml") == true);
+ REQUIRE(VirtFs::exists("units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml"));
+ REQUIRE(VirtFs::exists("file1.txt") == false);
+ REQUIRE(VirtFs::exists("file2.txt") == false);
+
+ REQUIRE_THROWS(VirtFs::exists("test/../units.xml"));
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+static void removeTemp(StringVect &restrict list)
+{
+ int cnt = 0;
+ std::sort(list.begin(), list.end());
+
+ FOR_EACH (StringVectIter, it, list)
+ {
+ if (*it != "serverlistplus.xml.part")
+ {
+ logger->log("file: %d %s",
+ cnt,
+ (*it).c_str());
+ cnt ++;
+ }
+ }
+
+ FOR_EACH (StringVectIter, it, list)
+ {
+ if (*it == "serverlistplus.xml.part")
+ {
+ list.erase(it);
+ return;
+ }
+ }
+}
+
+TEST_CASE("VirtFs1 getRealDir1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ REQUIRE(VirtFs::getRealDir(".").empty());
+ REQUIRE(VirtFs::getRealDir("..").empty());
+ const bool dir1 = VirtFs::mountDirSilent("data",
+ Append_false);
+ REQUIRE((dir1 || VirtFs::mountDirSilent("../data",
+ Append_false)) == true);
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "data");
+ REQUIRE(VirtFs::getRealDir("test\\test.txt") ==
+ "data");
+ REQUIRE(VirtFs::getRealDir("test//test.txt") ==
+ "data");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "../data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "../data");
+ REQUIRE(VirtFs::getRealDir("test\\test.txt") ==
+ "../data");
+ REQUIRE(VirtFs::getRealDir("test//test.txt") ==
+ "../data");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::mountDirSilent("data/test",
+ Append_false);
+ VirtFs::mountDirSilent("../data/test",
+ Append_false);
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "data");
+ REQUIRE(VirtFs::getRealDir("test\\test.txt") ==
+ "data");
+ REQUIRE(VirtFs::getRealDir("test.txt") ==
+ "data" + sep + "test");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("test") == ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test\\test.txt") ==
+ ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test.txt") ==
+ ".." + sep + "data" + sep + "test");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "data");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("test") == ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ ".." + sep + "data");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getRealDir2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ std::string name("data/test/test.zip");
+ std::string prefix("data" + sep + "test" + sep);
+ if (Files::existsLocal(name) == false)
+ prefix = ".." + sep + prefix;
+ VirtFs::mountZip(prefix + "test2.zip",
+ Append_false);
+
+ REQUIRE(VirtFs::getRealDir(".").empty());
+ REQUIRE(VirtFs::getRealDir("..").empty());
+ REQUIRE(VirtFs::getRealDir("test.txt") == prefix + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("dir/1") == prefix + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("dir\\dye.png") ==
+ prefix + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::mountZip(prefix + "test.zip",
+ Append_false);
+ REQUIRE(VirtFs::getRealDir("dir//dye.png") ==
+ prefix + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("dir///hide.png") ==
+ prefix + "test.zip");
+ REQUIRE(VirtFs::getRealDir("dir\\\\brimmedhat.png") ==
+ prefix + "test.zip");
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::unmountZip(prefix + "test.zip");
+
+ REQUIRE(VirtFs::getRealDir("dir/brimmedhat.png").empty());
+ REQUIRE(VirtFs::getRealDir("test.txt") == prefix + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("dir//dye.png") ==
+ prefix + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::unmountZip(prefix + "test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getRealDir3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ REQUIRE(VirtFs::getRealDir(".").empty());
+ REQUIRE(VirtFs::getRealDir("..").empty());
+ const bool dir1 = VirtFs::mountDirSilent2("data",
+ "test",
+ Append_false);
+ REQUIRE((dir1 || VirtFs::mountDirSilent2("../data",
+ "test",
+ Append_false)) == true);
+ REQUIRE(VirtFs::getRealDir("file1.txt").empty());
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("dir1") == "data");
+ REQUIRE(VirtFs::getRealDir("simplefile.txt") == "data");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("dir1") == ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("simplefile.txt") == ".." + sep + "data");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::mountDirSilent2("data/test",
+ "dir2",
+ Append_false);
+ VirtFs::mountDirSilent2("../data/test",
+ "dir2",
+ Append_false);
+ REQUIRE(VirtFs::getRealDir("dir").empty());
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("file1.txt") == "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("simplefile.txt") == "data");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("file1.txt") ==
+ ".." + sep + "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("simplefile.txt") == ".." + sep + "data");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+static bool inList(const VirtFs::List *const list,
+ const std::string &name)
+{
+ FOR_EACH (StringVectCIter, it, list->names)
+ {
+ if (*it == name)
+ return true;
+ }
+ return false;
+}
+
+static bool inList(StringVect list,
+ const std::string &name)
+{
+ FOR_EACH (StringVectCIter, it, list)
+ {
+ if (*it == name)
+ return true;
+ }
+ return false;
+}
+
+static bool inList(StringVect list,
+ const std::string &dir,
+ const std::string &name)
+{
+ const std::string path = pathJoin(dir, name);
+ FOR_EACH (StringVectCIter, it, list)
+ {
+ if (*it == path)
+ return true;
+ }
+ return false;
+}
+
+TEST_CASE("VirtFs1 enumerateFiles1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+
+ VirtFs::mountDirSilent("data",
+ Append_false);
+ VirtFs::mountDirSilent("../data",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ const int cnt1 = VirtFs::exists("test/test2.txt") ? 28 : 27;
+ const int cnt2 = 28;
+
+ VirtFs::permitLinks(false);
+ list = VirtFs::enumerateFiles("test");
+ removeTemp(list->names);
+ const size_t sz = list->names.size();
+ REQUIRE(sz == cnt1);
+ VirtFs::freeList(list);
+
+ VirtFs::permitLinks(true);
+ list = VirtFs::enumerateFiles("test/");
+ removeTemp(list->names);
+ REQUIRE(list->names.size() == cnt2);
+ VirtFs::freeList(list);
+
+ VirtFs::permitLinks(true);
+ list = VirtFs::enumerateFiles("test/units.xml");
+ REQUIRE(list->names.empty());
+ VirtFs::freeList(list);
+
+ VirtFs::permitLinks(false);
+ list = VirtFs::enumerateFiles("test\\");
+ removeTemp(list->names);
+ REQUIRE(list->names.size() == cnt1);
+ VirtFs::freeList(list);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 enumerateFiles2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+
+ VirtFs::mountDirSilent("data/test/dir1",
+ Append_false);
+ VirtFs::mountDirSilent("../data/test/dir1",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 5);
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE_FALSE(inList(list, "file2.txt"));
+ VirtFs::freeList(list);
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 enumerateFiles3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+
+ VirtFs::mountDirSilent("data/test/dir1",
+ Append_false);
+ VirtFs::mountDirSilent("../data/test/dir1",
+ Append_false);
+ VirtFs::mountDirSilent("data/test/dir2",
+ Append_false);
+ VirtFs::mountDirSilent("../data/test/dir2",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "file2.txt"));
+ VirtFs::freeList(list);
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles4", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix("data\\test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test.zip",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir");
+ REQUIRE(list->names.size() == 2);
+ REQUIRE(inList(list, "brimmedhat.png"));
+ REQUIRE(inList(list, "hide.png"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "test.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles5", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix("data//test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test.zip",
+ Append_true);
+ VirtFs::mountZip(prefix + "test2.zip",
+ Append_true);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir");
+ FOR_EACH (StringVectCIter, it, list->names)
+ {
+ logger->log("filename: " + *it);
+ }
+
+ REQUIRE(list->names.size() == 5);
+ REQUIRE(inList(list, "brimmedhat.png"));
+ REQUIRE(inList(list, "hide.png"));
+ REQUIRE(inList(list, "1"));
+ REQUIRE(inList(list, "gpl"));
+ REQUIRE(inList(list, "dye.png"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "test.zip");
+ VirtFs::unmountZip(prefix + "test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles6", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix("data\\test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test.zip",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 1);
+ REQUIRE(inList(list, "dir"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "test.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles7", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix("data\\test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test2.zip",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 4);
+ REQUIRE(inList(list, "dir"));
+ REQUIRE(inList(list, "dir2"));
+ REQUIRE(inList(list, "test.txt"));
+ REQUIRE(inList(list, "units.xml"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles8", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+ VirtFs::mountDirSilent(prefix + "data/test",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir2");
+ REQUIRE(list->names.size() >= 6);
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "file2.txt"));
+ REQUIRE(inList(list, "hide.png"));
+ REQUIRE(inList(list, "paths.xml"));
+ REQUIRE(inList(list, "test.txt"));
+ REQUIRE(inList(list, "units.xml"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles9", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+ VirtFs::mountDirSilent(prefix + "data/test",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir");
+ REQUIRE(list->names.size() == 4);
+ REQUIRE(inList(list, "1"));
+ REQUIRE(inList(list, "gpl"));
+ REQUIRE(inList(list, "dye.png"));
+ REQUIRE(inList(list, "hide.png"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles10", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix("data\\test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "test.zip",
+ "dir",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 2);
+ REQUIRE(inList(list, "brimmedhat.png"));
+ REQUIRE(inList(list, "hide.png"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip2(prefix + "test.zip",
+ "dir");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFsZip enumerateFiles11", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix("data\\test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "test2.zip",
+ "dir",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("1");
+ REQUIRE(list->names.size() == 2);
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "test.txt"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip2(prefix + "test2.zip",
+ "dir");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 enumerateFiles12", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+
+ VirtFs::mountDirSilent2("data/test",
+ "dir2",
+ Append_false);
+ VirtFs::mountDirSilent2("../data/test",
+ "dir2",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "file2.txt"));
+ VirtFs::freeList(list);
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 enumerateFiles13", "")
+{
+ VirtFs::init(".");
+ logger = new Logger;
+
+ VirtFs::mountDirSilent2("data",
+ "test",
+ Append_false);
+ VirtFs::mountDirSilent2("../data",
+ "test",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir2");
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "file2.txt"));
+ VirtFs::freeList(list);
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+
+TEST_CASE("VirtFs1 isDirectory1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("test//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test//units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test") == true);
+ REQUIRE(VirtFs::isDirectory("test/") == true);
+ REQUIRE(VirtFs::isDirectory("test//") == true);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == true);
+ REQUIRE(VirtFs::isDirectory("test//dir1") == true);
+ REQUIRE(VirtFs::isDirectory("test//dir1/") == true);
+ REQUIRE(VirtFs::isDirectory("test//dir1//") == true);
+ REQUIRE(VirtFs::isDirectory("test\\dir1/") == true);
+ REQUIRE(VirtFs::isDirectory("test/dir1//") == true);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::mountDir(prefix + "data/test",
+ Append_false);
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("test//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test") == true);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == true);
+ REQUIRE(VirtFs::isDirectory("test\\dir1") == true);
+
+ VirtFs::unmountDir(prefix + "data/test");
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("test") == true);
+ REQUIRE(VirtFs::isDirectory("test/") == true);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == true);
+
+ VirtFs::unmountDirSilent(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 isDirectory2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir") == true);
+ REQUIRE(VirtFs::isDirectory("dir2/") == true);
+ REQUIRE(VirtFs::isDirectory("dir2//") == true);
+ REQUIRE(VirtFs::isDirectory("dir/1") == true);
+ REQUIRE(VirtFs::isDirectory("dir//1") == true);
+ REQUIRE(VirtFs::isDirectory("dir\\1/") == true);
+ REQUIRE(VirtFs::isDirectory("dir/1") == true);
+ REQUIRE(VirtFs::isDirectory("dir/1/zzz") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1\\") == false);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false);
+
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("dir2\\units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir") == true);
+ REQUIRE(VirtFs::isDirectory("dir2/") == true);
+ REQUIRE(VirtFs::isDirectory("dir2\\") == true);
+ REQUIRE(VirtFs::isDirectory("dir/1") == true);
+ REQUIRE(VirtFs::isDirectory("dir//1") == true);
+ REQUIRE(VirtFs::isDirectory("dir//1/") == true);
+ REQUIRE(VirtFs::isDirectory("dir/1") == true);
+ REQUIRE(VirtFs::isDirectory("dir/1/zzz") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1//") == false);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir") == true);
+ REQUIRE(VirtFs::isDirectory("dir2/") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//") == false);
+ REQUIRE(VirtFs::isDirectory("dir/1") == false);
+ REQUIRE(VirtFs::isDirectory("dir\\1") == false);
+ REQUIRE(VirtFs::isDirectory("dir//1/") == false);
+ REQUIRE(VirtFs::isDirectory("dir/1") == false);
+ REQUIRE(VirtFs::isDirectory("dir/1/zzz") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1//") == false);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 isDirectory3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir2(prefix + "data",
+ "test",
+ Append_false);
+
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test") == false);
+ REQUIRE(VirtFs::isDirectory("dir1") == true);
+ REQUIRE(VirtFs::isDirectory("dir2//") == true);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == false);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::unmountDirSilent2(prefix + "data",
+ "test");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 isDirectory4", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir",
+ Append_false);
+
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir2//units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("1") == true);
+ REQUIRE(VirtFs::isDirectory("gpl") == true);
+ REQUIRE(VirtFs::isDirectory("dir2/") == false);
+ REQUIRE(VirtFs::isDirectory("dir/1") == false);
+ REQUIRE(VirtFs::isDirectory("dir/1/zzz") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1\\") == false);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 openRead1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test\\units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+
+ VirtFs::mountDir(prefix + "data/test",
+ Append_false);
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountDir(prefix + "data/test");
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountDir(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 openRead2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix("data/test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test2.zip",
+ Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("dir2/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir2\\units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir2/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml1");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dir/brimmedhat.png");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dir//brimmedhat.png");
+ REQUIRE(file == nullptr);
+
+ VirtFs::mountZip(prefix + "test.zip",
+ Append_false);
+
+ file = VirtFs::openRead("dir2/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir2//units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir2/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml1");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dir/brimmedhat.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+
+ VirtFs::unmountZip(prefix + "test.zip");
+
+ file = VirtFs::openRead("dir2/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir2\\/\\units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir2/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml1");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dir/brimmedhat.png");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountZip(prefix + "test2.zip");
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 openRead3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir2(prefix + "data",
+ "test",
+ Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("file1.txt");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("file2.txt");
+ REQUIRE(file == nullptr);
+
+ VirtFs::mountDir2(prefix + "data/test",
+ "dir2",
+ Append_false);
+
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("file1.txt");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("file2.txt");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+
+ VirtFs::unmountDir2(prefix + "data/test",
+ "dir2");
+
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("file1.txt");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("file2.txt");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountDir2(prefix + "data",
+ "test");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 openRead4", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix("data/test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "test2.zip",
+ "dir",
+ Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("dye.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("1\\test.txt");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/dye.png");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dye.png1");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("brimmedhat.png");
+ REQUIRE(file == nullptr);
+
+ VirtFs::mountZip2(prefix + "test.zip",
+ "dir",
+ Append_false);
+
+ file = VirtFs::openRead("dye.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("1\\test.txt");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/dye.png");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dye.png1");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("brimmedhat.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+
+ VirtFs::unmountZip2(prefix + "test.zip",
+ "dir");
+
+ file = VirtFs::openRead("dye.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("1\\test.txt");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/dye.png");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("dye.png1");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("brimmedhat.png");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountZip2(prefix + "test2.zip",
+ "dir");
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 permitLinks", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ const int cnt1 = VirtFs::exists("test/test2.txt") ? 26 : 25;
+ const int cnt2 = 26;
+
+ StringVect list;
+ VirtFs::permitLinks(false);
+ VirtFs::getFiles("test", list);
+ removeTemp(list);
+ const size_t sz = list.size();
+ REQUIRE(sz == cnt1);
+
+ list.clear();
+ VirtFs::permitLinks(true);
+ VirtFs::getFiles("test", list);
+ removeTemp(list);
+ REQUIRE(list.size() == cnt2);
+
+ list.clear();
+ VirtFs::permitLinks(false);
+ VirtFs::getFiles("test", list);
+ removeTemp(list);
+ REQUIRE(list.size() == cnt1);
+
+ VirtFs::unmountDirSilent(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 read1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ VirtFs::File *file = VirtFs::openRead("test/test.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) != 0);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ REQUIRE(VirtFs::eof(file) != 0);
+
+ VirtFs::close(file);
+ free(buffer);
+
+ VirtFs::unmountDir(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 read2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix("data/test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test2.zip",
+ Append_false);
+ VirtFs::File *file = nullptr;
+ void *restrict buffer = nullptr;
+
+ SECTION("test 1")
+ {
+ file = VirtFs::openRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) != 0);
+ }
+
+ SECTION("test 2")
+ {
+ file = VirtFs::openRead("dir2\\/test.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ REQUIRE(VirtFs::eof(file) != 0);
+ }
+
+ SECTION("test 3")
+ {
+ file = VirtFs::openRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = VirtFs::fileLength(file);
+
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize; f ++)
+ {
+ REQUIRE(VirtFs::seek(file, f) != 0);
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == f);
+ }
+ }
+
+ SECTION("test 4")
+ {
+ file = VirtFs::openRead("dir2/test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = VirtFs::fileLength(file);
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f ++)
+ {
+ REQUIRE(VirtFs::read(file, buffer, 1, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == f + 1);
+ }
+ REQUIRE(VirtFs::read(file, buffer, 1, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ REQUIRE(VirtFs::eof(file) != 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ }
+
+ SECTION("test 5")
+ {
+ file = VirtFs::openRead("dir2\\\\test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = VirtFs::fileLength(file);
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(VirtFs::read(file, buffer, 2, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == f + 2);
+ }
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == 22);
+ REQUIRE(VirtFs::read(file, buffer, 2, 1) == 0);
+ REQUIRE(VirtFs::eof(file) == 0);
+ }
+
+ SECTION("test 6")
+ {
+ file = VirtFs::openRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = VirtFs::fileLength(file);
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(VirtFs::read(file, buffer, 1, 2) == 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == f + 2);
+ }
+ REQUIRE(VirtFs::eof(file) == 0);
+ REQUIRE(VirtFs::tell(file) == 22);
+ REQUIRE(VirtFs::read(file, buffer, 1, 2) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ REQUIRE(VirtFs::eof(file) != 0);
+ }
+
+ VirtFs::close(file);
+ free(buffer);
+ VirtFs::unmountZip(prefix + "test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 loadFile1", "")
+{
+ VirtFs::init(".");
+ int fileSize = 0;
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ const char *const buffer = VirtFs::loadFile("test/test.txt", fileSize);
+ REQUIRE(static_cast<const void*>(buffer) != nullptr);
+ REQUIRE(fileSize == 23);
+ REQUIRE(strncmp(buffer, "test line 1\ntest line 2", 23) == 0);
+ delete [] buffer;
+
+ VirtFs::unmountDir(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 loadFile2", "")
+{
+ VirtFs::init(".");
+ int fileSize = 0;
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ SECTION("test 1")
+ {
+ const char *restrict buffer = VirtFs::loadFile("dir2//test.txt",
+ fileSize);
+ REQUIRE(static_cast<const void*>(buffer) != nullptr);
+ REQUIRE(fileSize == 23);
+ REQUIRE(strncmp(buffer, "test line 1\ntest line 2", 23) == 0);
+ delete [] buffer;
+ }
+
+ SECTION("test 2")
+ {
+ const char *restrict buffer = VirtFs::loadFile("dir2\\/test.txt",
+ fileSize);
+ REQUIRE(static_cast<const void*>(buffer) != nullptr);
+ REQUIRE(fileSize == 23);
+ REQUIRE(strncmp(buffer, "test line 1\ntest line 2", 23) == 0);
+ delete [] buffer;
+ }
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 loadFile3", "")
+{
+ VirtFs::init(".");
+ int fileSize = 0;
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir2(prefix + "data",
+ "test",
+ Append_false);
+
+ const char *const buffer = VirtFs::loadFile("test.txt", fileSize);
+ REQUIRE(static_cast<const void*>(buffer) != nullptr);
+ REQUIRE(fileSize == 23);
+ REQUIRE(strncmp(buffer, "test line 1\ntest line 2", 23) == 0);
+ delete [] buffer;
+
+ VirtFs::unmountDir2(prefix + "data",
+ "test");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 loadFile4", "")
+{
+ VirtFs::init(".");
+ int fileSize = 0;
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir2",
+ Append_false);
+
+ SECTION("test 1")
+ {
+ const char *restrict buffer = VirtFs::loadFile("test.txt",
+ fileSize);
+ REQUIRE(static_cast<const void*>(buffer) != nullptr);
+ REQUIRE(fileSize == 23);
+ REQUIRE(strncmp(buffer, "test line 1\ntest line 2", 23) == 0);
+ delete [] buffer;
+ }
+
+ SECTION("test 2")
+ {
+ const char *restrict buffer = VirtFs::loadFile("test.txt",
+ fileSize);
+ REQUIRE(static_cast<const void*>(buffer) != nullptr);
+ REQUIRE(fileSize == 23);
+ REQUIRE(strncmp(buffer, "test line 1\ntest line 2", 23) == 0);
+ delete [] buffer;
+ }
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir2");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 rwops_read1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ SDL_RWops *file = VirtFs::rwopsOpenRead("test/test.txt");
+ REQUIRE(file != nullptr);
+#ifdef USE_SDL2
+ REQUIRE(file->size(file) == 23);
+#endif // USE_SDL2
+
+ const int fileSize = 23;
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(file->read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == fileSize);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(file->seek(file, 12, SEEK_SET) != 0);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 12);
+ REQUIRE(file->read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+
+ file->close(file);
+ free(buffer);
+
+ VirtFs::unmountDir(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 rwops_read2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix("data/test/");
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "test2.zip",
+ Append_false);
+ SDL_RWops *file = nullptr;
+ void *restrict buffer = nullptr;
+
+ SECTION("test 1")
+ {
+ file = VirtFs::rwopsOpenRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+#ifdef USE_SDL2
+ REQUIRE(file->size(file) == 23);
+#endif // USE_SDL2
+ const int fileSize = 23;
+
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(file->read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == fileSize);
+ }
+
+ SECTION("test 2")
+ {
+ file = VirtFs::rwopsOpenRead("dir2\\/test.txt");
+ REQUIRE(file != nullptr);
+#ifdef USE_SDL2
+ REQUIRE(file->size(file) == 23);
+#endif // USE_SDL2
+ const int fileSize = 23;
+
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(file->seek(file, 12, SEEK_SET) != 0);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 12);
+ REQUIRE(file->read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ }
+
+ SECTION("test 3")
+ {
+ file = VirtFs::rwopsOpenRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize; f ++)
+ {
+ REQUIRE(file->seek(file, f, SEEK_SET) == f);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f);
+ }
+ }
+
+ SECTION("test 4")
+ {
+ file = VirtFs::rwopsOpenRead("dir2/test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f ++)
+ {
+ REQUIRE(file->read(file, buffer, 1, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 1);
+ }
+ REQUIRE(file->read(file, buffer, 1, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == fileSize);
+ }
+
+ SECTION("test 5")
+ {
+ file = VirtFs::rwopsOpenRead("dir2\\\\test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->read(file, buffer, 2, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 2);
+ }
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 22);
+ REQUIRE(file->read(file, buffer, 2, 1) == 0);
+ }
+
+ SECTION("test 6")
+ {
+ file = VirtFs::rwopsOpenRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 2);
+ }
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 22);
+ REQUIRE(file->read(file, buffer, 1, 2) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ }
+
+ SECTION("test 7")
+ {
+ file = VirtFs::rwopsOpenRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ REQUIRE(file->seek(file, -2, SEEK_CUR) == f);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f);
+ REQUIRE(file->seek(file, 2, SEEK_CUR) == f + 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 2);
+ }
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 22);
+ REQUIRE(file->read(file, buffer, 1, 2) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ }
+
+ SECTION("test 8")
+ {
+ file = VirtFs::rwopsOpenRead("dir2//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->seek(file, -f - 2, SEEK_END) == 23 - f - 2);
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[23 - f - 2]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[23 - f - 2 + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 23 - f);
+ }
+ // 3
+ REQUIRE(file->seek(file, 1, SEEK_CUR) == 4);
+ // 4
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ // 6
+ REQUIRE(static_cast<char*>(buffer)[0] == str[4]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[5]);
+ REQUIRE(file->seek(file, -7, SEEK_CUR) == -1);
+ REQUIRE(file->seek(file, 6, SEEK_SET) == 6);
+ REQUIRE(file->seek(file, -6, SEEK_CUR) == 0);
+ }
+
+ if (file != nullptr)
+ file->close(file);
+ free(buffer);
+ VirtFs::unmountZip(prefix + "test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 rwops_read3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+ SDL_RWops *file = nullptr;
+ void *restrict buffer = nullptr;
+
+ SECTION("test 1")
+ {
+ file = VirtFs::rwopsOpenRead("test/test.txt");
+ REQUIRE(file != nullptr);
+#ifdef USE_SDL2
+ REQUIRE(file->size(file) == 23);
+#endif // USE_SDL2
+ const int fileSize = 23;
+
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(file->read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == fileSize);
+ }
+
+ SECTION("test 2")
+ {
+ file = VirtFs::rwopsOpenRead("test\\test.txt");
+ REQUIRE(file != nullptr);
+#ifdef USE_SDL2
+ REQUIRE(file->size(file) == 23);
+#endif // USE_SDL2
+ const int fileSize = 23;
+
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(file->seek(file, 12, SEEK_SET) != 0);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 12);
+ REQUIRE(file->read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ }
+
+ SECTION("test 3")
+ {
+ file = VirtFs::rwopsOpenRead("test\\/test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize; f ++)
+ {
+ REQUIRE(file->seek(file, f, SEEK_SET) == f);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f);
+ }
+ }
+
+ SECTION("test 4")
+ {
+ file = VirtFs::rwopsOpenRead("test/test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f ++)
+ {
+ REQUIRE(file->read(file, buffer, 1, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 1);
+ }
+ REQUIRE(file->read(file, buffer, 1, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == fileSize);
+ }
+
+ SECTION("test 5")
+ {
+ file = VirtFs::rwopsOpenRead("test///test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->read(file, buffer, 2, 1) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 2);
+ }
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 22);
+ REQUIRE(file->read(file, buffer, 2, 1) == 0);
+ }
+
+ SECTION("test 6")
+ {
+ file = VirtFs::rwopsOpenRead("test\\\\test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 2);
+ }
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 22);
+ REQUIRE(file->read(file, buffer, 1, 2) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ }
+
+ SECTION("test 7")
+ {
+ file = VirtFs::rwopsOpenRead("test//test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ REQUIRE(file->seek(file, -2, SEEK_CUR) == f);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f);
+ REQUIRE(file->seek(file, 2, SEEK_CUR) == f + 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[f]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[f + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == f + 2);
+ }
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 22);
+ REQUIRE(file->read(file, buffer, 1, 2) == 1);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[22]);
+ }
+
+ SECTION("test 8")
+ {
+ file = VirtFs::rwopsOpenRead("test/test.txt");
+ REQUIRE(file != nullptr);
+ const int fileSize = 23;
+ const char *restrict const str = "test line 1\ntest line 2";
+ buffer = calloc(fileSize + 1, 1);
+ for (int f = 0; f < fileSize - 1; f += 2)
+ {
+ REQUIRE(file->seek(file, -f - 2, SEEK_END) == 23 - f - 2);
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ REQUIRE(static_cast<char*>(buffer)[0] == str[23 - f - 2]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[23 - f - 2 + 1]);
+ REQUIRE(file->seek(file, 0, SEEK_CUR) == 23 - f);
+ }
+ // 3
+ REQUIRE(file->seek(file, 1, SEEK_CUR) == 4);
+ // 4
+ REQUIRE(file->read(file, buffer, 1, 2) == 2);
+ // 6
+ REQUIRE(static_cast<char*>(buffer)[0] == str[4]);
+ REQUIRE(static_cast<char*>(buffer)[1] == str[5]);
+ REQUIRE(file->seek(file, -7, SEEK_CUR) == -1);
+ REQUIRE(file->seek(file, 6, SEEK_SET) == 6);
+ REQUIRE(file->seek(file, -6, SEEK_CUR) == 0);
+ }
+
+ if (file != nullptr)
+ file->close(file);
+ free(buffer);
+ VirtFs::unmountDir(prefix + "data");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getFiles zip1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getFiles("dir", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "dye.png"));
+ REQUIRE(inList(list, "hide.png"));
+
+ list.clear();
+ VirtFs::getFiles("dir2", list);
+ REQUIRE(list.size() == 4);
+ REQUIRE(inList(list, "hide.png"));
+ REQUIRE(inList(list, "paths.xml"));
+ REQUIRE(inList(list, "test.txt"));
+ REQUIRE(inList(list, "units.xml"));
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getFiles zip2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getFiles(dirSeparator, list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "dye.png"));
+ REQUIRE(inList(list, "hide.png"));
+
+ list.clear();
+ VirtFs::getFiles("1", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "test.txt"));
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getDirs1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getDirs("dir", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "1"));
+ REQUIRE(inList(list, "gpl"));
+ list.clear();
+
+ VirtFs::getDirs("dir2", list);
+ REQUIRE(list.empty());
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getDirs2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+ StringVect list;
+
+ SECTION("dir1")
+ {
+ VirtFs::mountDir(prefix + "data/test",
+ Append_false);
+
+ VirtFs::getDirs("/", list);
+// REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "dir1"));
+ REQUIRE(inList(list, "dir2"));
+ list.clear();
+
+ VirtFs::getDirs("dir1", list);
+ REQUIRE(list.empty());
+
+ VirtFs::unmountDir(prefix + "data/test");
+ }
+
+ SECTION("dir2")
+ {
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ VirtFs::getDirs("sfx", list);
+ REQUIRE(inList(list, "system"));
+ list.clear();
+
+ VirtFs::getDirs("evol", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "icons"));
+ REQUIRE(inList(list, "images"));
+
+ VirtFs::unmountDir(prefix + "data");
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getDirs3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getDirs(dirSeparator, list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "1"));
+ REQUIRE(inList(list, "gpl"));
+ list.clear();
+
+ VirtFs::getDirs("1", list);
+ REQUIRE(list.empty());
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getDirs4", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+ StringVect list;
+
+ SECTION("dir1")
+ {
+ VirtFs::mountDir2(prefix + "data",
+ "test",
+ Append_false);
+
+ VirtFs::getDirs("/", list);
+ REQUIRE(inList(list, "dir1"));
+ REQUIRE(inList(list, "dir2"));
+ list.clear();
+
+ VirtFs::getDirs("dir1", list);
+ REQUIRE(list.empty());
+
+ VirtFs::unmountDir2(prefix + "data",
+ "test");
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getFilesWithDir1", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getFilesWithDir("dir", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "dir", "dye.png"));
+ REQUIRE(inList(list, "dir", "hide.png"));
+ list.clear();
+
+ VirtFs::getFilesWithDir("dir2", list);
+ REQUIRE(list.size() == 4);
+ REQUIRE(inList(list, "dir2", "hide.png"));
+ REQUIRE(inList(list, "dir2", "paths.xml"));
+ REQUIRE(inList(list, "dir2", "test.txt"));
+ REQUIRE(inList(list, "dir2", "units.xml"));
+ list.clear();
+
+ VirtFs::getFilesWithDir(dirSeparator, list);
+ REQUIRE(list.size() > 2);
+ REQUIRE(inList(list, dirSeparator, "test.txt"));
+ REQUIRE(inList(list, dirSeparator, "units.xml"));
+ list.clear();
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getFilesWithDir2", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+ StringVect list;
+
+ SECTION("dir1")
+ {
+ VirtFs::mountDir(prefix + "data/graphics",
+ Append_false);
+
+ VirtFs::getFilesWithDir("/", list);
+ REQUIRE(list.size() <= 5);
+ VirtFs::unmountDir(prefix + "data/graphics");
+ }
+
+ SECTION("dir2")
+ {
+ VirtFs::mountDir(prefix + "data",
+ Append_false);
+
+ VirtFs::getFilesWithDir("music", list);
+ REQUIRE(list.size() <= 5);
+ REQUIRE(!list.empty());
+ REQUIRE(inList(list, "music", "keprohm.ogg"));
+ list.clear();
+
+ VirtFs::getFilesWithDir(pathJoin("evol", "icons"), list);
+#ifdef WIN32
+ REQUIRE(list.size() == 1);
+ REQUIRE(inList(list, pathJoin("evol", "icons"), "evol-client.ico"));
+#else // WIN32
+
+ REQUIRE(list.size() == 3);
+ REQUIRE(inList(list, pathJoin("evol", "icons"), "evol-client.ico"));
+ REQUIRE(inList(list, pathJoin("evol", "icons"), "evol-client.png"));
+ REQUIRE(inList(list, pathJoin("evol", "icons"), "evol-client.xpm"));
+#endif // WIN32
+
+ VirtFs::unmountDir(prefix + "data");
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getFilesWithDir3", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir",
+ Append_false);
+
+ StringVect list;
+ VirtFs::getFilesWithDir("1", list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, "1", "file1.txt"));
+ REQUIRE(inList(list, "1", "test.txt"));
+ list.clear();
+
+ VirtFs::getFilesWithDir(dirSeparator, list);
+ REQUIRE(list.size() == 2);
+ REQUIRE(inList(list, dirSeparator, "dye.png"));
+ REQUIRE(inList(list, dirSeparator, "hide.png"));
+ list.clear();
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir");
+ VirtFs::deinit();
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs1 getFilesWithDir4", "")
+{
+ VirtFs::init(".");
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+ StringVect list;
+
+ SECTION("dir1")
+ {
+ VirtFs::mountDir2(prefix + "data/graphics",
+ "sprites",
+ Append_false);
+
+ VirtFs::getFilesWithDir("/", list);
+ REQUIRE(list.size() <= 16);
+ VirtFs::unmountDir2(prefix + "data/graphics",
+ "sprites");
+ }
+
+ SECTION("dir2")
+ {
+ VirtFs::mountDir2(prefix + "data",
+ "test",
+ Append_false);
+
+ VirtFs::getFilesWithDir("dir1", list);
+ REQUIRE(list.size() <= 6);
+ REQUIRE(!list.empty());
+ REQUIRE(inList(list, "dir1", "file1.txt"));
+ list.clear();
+
+ VirtFs::unmountDir2(prefix + "data",
+ "test");
+ }
+
+ VirtFs::deinit();
+ delete2(logger);
+}
diff --git a/src/unittests/fs/virtfs/virtfs_unittest.cc b/src/unittests/fs/virtfs/virtfs_unittest.cc
new file mode 100644
index 000000000..c31f0965e
--- /dev/null
+++ b/src/unittests/fs/virtfs/virtfs_unittest.cc
@@ -0,0 +1,1054 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "fs/files.h"
+#include "fs/paths.h"
+
+#include "fs/virtfs/fs.h"
+#include "fs/virtfs/list.h"
+
+#include "utils/checkutils.h"
+#include "utils/delete2.h"
+#include "utils/foreach.h"
+
+#ifndef UNITTESTS_CATCH
+#include <algorithm>
+#endif // UNITTESTS_CATCH
+
+#include "debug.h"
+
+TEST_CASE("VirtFs dirSeparator", "")
+{
+ REQUIRE(dirSeparator != nullptr);
+ REQUIRE(VirtFs::getDirSeparator() == std::string(dirSeparator));
+ VirtFs::updateDirSeparator();
+ REQUIRE(dirSeparator != nullptr);
+ REQUIRE(VirtFs::getDirSeparator() == std::string(dirSeparator));
+}
+
+TEST_CASE("VirtFs getBaseDir", "")
+{
+ REQUIRE(VirtFs::getBaseDir() != nullptr);
+}
+
+TEST_CASE("VirtFs getUserDir", "")
+{
+ REQUIRE(VirtFs::getUserDir() != nullptr);
+}
+
+TEST_CASE("VirtFs exists1", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ REQUIRE(VirtFs::exists("test") == true);
+ REQUIRE(VirtFs::exists("test/dir1") == true);
+ REQUIRE(VirtFs::exists("test/dir") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == true);
+ REQUIRE(VirtFs::exists("test/units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml") == false);
+
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+ REQUIRE(VirtFs::exists("test") == true);
+ REQUIRE(VirtFs::exists("test/dir1") == true);
+ REQUIRE(VirtFs::exists("test/dir") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == true);
+ REQUIRE(VirtFs::exists("test/units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml") == true);
+
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+
+ REQUIRE(VirtFs::exists("test") == true);
+ REQUIRE(VirtFs::exists("test/dir1") == true);
+ REQUIRE(VirtFs::exists("test/dir") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == true);
+ REQUIRE(VirtFs::exists("test/units123.xml") == false);
+ REQUIRE(VirtFs::exists("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml") == false);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs exists2", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == false);
+ REQUIRE(VirtFs::exists("test.txt") == true);
+ REQUIRE(VirtFs::exists("dir/hide.png") == true);
+ REQUIRE(VirtFs::exists("dir/gpl") == true);
+ REQUIRE(VirtFs::exists("dir/gpl/zzz") == false);
+ REQUIRE(VirtFs::exists("units.xml") == true);
+ REQUIRE(VirtFs::exists("units.xml.") == false);
+ REQUIRE(VirtFs::exists("units.xml2") == false);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs exists3", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == false);
+ REQUIRE(VirtFs::exists("dir/brimmedhat.png"));
+ REQUIRE(VirtFs::exists("dir//brimmedhat.png"));
+ REQUIRE(VirtFs::exists("dir//hide.png"));
+ REQUIRE(VirtFs::exists("dir/1"));
+ REQUIRE(VirtFs::exists("dir/gpl"));
+ REQUIRE(VirtFs::exists("dir/dye.png"));
+ REQUIRE(VirtFs::exists("dir/2") == false);
+ REQUIRE(VirtFs::exists("dir2/2") == false);
+ REQUIRE(VirtFs::exists("dir2/paths.xml"));
+
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs exists4", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+ VirtFs::mountDirSilent(prefix + "data/test", Append_false);
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == false);
+ REQUIRE(VirtFs::exists("dir/brimmedhat.png"));
+ REQUIRE(VirtFs::exists("dir//brimmedhat.png"));
+ REQUIRE(VirtFs::exists("dir//hide.png"));
+ REQUIRE(VirtFs::exists("dir/1") == false);
+ REQUIRE(VirtFs::exists("dir/gpl") == false);
+ REQUIRE(VirtFs::exists("dir/dye.png") == false);
+ REQUIRE(VirtFs::exists("dir/2") == false);
+ REQUIRE(VirtFs::exists("dir2/2") == false);
+ REQUIRE(VirtFs::exists("dir2/paths.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml"));
+ REQUIRE(VirtFs::exists("dir1/file1.txt"));
+ REQUIRE(VirtFs::exists("dir2/file2.txt"));
+ REQUIRE(VirtFs::exists("dir2/file3.txt") == false);
+
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ VirtFs::unmountDirSilent(prefix + "data/test");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs exists5", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ const std::string realDir = getRealPath(prefix + "data");
+ logger->log("real dir: " + realDir);
+ REQUIRE_FALSE(VirtFs::exists(realDir));
+
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs exists6", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir",
+ Append_false);
+
+ REQUIRE(VirtFs::exists("test") == false);
+ REQUIRE(VirtFs::exists("test/units.xml") == false);
+ REQUIRE(VirtFs::exists("test.txt") == false);
+ REQUIRE(VirtFs::exists("dir/hide.png") == false);
+ REQUIRE(VirtFs::exists("dir/gpl") == false);
+ REQUIRE(VirtFs::exists("dir/gpl/zzz") == false);
+ REQUIRE(VirtFs::exists("units.xml") == false);
+ REQUIRE(VirtFs::exists("units.xml.") == false);
+ REQUIRE(VirtFs::exists("units.xml2") == false);
+ REQUIRE(VirtFs::exists("hide.png"));
+ REQUIRE(VirtFs::exists("dye.png"));
+ REQUIRE(VirtFs::exists("gpl"));
+ REQUIRE(VirtFs::exists("gpl/zzz") == false);
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir");
+ delete2(logger);
+}
+
+static void removeTemp(StringVect &restrict list)
+{
+ int cnt = 0;
+ std::sort(list.begin(), list.end());
+
+ FOR_EACH (StringVectIter, it, list)
+ {
+ if (*it != "serverlistplus.xml.part")
+ {
+ logger->log("file: %d %s",
+ cnt,
+ (*it).c_str());
+ cnt ++;
+ }
+ }
+
+ FOR_EACH (StringVectIter, it, list)
+ {
+ if (*it == "serverlistplus.xml.part")
+ {
+ list.erase(it);
+ return;
+ }
+ }
+}
+
+static bool inList(const VirtFs::List *const list,
+ const std::string &name)
+{
+ FOR_EACH (StringVectCIter, it, list->names)
+ {
+ if (*it == name)
+ return true;
+ }
+ return false;
+}
+
+TEST_CASE("VirtFs enumerateFiles1", "")
+{
+ logger = new Logger;
+
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ const int cnt1 = VirtFs::exists("test/test2.txt") ? 28 : 27;
+ const int cnt2 = 28;
+
+ VirtFs::permitLinks(false);
+ list = VirtFs::enumerateFiles("test");
+ removeTemp(list->names);
+ const size_t sz = list->names.size();
+ REQUIRE(sz == cnt1);
+ VirtFs::freeList(list);
+
+ VirtFs::permitLinks(true);
+ list = VirtFs::enumerateFiles("test");
+ removeTemp(list->names);
+ REQUIRE(list->names.size() == cnt2);
+ VirtFs::freeList(list);
+
+ VirtFs::permitLinks(false);
+ list = VirtFs::enumerateFiles("test");
+ removeTemp(list->names);
+ REQUIRE(list->names.size() == cnt1);
+ VirtFs::freeList(list);
+
+ list = VirtFs::enumerateFiles("test/units.xml");
+ removeTemp(list->names);
+ REQUIRE(list->names.empty());
+ VirtFs::freeList(list);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs enumerateFiles2", "")
+{
+ logger = new Logger;
+
+ VirtFs::mountDirSilent("data/test/dir1",
+ Append_false);
+ VirtFs::mountDirSilent("../data/test/dir1",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 5);
+ VirtFs::freeList(list);
+
+ VirtFs::unmountDirSilent("data/test/dir1");
+ VirtFs::unmountDirSilent("../data/test/dir1");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs enumerateFiles3", "")
+{
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test.zip",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 1);
+ REQUIRE(inList(list, "dir"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs enumerateFiles4", "")
+{
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("/");
+ REQUIRE(list->names.size() == 4);
+ REQUIRE(inList(list, "dir"));
+ REQUIRE(inList(list, "dir2"));
+ REQUIRE(inList(list, "test.txt"));
+ REQUIRE(inList(list, "units.xml"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs enumerateFiles5", "")
+{
+ logger = new Logger;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip",
+ Append_false);
+ VirtFs::mountDirSilent(prefix + "data/test", Append_false);
+
+ VirtFs::List *list = nullptr;
+
+ list = VirtFs::enumerateFiles("dir2");
+ REQUIRE(inList(list, "file1.txt"));
+ REQUIRE(inList(list, "file2.txt"));
+ REQUIRE(inList(list, "hide.png"));
+ REQUIRE(inList(list, "paths.xml"));
+ REQUIRE(inList(list, "test.txt"));
+ REQUIRE(inList(list, "units.xml"));
+ VirtFs::freeList(list);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDirSilent(prefix + "data/test");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs isDirectory1", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("test//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test//units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test") == true);
+ REQUIRE(VirtFs::isDirectory("test/") == true);
+ REQUIRE(VirtFs::isDirectory("test//") == true);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == true);
+ REQUIRE(VirtFs::isDirectory("test//dir1") == true);
+ REQUIRE(VirtFs::isDirectory("test//dir1/") == true);
+ REQUIRE(VirtFs::isDirectory("test//dir1//") == true);
+ REQUIRE(VirtFs::isDirectory("test/dir1/") == true);
+ REQUIRE(VirtFs::isDirectory("test/dir1//") == true);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("testQ/") == false);
+ REQUIRE(VirtFs::isDirectory("testQ//") == false);
+
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("test//units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test") == true);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == true);
+
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test/units123.xml") == false);
+ REQUIRE(VirtFs::isDirectory("tesQ/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("units.xml/") == false);
+ REQUIRE(VirtFs::isDirectory("test") == true);
+ REQUIRE(VirtFs::isDirectory("test/") == true);
+ REQUIRE(VirtFs::isDirectory("testQ") == false);
+ REQUIRE(VirtFs::isDirectory("test/dir1") == true);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs isDirectory2", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("dir") == true);
+ REQUIRE(VirtFs::isDirectory("dir/") == true);
+ REQUIRE(VirtFs::isDirectory("dir//") == true);
+ REQUIRE(VirtFs::isDirectory("dir2") == true);
+ REQUIRE(VirtFs::isDirectory("dir3") == false);
+ REQUIRE(VirtFs::isDirectory("test.txt") == false);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs isDirectory3", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data", Append_false);
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+
+ REQUIRE(VirtFs::isDirectory("test/units.xml") == false);
+ REQUIRE(VirtFs::isDirectory("test"));
+ REQUIRE(VirtFs::isDirectory("test//dye.png") == false);
+ REQUIRE(VirtFs::isDirectory("dir"));
+ REQUIRE(VirtFs::isDirectory("dir/"));
+ REQUIRE(VirtFs::isDirectory("dir//"));
+ REQUIRE(VirtFs::isDirectory("dir2"));
+ REQUIRE(VirtFs::isDirectory("dir3") == false);
+ REQUIRE(VirtFs::isDirectory("test.txt") == false);
+ REQUIRE(VirtFs::isDirectory("dir/hide.png") == false);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs openRead1", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file == nullptr);
+// file = VirtFs::openRead("test");
+// REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+// file = VirtFs::openRead("test");
+// REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("test/units123.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("tesQ/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file == nullptr);
+// file = VirtFs::openRead("test");
+// REQUIRE(file == nullptr);
+ file = VirtFs::openRead("testQ");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs openRead2", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/hide.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir//hide.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs openRead3", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+ VirtFs::mountDir(prefix + "data/test", Append_false);
+
+ VirtFs::File *file = nullptr;
+
+ file = VirtFs::openRead("test/units.xml");
+ REQUIRE(file == nullptr);
+ file = VirtFs::openRead("units.xml");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/hide.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir//hide.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/dye.png");
+ REQUIRE(file != nullptr);
+ VirtFs::close(file);
+ file = VirtFs::openRead("dir/dye.pn_");
+ REQUIRE(file == nullptr);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs getRealDir1", "")
+{
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ REQUIRE(VirtFs::getRealDir(".").empty());
+ REQUIRE(VirtFs::getRealDir("..").empty());
+ const bool dir1 = VirtFs::mountDirSilent("data", Append_false);
+ REQUIRE((dir1 || VirtFs::mountDirSilent("../data", Append_false))
+ == true);
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "data");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "../data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "../data");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "data");
+ REQUIRE(VirtFs::getRealDir("test.txt") ==
+ "data" + sep + "test");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("test") == ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test.txt") ==
+ ".." + sep + "data" + sep + "test");
+ }
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ if (dir1 == true)
+ {
+ VirtFs::mountZip("data/test/test.zip", Append_false);
+ REQUIRE(VirtFs::getRealDir("dir/brimmedhat.png") ==
+ "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getRealDir("hide.png") ==
+ "data" + sep + "test");
+ }
+ else
+ {
+ VirtFs::mountZip("../data/test/test.zip", Append_false);
+ REQUIRE(VirtFs::getRealDir("dir/brimmedhat.png") ==
+ ".." + sep + "data" + sep + "test" + sep + "test.zip");
+ REQUIRE(VirtFs::getRealDir("hide.png") ==
+ ".." + sep + "data" + sep + "test");
+ }
+
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+
+ if (dir1 == true)
+ {
+ REQUIRE(VirtFs::getRealDir("test") == "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ "data");
+ REQUIRE(VirtFs::getRealDir("dir/hide.png") ==
+ "data" + sep + "test" + sep + "test.zip");
+ }
+ else
+ {
+ REQUIRE(VirtFs::getRealDir("test") == ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("test/test.txt") ==
+ ".." + sep + "data");
+ REQUIRE(VirtFs::getRealDir("dir/hide.png") ==
+ ".." + sep + "data" + sep + "test" + sep + "test.zip");
+ }
+ REQUIRE(VirtFs::exists("dir/hide.png"));
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ if (dir1 == true)
+ VirtFs::unmountZip("data/test/test.zip");
+ else
+ VirtFs::unmountZip("../data/test/test.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs getrealDir2", "")
+{
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+ VirtFs::mountDir(prefix + "data/test", Append_false);
+ VirtFs::mountDir(prefix + "data", Append_false);
+
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ REQUIRE(VirtFs::getRealDir("dir1/file1.txt") ==
+ prefix + "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("hide.png") ==
+ prefix + "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("dir//hide.png") ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+ REQUIRE(VirtFs::getRealDir("dir/1//test.txt") ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ VirtFs::unmountDir(prefix + "data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs getrealDir3", "")
+{
+ logger = new Logger();
+ const std::string sep = dirSeparator;
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip2(prefix + "data/test/test2.zip",
+ "dir",
+ Append_false);
+ VirtFs::mountDir(prefix + "data/test", Append_false);
+
+ REQUIRE(VirtFs::getRealDir("zzz").empty());
+
+ REQUIRE(VirtFs::getRealDir("dir1/file1.txt") ==
+ prefix + "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("hide.png") ==
+ prefix + "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("hide.png") ==
+ prefix + "data" + sep + "test");
+ REQUIRE(VirtFs::getRealDir("1//test.txt") ==
+ prefix + "data" + sep + "test" + sep + "test2.zip");
+
+ VirtFs::unmountZip2(prefix + "data/test/test2.zip",
+ "dir");
+ VirtFs::unmountDir(prefix + "data/test");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs permitLinks1", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ const int cnt1 = VirtFs::exists("test/test2.txt") ? 26 : 25;
+ const int cnt2 = 26;
+
+ StringVect list;
+ VirtFs::permitLinks(false);
+ VirtFs::getFiles("test", list);
+ removeTemp(list);
+ const size_t sz = list.size();
+ REQUIRE(sz == cnt1);
+
+ list.clear();
+ VirtFs::permitLinks(true);
+ VirtFs::getFiles("test", list);
+ removeTemp(list);
+ REQUIRE(list.size() == cnt2);
+
+ list.clear();
+ VirtFs::permitLinks(false);
+ VirtFs::getFiles("test", list);
+ removeTemp(list);
+ REQUIRE(list.size() == cnt1);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs permitLinks2", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent2("data",
+ "test",
+ Append_false);
+ VirtFs::mountDirSilent2("../data",
+ "test",
+ Append_false);
+
+ const int cnt1 = VirtFs::exists("test2.txt") ? 26 : 25;
+ const int cnt2 = 26;
+
+ StringVect list;
+ VirtFs::permitLinks(false);
+ VirtFs::getFiles(dirSeparator, list);
+ removeTemp(list);
+ const size_t sz = list.size();
+ REQUIRE(sz == cnt1);
+
+ list.clear();
+ VirtFs::permitLinks(true);
+ VirtFs::getFiles(dirSeparator, list);
+ removeTemp(list);
+ REQUIRE(list.size() == cnt2);
+
+ list.clear();
+ VirtFs::permitLinks(false);
+ VirtFs::getFiles(dirSeparator, list);
+ removeTemp(list);
+ REQUIRE(list.size() == cnt1);
+
+ VirtFs::unmountDirSilent2("data",
+ "test");
+ VirtFs::unmountDirSilent2("../data",
+ "test");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs read1", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ VirtFs::File *file = VirtFs::openRead("test/test.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == false);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ VirtFs::close(file);
+ free(buffer);
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs read2", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+
+ VirtFs::File *file = VirtFs::openRead("dir2/test.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == false);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ VirtFs::close(file);
+ free(buffer);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs read3", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test2.zip", Append_false);
+ VirtFs::mountDir(prefix + "data", Append_false);
+
+ VirtFs::File *file = VirtFs::openRead("dir2/test.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == false);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ VirtFs::close(file);
+ free(buffer);
+
+ VirtFs::unmountZip(prefix + "data/test/test2.zip");
+ VirtFs::unmountDir(prefix + "data");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs read4", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDir(prefix + "data/test", Append_true);
+ VirtFs::mountZip(prefix + "data/test/test5.zip", Append_true);
+
+ VirtFs::File *file = VirtFs::openRead("dir1/file1.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 1\ntest line 2") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == false);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 2") == 0);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ VirtFs::close(file);
+ free(buffer);
+
+ VirtFs::unmountZip(prefix + "data/test/test5.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ delete2(logger);
+}
+
+TEST_CASE("VirtFs read5", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountZip(prefix + "data/test/test5.zip", Append_true);
+ VirtFs::mountDir(prefix + "data/test", Append_true);
+
+ VirtFs::File *file = VirtFs::openRead("dir1/file1.txt");
+ REQUIRE(file != nullptr);
+ REQUIRE(VirtFs::fileLength(file) == 23);
+ const int fileSize = VirtFs::fileLength(file);
+
+ void *restrict buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::read(file, buffer, 1, fileSize) == fileSize);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 3\ntest line 4") == 0);
+ REQUIRE(VirtFs::tell(file) == fileSize);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ free(buffer);
+ buffer = calloc(fileSize + 1, 1);
+ REQUIRE(VirtFs::seek(file, 12) != 0);
+ REQUIRE(VirtFs::eof(file) == false);
+ REQUIRE(VirtFs::tell(file) == 12);
+ REQUIRE(VirtFs::read(file, buffer, 1, 11) == 11);
+ REQUIRE(strcmp(static_cast<char*>(buffer),
+ "test line 4") == 0);
+ REQUIRE(VirtFs::eof(file) == true);
+
+ VirtFs::close(file);
+ free(buffer);
+
+ VirtFs::unmountZip(prefix + "data/test/test5.zip");
+ VirtFs::unmountDir(prefix + "data/test");
+ delete2(logger);
+}
diff --git a/src/unittests/fs/virtfs/zip_unittest.cc b/src/unittests/fs/virtfs/zip_unittest.cc
new file mode 100644
index 000000000..10b4b52b5
--- /dev/null
+++ b/src/unittests/fs/virtfs/zip_unittest.cc
@@ -0,0 +1,304 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "logger.h"
+
+#include "fs/files.h"
+
+#include "fs/virtfs/fszip.h"
+#include "fs/virtfs/zipentry.h"
+#include "fs/virtfs/zipreader.h"
+#include "fs/virtfs/ziplocalheader.h"
+
+#include "utils/delete2.h"
+
+#include "debug.h"
+
+extern const char *dirSeparator;
+
+TEST_CASE("Zip readArchiveInfo", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ const std::string sep = dirSeparator;
+ if (Files::existsLocal(name) == false)
+ prefix = "../";
+
+ SECTION("test.zip")
+ {
+ name = prefix + "data/test/test.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 2);
+ REQUIRE(entry->root == name);
+ REQUIRE(headers[0]->fileName == "dir" + sep + "hide.png");
+ REQUIRE(headers[0]->compressSize == 365);
+ REQUIRE(headers[0]->uncompressSize == 368);
+ REQUIRE(headers[1]->fileName == "dir" + sep + "brimmedhat.png");
+ REQUIRE(headers[1]->compressSize == 1959);
+ REQUIRE(headers[1]->uncompressSize == 1959);
+
+ delete entry;
+ }
+
+ SECTION("test2.zip")
+ {
+ name = prefix + "data/test/test2.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 11);
+ REQUIRE(entry->root == name);
+ REQUIRE(headers[0]->fileName == "test.txt");
+ REQUIRE(headers[0]->compressSize == 17);
+ REQUIRE(headers[0]->uncompressSize == 23);
+
+ REQUIRE(headers[1]->fileName == "dir2" + sep + "hide.png");
+ REQUIRE(headers[1]->compressSize == 365);
+ REQUIRE(headers[1]->uncompressSize == 368);
+
+ REQUIRE(headers[2]->fileName == "dir2" + sep + "test.txt");
+ REQUIRE(headers[2]->compressSize == 17);
+ REQUIRE(headers[2]->uncompressSize == 23);
+
+ REQUIRE(headers[3]->fileName == "dir2" + sep + "paths.xml");
+ REQUIRE(headers[3]->compressSize == 154);
+ REQUIRE(headers[3]->uncompressSize == 185);
+
+ REQUIRE(headers[4]->fileName == "dir2" + sep + "units.xml");
+ REQUIRE(headers[4]->compressSize == 202);
+ REQUIRE(headers[4]->uncompressSize == 306);
+
+ REQUIRE(headers[5]->fileName == "dir" + sep + "hide.png");
+ REQUIRE(headers[5]->compressSize == 365);
+ REQUIRE(headers[5]->uncompressSize == 368);
+
+ REQUIRE(headers[6]->fileName ==
+ "dir" + sep + "1" + sep + "test.txt");
+ REQUIRE(headers[6]->compressSize == 17);
+ REQUIRE(headers[6]->uncompressSize == 23);
+
+ REQUIRE(headers[7]->fileName ==
+ "dir" + sep + "1" + sep + "file1.txt");
+ REQUIRE(headers[7]->compressSize == 17);
+ REQUIRE(headers[7]->uncompressSize == 23);
+
+ REQUIRE(headers[8]->fileName ==
+ "dir" + sep + "gpl" + sep + "palette.gpl");
+ REQUIRE(headers[8]->compressSize == 128);
+ REQUIRE(headers[8]->uncompressSize == 213);
+
+ REQUIRE(headers[9]->fileName ==
+ "dir" + sep + "dye.png");
+ REQUIRE(headers[9]->compressSize == 794);
+ REQUIRE(headers[9]->uncompressSize == 794);
+
+ REQUIRE(headers[10]->fileName == "units.xml");
+ REQUIRE(headers[10]->compressSize == 202);
+ REQUIRE(headers[10]->uncompressSize == 306);
+
+ delete entry;
+ }
+
+ SECTION("test3.zip")
+ {
+ name = prefix + "data/test/test3.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 2);
+ REQUIRE(entry->root == name);
+ REQUIRE(headers[0]->fileName == "test.txt");
+ REQUIRE(headers[0]->compressSize == 17);
+ REQUIRE(headers[0]->uncompressSize == 23);
+ REQUIRE(headers[1]->fileName == "units.xml");
+ REQUIRE(headers[1]->compressSize == 202);
+ REQUIRE(headers[1]->uncompressSize == 306);
+
+ delete entry;
+ }
+
+ SECTION("test4.zip")
+ {
+ name = prefix + "data/test/test4.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(entry->root == name);
+ REQUIRE(headers.empty());
+
+ delete entry;
+ }
+
+ delete2(logger);
+}
+
+TEST_CASE("Zip readCompressedFile", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../";
+
+ SECTION("empty")
+ {
+ REQUIRE_THROWS(VirtFs::ZipReader::readCompressedFile(nullptr));
+ }
+
+ SECTION("test2.zip")
+ {
+ name = prefix + "data/test/test2.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 11);
+ REQUIRE(entry->root == name);
+ // test.txt
+ uint8_t *const buf = VirtFs::ZipReader::readCompressedFile(headers[0]);
+ REQUIRE(buf != nullptr);
+ delete [] buf;
+ delete entry;
+ }
+
+ delete2(logger);
+}
+
+TEST_CASE("Zip readFile", "")
+{
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../";
+
+ SECTION("empty")
+ {
+ REQUIRE_THROWS(VirtFs::ZipReader::readFile(nullptr));
+ }
+
+ SECTION("test.zip")
+ {
+ name = prefix + "data/test/test.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 2);
+ REQUIRE(entry->root == name);
+ for (int f = 0; f < 2; f ++)
+ {
+ logger->log("test header: %s, %u, %u",
+ headers[f]->fileName.c_str(),
+ headers[f]->compressSize,
+ headers[f]->uncompressSize);
+ const uint8_t *const buf = VirtFs::ZipReader::readFile(headers[f]);
+ REQUIRE(buf != nullptr);
+ delete [] buf;
+ }
+ delete entry;
+ }
+
+ SECTION("test2.zip")
+ {
+ name = prefix + "data/test/test2.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 11);
+ REQUIRE(entry->root == name);
+ // test.txt
+ const uint8_t *buf = VirtFs::ZipReader::readFile(headers[0]);
+ REQUIRE(buf != nullptr);
+ const std::string str = std::string(reinterpret_cast<const char*>(buf),
+ headers[0]->uncompressSize);
+ REQUIRE(str == "test line 1\ntest line 2");
+ delete [] buf;
+ for (int f = 0; f < 11; f ++)
+ {
+ logger->log("test header: %s, %u, %u",
+ headers[f]->fileName.c_str(),
+ headers[f]->compressSize,
+ headers[f]->uncompressSize);
+ buf = VirtFs::ZipReader::readFile(headers[f]);
+ REQUIRE(buf != nullptr);
+ delete [] buf;
+ }
+ delete entry;
+ }
+
+ SECTION("test3.zip")
+ {
+ name = prefix + "data/test/test3.zip";
+
+ VirtFs::ZipEntry *const entry = new VirtFs::ZipEntry(name,
+ dirSeparator,
+ VirtFs::FsZip::getFuncs());
+ std::vector<VirtFs::ZipLocalHeader*> &headers = entry->mHeaders;
+
+ REQUIRE(VirtFs::ZipReader::readArchiveInfo(entry));
+ REQUIRE(headers.size() == 2);
+ REQUIRE(entry->root == name);
+ for (int f = 0; f < 2; f ++)
+ {
+ logger->log("test header: %s, %u, %u",
+ headers[f]->fileName.c_str(),
+ headers[f]->compressSize,
+ headers[f]->uncompressSize);
+ const uint8_t *const buf = VirtFs::ZipReader::readFile(headers[f]);
+ REQUIRE(buf != nullptr);
+ delete [] buf;
+ }
+ delete entry;
+ }
+
+ delete2(logger);
+}
diff --git a/src/unittests/gui/fonts/textchunklist_unittest.cc b/src/unittests/gui/fonts/textchunklist_unittest.cc
new file mode 100644
index 000000000..c8df87455
--- /dev/null
+++ b/src/unittests/gui/fonts/textchunklist_unittest.cc
@@ -0,0 +1,548 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "gui/fonts/font.h"
+#include "gui/fonts/textchunk.h"
+
+#include "debug.h"
+
+TEST_CASE("TextChunkList empty", "TextChunkList")
+{
+ TextChunkList list;
+
+ REQUIRE(0 == list.size);
+ REQUIRE(nullptr == list.start);
+ REQUIRE(nullptr == list.end);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList add 1", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 3, 4), nullptr);
+
+ list.insertFirst(chunk);
+
+ REQUIRE(1 == list.size);
+ REQUIRE(chunk == list.start);
+ REQUIRE(chunk == list.end);
+ REQUIRE(nullptr == chunk->prev);
+ REQUIRE(nullptr == chunk->next);
+
+ REQUIRE(1 == list.search.size());
+ REQUIRE(chunk == (*list.search.find(TextChunkSmall(
+ chunk->text, chunk->color, chunk->color2))).second);
+
+ REQUIRE(1 == list.searchWidth.size());
+ REQUIRE(chunk == (*list.searchWidth.find(chunk->text)).second);
+ delete chunk;
+}
+
+TEST_CASE("TextChunkList add 2", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(3, 4, 5), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test",
+ Color(2, 3, 4), Color(4, 5, 6), nullptr);
+
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+
+ REQUIRE(2 == list.size);
+ REQUIRE(chunk1 == list.start);
+ REQUIRE(chunk2 == list.end);
+ REQUIRE(nullptr == chunk1->prev);
+ REQUIRE(chunk2 == chunk1->next);
+ REQUIRE(chunk1 == chunk2->prev);
+ REQUIRE(nullptr == chunk2->next);
+
+ REQUIRE(2 == list.search.size());
+ REQUIRE(chunk1 == (*list.search.find(TextChunkSmall(
+ chunk1->text, chunk1->color, chunk1->color2))).second);
+ REQUIRE(chunk2 == (*list.search.find(TextChunkSmall(
+ chunk2->text, chunk2->color, chunk2->color2))).second);
+
+ REQUIRE(1 == list.searchWidth.size());
+ REQUIRE(chunk1 == (*list.searchWidth.find(chunk1->text)).second);
+ delete chunk1;
+ delete chunk2;
+}
+
+TEST_CASE("TextChunkList addRemoveBack 1", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk = new TextChunk("test",
+ Color(1, 2, 3), Color(1, 2, 3), nullptr);
+
+ list.insertFirst(chunk);
+ list.removeBack();
+
+ REQUIRE(0 == list.size);
+ REQUIRE(nullptr == list.start);
+ REQUIRE(nullptr == list.end);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList addRemoveBack 2", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(1, 2, 3), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test2",
+ Color(1, 2, 4), Color(1, 2, 5), nullptr);
+
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+ list.removeBack();
+
+ REQUIRE(1 == list.size);
+ REQUIRE(chunk1 == list.start);
+ REQUIRE(chunk1 == list.end);
+ REQUIRE(nullptr == chunk1->prev);
+ REQUIRE(nullptr == chunk1->next);
+
+ REQUIRE(1 == list.search.size());
+ REQUIRE(chunk1 == (*list.search.find(TextChunkSmall(
+ chunk1->text, chunk1->color, chunk1->color2))).second);
+
+ REQUIRE(1 == list.searchWidth.size());
+ REQUIRE(chunk1 == (*list.searchWidth.find(chunk1->text)).second);
+ delete chunk1;
+}
+
+TEST_CASE("TextChunkList addRemoveBack 3", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(1, 2, 3), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test2",
+ Color(2, 3, 4), Color(2, 3, 4), nullptr);
+
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+ list.removeBack(2);
+
+ REQUIRE(0 == list.size);
+ REQUIRE(nullptr == list.start);
+ REQUIRE(nullptr == list.end);
+
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList addRemoveBack 4", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(1, 2, 3), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test2",
+ Color(2, 3, 4), Color(2, 3, 4), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test",
+ Color(3, 4, 5), Color(3, 4, 5), nullptr);
+
+ list.insertFirst(chunk3);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk1);
+ list.removeBack();
+ list.removeBack();
+
+ REQUIRE(1 == list.size);
+ REQUIRE(chunk1 == list.start);
+ REQUIRE(chunk1 == list.end);
+ REQUIRE(nullptr == chunk1->prev);
+ REQUIRE(nullptr == chunk1->next);
+
+ REQUIRE(1 == list.search.size());
+ REQUIRE(chunk1 == (*list.search.find(TextChunkSmall(
+ chunk1->text, chunk1->color, chunk1->color2))).second);
+
+ REQUIRE(list.searchWidth.empty());
+ delete chunk1;
+}
+
+TEST_CASE("TextChunkList moveToFirst 1", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 3, 4), nullptr);
+
+ list.insertFirst(chunk);
+ list.moveToFirst(chunk);
+
+ REQUIRE(1 == list.size);
+ REQUIRE(chunk == list.start);
+ REQUIRE(chunk == list.end);
+ REQUIRE(nullptr == chunk->prev);
+ REQUIRE(nullptr == chunk->next);
+ delete chunk;
+}
+
+TEST_CASE("TextChunkList moveToFirst 2", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(1, 2, 3), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test",
+ Color(2, 3, 4), Color(1, 2, 3), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.moveToFirst(chunk1);
+
+ REQUIRE(2 == list.size);
+ REQUIRE(chunk1 == list.start);
+ REQUIRE(chunk2 == list.end);
+ REQUIRE(nullptr == chunk1->prev);
+ REQUIRE(chunk2 == chunk1->next);
+ REQUIRE(chunk1 == chunk2->prev);
+ REQUIRE(nullptr == chunk2->next);
+ delete chunk1;
+ delete chunk2;
+}
+
+TEST_CASE("TextChunkList moveToFirst 3", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(1, 2, 3), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test",
+ Color(1, 2, 4), Color(1, 2, 3), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test",
+ Color(1, 2, 5), Color(1, 2, 3), nullptr);
+
+ list.insertFirst(chunk3);
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.moveToFirst(chunk1);
+
+ REQUIRE(3 == list.size);
+ REQUIRE(chunk1 == list.start);
+ REQUIRE(chunk3 == list.end);
+ REQUIRE(nullptr == chunk1->prev);
+ REQUIRE(chunk2 == chunk1->next);
+ REQUIRE(chunk1 == chunk2->prev);
+ REQUIRE(chunk3 == chunk2->next);
+ REQUIRE(chunk2 == chunk3->prev);
+ REQUIRE(nullptr == chunk3->next);
+ delete chunk1;
+ delete chunk2;
+ delete chunk3;
+}
+
+TEST_CASE("TextChunkList moveToFirst 4", "TextChunkList")
+{
+ TextChunkList list;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(), Color(), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test2",
+ Color(), Color(), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test3",
+ Color(), Color(), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk3);
+ list.insertFirst(chunk2);
+ list.moveToFirst(chunk1);
+
+ REQUIRE(3 == list.size);
+ REQUIRE(chunk1 == list.start);
+ REQUIRE(chunk3 == list.end);
+ REQUIRE(nullptr == chunk1->prev);
+ REQUIRE(chunk2 == chunk1->next);
+ REQUIRE(chunk1 == chunk2->prev);
+ REQUIRE(chunk3 == chunk2->next);
+ REQUIRE(chunk2 == chunk3->prev);
+ REQUIRE(nullptr == chunk3->next);
+ delete chunk1;
+ delete chunk2;
+ delete chunk3;
+}
+
+TEST_CASE("TextChunkList clear 1", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk = new TextChunk("test",
+ Color(), Color(), nullptr);
+
+ list.insertFirst(chunk);
+ list.clear();
+
+ REQUIRE(0 == list.size);
+ REQUIRE(nullptr == list.start);
+ REQUIRE(nullptr == list.end);
+ REQUIRE(chunksLeft == textChunkCnt);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList clear 2", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 0), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 1), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 2), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.clear();
+
+ REQUIRE(0 == list.size);
+ REQUIRE(nullptr == list.start);
+ REQUIRE(nullptr == list.end);
+ REQUIRE(chunksLeft == textChunkCnt);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList clear 3", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 0), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 1), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 2), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.moveToFirst(chunk1);
+ REQUIRE((chunksLeft + 3) == textChunkCnt);
+ REQUIRE(3 == list.search.size());
+ REQUIRE(1 == list.searchWidth.size());
+
+ list.removeBack();
+ REQUIRE((chunksLeft + 2) == textChunkCnt);
+ REQUIRE(2 == list.search.size());
+ REQUIRE(list.searchWidth.empty());
+
+ list.clear();
+ REQUIRE(chunksLeft == textChunkCnt);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList clear 4", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk1 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 0), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test",
+ Color(1, 2, 3), Color(2, 0, 1), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test3",
+ Color(1, 2, 3), Color(2, 0, 2), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.moveToFirst(chunk2);
+ REQUIRE((chunksLeft + 3) == textChunkCnt);
+ REQUIRE(3 == list.search.size());
+ REQUIRE(2 == list.searchWidth.size());
+
+ list.removeBack(2);
+ REQUIRE((chunksLeft + 1) == textChunkCnt);
+ REQUIRE(1 == list.search.size());
+ REQUIRE(list.searchWidth.empty());
+
+ list.clear();
+ REQUIRE(chunksLeft == textChunkCnt);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList remove 1", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk = new TextChunk("test",
+ Color(), Color(), nullptr);
+
+ list.insertFirst(chunk);
+ list.remove(chunk);
+ delete chunk;
+
+ REQUIRE(0 == list.size);
+ REQUIRE(nullptr == list.start);
+ REQUIRE(nullptr == list.end);
+ REQUIRE(chunksLeft == textChunkCnt);
+ REQUIRE(list.search.empty());
+ REQUIRE(list.searchWidth.empty());
+}
+
+TEST_CASE("TextChunkList remove 2", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk1 = new TextChunk("test1",
+ Color(1, 2, 3), Color(2, 0, 0), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test2",
+ Color(1, 2, 3), Color(2, 0, 1), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test3",
+ Color(1, 2, 3), Color(2, 0, 2), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.remove(chunk1);
+ delete chunk1;
+
+ REQUIRE(2 == list.size);
+ REQUIRE(chunk3 == list.start);
+ REQUIRE(chunk2 == list.end);
+ REQUIRE((chunksLeft + 2) == textChunkCnt);
+ REQUIRE(2 == list.search.size());
+ REQUIRE(2 == list.searchWidth.size());
+ delete chunk2;
+ delete chunk3;
+}
+
+TEST_CASE("TextChunkList remove 3", "TextChunkList")
+{
+ TextChunkList list;
+ const int chunksLeft = textChunkCnt;
+
+ TextChunk *const chunk1 = new TextChunk("test1",
+ Color(1, 2, 3), Color(2, 0, 0), nullptr);
+ TextChunk *const chunk2 = new TextChunk("test2",
+ Color(1, 2, 3), Color(2, 0, 1), nullptr);
+ TextChunk *const chunk3 = new TextChunk("test3",
+ Color(1, 2, 3), Color(2, 0, 2), nullptr);
+
+ list.insertFirst(chunk1);
+ list.insertFirst(chunk2);
+ list.insertFirst(chunk3);
+ list.remove(chunk2);
+ delete chunk2;
+
+ REQUIRE(2 == list.size);
+ REQUIRE(chunk3 == list.start);
+ REQUIRE(chunk1 == list.end);
+ REQUIRE((chunksLeft + 2) == textChunkCnt);
+ REQUIRE(2 == list.search.size());
+ REQUIRE(2 == list.searchWidth.size());
+ delete chunk1;
+ delete chunk3;
+}
+
+TEST_CASE("TextChunkList sort 1", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item3("test line2",
+ Color(1, 2, 3), Color(1, 2, 3));
+ REQUIRE(false == (item1 < item2));
+ REQUIRE(false == (item2 < item1));
+ REQUIRE(item1 < item3);
+ REQUIRE(false == (item3 < item1));
+}
+
+TEST_CASE("TextChunkList sort 2", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(2, 3, 4), Color(1, 2, 3));
+ REQUIRE(item1 < item2);
+ REQUIRE(false == (item2 < item1));
+}
+
+TEST_CASE("TextChunkList sort 3", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(1, 3, 4), Color(1, 2, 3));
+ REQUIRE(item1 < item2);
+ REQUIRE(false == (item2 < item1));
+}
+
+TEST_CASE("TextChunkList sort 4", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(1, 2, 4), Color(1, 2, 3));
+ REQUIRE(item1 < item2);
+ REQUIRE(false == (item2 < item1));
+}
+
+TEST_CASE("TextChunkList sort 5", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(1, 2, 3), Color(2, 2, 3));
+ REQUIRE(item1 < item2);
+ REQUIRE(false == (item2 < item1));
+}
+
+TEST_CASE("TextChunkList sort 6", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(1, 2, 3), Color(1, 3, 3));
+ REQUIRE(item1 < item2);
+ REQUIRE(false == (item2 < item1));
+}
+
+TEST_CASE("TextChunkList sort 7", "TextChunkList")
+{
+ TextChunkSmall item1("test line1",
+ Color(1, 2, 3), Color(1, 2, 3));
+ TextChunkSmall item2("test line1",
+ Color(1, 2, 3), Color(1, 2, 4));
+ REQUIRE(item1 < item2);
+ REQUIRE(false == (item2 < item1));
+}
diff --git a/src/unittests/gui/widgets/browserbox_unittest.cc b/src/unittests/gui/widgets/browserbox_unittest.cc
new file mode 100644
index 000000000..128c7a52c
--- /dev/null
+++ b/src/unittests/gui/widgets/browserbox_unittest.cc
@@ -0,0 +1,211 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "configmanager.h"
+#include "dirs.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+
+#include "gui/fonts/font.h"
+
+#include "gui/widgets/browserbox.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "debug.h"
+
+TEST_CASE("BrowserBox leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("BrowserBox tests", "browserbox")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ theme = new Theme;
+ Theme::selectSkin();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+
+ Widget::setGlobalFont(new Font("/usr/share/fonts/truetype/"
+ "ttf-dejavu/DejaVuSans-Oblique.ttf", 18));
+ BrowserBox *const box = new BrowserBox(nullptr,
+ Opaque_true,
+ "");
+ box->setWidth(100);
+ std::string row = "test";
+ box->addRow(row);
+ REQUIRE(box->hasRows() == true);
+ box->clearRows();
+ row = "@@";
+ box->addRow(row);
+ row = "@@|";
+ box->addRow(row);
+ row = "|@@";
+ box->addRow(row);
+ row = "@@|@@";
+ box->addRow(row);
+ row = "|@@@@";
+ box->addRow(row);
+ row = "@@11|22@@";
+ box->addRow(row);
+ row = "##@@11|22@@";
+ box->addRow(row);
+ row = "@@##|22@@";
+ box->addRow(row);
+ row = "@@11|##22@@";
+ box->addRow(row);
+ row = "@@11|22##@@";
+ box->addRow(row);
+ row = "@@11|22@@##";
+ box->addRow(row);
+ row = "<##@@11|22@@";
+ box->addRow(row);
+ row = "@@<##|22@@";
+ box->addRow(row);
+ row = "@@11|<##22@@";
+ box->addRow(row);
+ row = "@@11|22<##@@";
+ box->addRow(row);
+ row = "@@11|22@@<##";
+ box->addRow(row);
+ row = "<##11|22@@";
+ box->addRow(row);
+ row = "<##|22@@";
+ box->addRow(row);
+ row = "11|<##22@@";
+ box->addRow(row);
+ row = "11|22<##@@";
+ box->addRow(row);
+ row = "11|22@@<##";
+ box->addRow(row);
+ row = "##>@@11|22@@";
+ box->addRow(row);
+ row = "@@##>|22@@";
+ box->addRow(row);
+ row = "@@11|##>22@@";
+ box->addRow(row);
+ row = "@@11|22##>@@";
+ box->addRow(row);
+ row = "@@11|22@@##>";
+ box->addRow(row);
+ row = "<##11|22##>";
+ box->addRow(row);
+ row = "<##|22##>";
+ box->addRow(row);
+ row = "11|<##22##>";
+ box->addRow(row);
+ row = "11|22<####>";
+ box->addRow(row);
+ row = "11|22##><##";
+ box->addRow(row);
+ row = "%%@@11|22@@";
+ box->addRow(row);
+ row = "%%2@@11|22@@";
+ box->addRow(row);
+ row = "<%%11|22@@";
+ box->addRow(row);
+ row = "@@%%>|22@@";
+ box->addRow(row);
+ row = "<%%|22%%>";
+ box->addRow(row);
+ row = "11|22<%%%%>";
+ box->addRow(row);
+ row = "%%";
+ box->addRow(row);
+ row = "%%1";
+ box->addRow(row);
+ row = "%%##";
+ box->addRow(row);
+ row = "%%###";
+ box->addRow(row);
+ row = "##%%";
+ box->addRow(row);
+ row = "##1%%";
+ box->addRow(row);
+ row = "##%%2";
+ box->addRow(row);
+ row = "##1%%2";
+ box->addRow(row);
+
+ delete Widget::getGloablFont();
+ Widget::setGlobalFont(nullptr);
+ delete box;
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("BrowserBox leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/gui/windowmanager_unittest.cc b/src/unittests/gui/windowmanager_unittest.cc
new file mode 100644
index 000000000..75949fc44
--- /dev/null
+++ b/src/unittests/gui/windowmanager_unittest.cc
@@ -0,0 +1,984 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "configmanager.h"
+#include "configuration.h"
+#include "dirs.h"
+#include "graphicsmanager.h"
+#include "main.h"
+#include "settings.h"
+#include "textcommand.h"
+
+#include "being/localplayer.h"
+
+#include "const/resources/currency.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+#include "gui/mailmessage.h"
+#include "gui/userpalette.h"
+#include "gui/windowmanager.h"
+
+#include "gui/popups/beingpopup.h"
+#include "gui/popups/itempopup.h"
+#include "gui/popups/popupmenu.h"
+#include "gui/popups/skillpopup.h"
+#include "gui/popups/spellpopup.h"
+#include "gui/popups/speechbubble.h"
+#include "gui/popups/statuspopup.h"
+#include "gui/popups/textboxpopup.h"
+#include "gui/popups/textpopup.h"
+
+#include "gui/widgets/desktop.h"
+#include "gui/widgets/emoteshortcutcontainer.h"
+#include "gui/widgets/createwidget.h"
+
+#include "gui/windows/bankwindow.h"
+#include "gui/windows/buydialog.h"
+#include "gui/windows/buyingstoreselldialog.h"
+#include "gui/windows/buyselldialog.h"
+#include "gui/windows/charselectdialog.h"
+#include "gui/windows/changeemaildialog.h"
+#include "gui/windows/changepassworddialog.h"
+#include "gui/windows/chatwindow.h"
+#include "gui/windows/connectiondialog.h"
+#include "gui/windows/confirmdialog.h"
+#include "gui/windows/cutinwindow.h"
+#include "gui/windows/debugwindow.h"
+#include "gui/windows/didyouknowwindow.h"
+#include "gui/windows/editdialog.h"
+#include "gui/windows/editserverdialog.h"
+#include "gui/windows/eggselectiondialog.h"
+#include "gui/windows/emotewindow.h"
+#include "gui/windows/equipmentwindow.h"
+#include "gui/windows/helpwindow.h"
+#include "gui/windows/insertcarddialog.h"
+#include "gui/windows/inventorywindow.h"
+#include "gui/windows/itemamountwindow.h"
+#include "gui/windows/killstats.h"
+#include "gui/windows/logindialog.h"
+#include "gui/windows/maileditwindow.h"
+#include "gui/windows/mailviewwindow.h"
+#include "gui/windows/mailwindow.h"
+#include "gui/windows/minimap.h"
+#include "gui/windows/ministatuswindow.h"
+#include "gui/windows/npcdialog.h"
+#include "gui/windows/npcselldialog.h"
+#include "gui/windows/okdialog.h"
+#include "gui/windows/outfitwindow.h"
+#include "gui/windows/questswindow.h"
+#include "gui/windows/quitdialog.h"
+#include "gui/windows/registerdialog.h"
+#include "gui/windows/serverdialog.h"
+#include "gui/windows/serverinfowindow.h"
+#include "gui/windows/setupwindow.h"
+#include "gui/windows/shopwindow.h"
+#include "gui/windows/shortcutwindow.h"
+#include "gui/windows/skilldialog.h"
+#include "gui/windows/socialwindow.h"
+#include "gui/windows/statuswindow.h"
+#include "gui/windows/textcommandeditor.h"
+#include "gui/windows/textdialog.h"
+#include "gui/windows/textselectdialog.h"
+#include "gui/windows/tradewindow.h"
+#include "gui/windows/updaterwindow.h"
+#include "gui/windows/whoisonline.h"
+#include "gui/windows/worldselectdialog.h"
+
+#include "input/touch/touchmanager.h"
+
+#include "net/logindata.h"
+
+#include "net/eathena/charserverhandler.h"
+#include "net/eathena/inventoryhandler.h"
+#include "net/eathena/serverfeatures.h"
+#include "net/eathena/playerhandler.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/db/unitsdb.h"
+
+#include "resources/item/item.h"
+
+#include "resources/map/map.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+#include "utils/gettext.h"
+
+#include "utils/translation/translationmanager.h"
+
+#include "debug.h"
+
+extern QuitDialog *quitDialog;
+
+TEST_CASE("windows leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("Windows tests", "windowmanager")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ ResourceManager::deleteInstance();
+ ResourceManager::cleanOrphans(true);
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+ paths.setDefaultValues(getPathsDefaults());
+ branding.setValue("onlineServerFile", "test/serverlistplus.xml");
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ userPalette = new UserPalette;
+ config.setValue("fontSize", 16);
+ theme = new Theme;
+ Theme::selectSkin();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ const std::string cfgName = settings.configDir +
+ "/nonexistserver/config.xml";
+ ::remove(cfgName.c_str());
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+ ConfigManager::initServerConfig("nonexistserver");
+
+ localPlayer = new LocalPlayer(static_cast<BeingId>(1),
+ BeingTypeId_zero);
+
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+ touchManager.init();
+ UnitsDb::loadUnits();
+ charServerHandler = new EAthena::CharServerHandler;
+ serverFeatures = new EAthena::ServerFeatures;
+ inventoryHandler = new EAthena::InventoryHandler;
+ playerHandler = new EAthena::PlayerHandler;
+ paths.setValue("itemIcons", "");
+
+ TranslationManager::init();
+
+ mainGraphics->setVideoMode(640, 480, 1, 8, false, false, false, false);
+
+ SECTION("bankWindow")
+ {
+ CREATEWIDGETV0(bankWindow, BankWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(bankWindow);
+ }
+ SECTION("buyDialog1")
+ {
+ BuyDialog *dialog;
+ CREATEWIDGETV0(dialog, BuyDialog);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("buyDialog2")
+ {
+ BuyDialog *dialog;
+ CREATEWIDGETV(dialog, BuyDialog,
+ BeingId_zero,
+ DEFAULT_CURRENCY);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+#ifdef TMWA_SUPPORT
+ SECTION("buyDialog3")
+ {
+ BuyDialog *dialog;
+ CREATEWIDGETV(dialog, BuyDialog,
+ "user",
+ DEFAULT_CURRENCY);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+#endif // TMWA_SUPPORT
+ SECTION("buyDialog4")
+ {
+ BuyDialog *dialog;
+ BeingTypeId id = static_cast<BeingTypeId>(1);
+ Map *map = new Map("test map",
+ 10, 10,
+ 32, 32);
+ Being *being = Being::createBeing(BeingId_zero,
+ ActorType::Avatar,
+ id,
+ map);
+ CREATEWIDGETV(dialog, BuyDialog,
+ being,
+ DEFAULT_CURRENCY);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ delete2(being);
+ }
+ SECTION("BuyingStoreSellDialog")
+ {
+ BuyingStoreSellDialog *dialog;
+ CREATEWIDGETV(dialog, BuyingStoreSellDialog,
+ BeingId_zero, 0);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("BuySellDialog1")
+ {
+ BuySellDialog *dialog;
+ CREATEWIDGETV(dialog, BuySellDialog, BeingId_zero);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("BuySellDialog2")
+ {
+ BuySellDialog *dialog;
+ CREATEWIDGETV(dialog, BuySellDialog, "user");
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("ChangeEmailDialog")
+ {
+ LoginData data;
+ ChangeEmailDialog *dialog;
+ CREATEWIDGETV(dialog, ChangeEmailDialog, data);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("ChangePasswordDialog")
+ {
+ LoginData data;
+ ChangePasswordDialog *dialog;
+ CREATEWIDGETV(dialog, ChangePasswordDialog, data);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("CharSelectDialog")
+ {
+ LoginData data;
+ CharSelectDialog *dialog;
+ CREATEWIDGETV(dialog, CharSelectDialog, data);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("CharCreateDialog")
+ {
+// LoginData data;
+// CharSelectDialog *dialog2;
+// CREATEWIDGETV(dialog2, CharSelectDialog, data);
+// CharCreateDialog *dialog;
+// CREATEWIDGETV(dialog, CharCreateDialog, dialog2, 0);
+// gui->draw();
+// mainGraphics->updateScreen();
+// delete2(dialog);
+// delete2(dialog2);
+ }
+ SECTION("ChatWindow")
+ {
+ CREATEWIDGETV(chatWindow, ChatWindow,
+ "Chat");
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(chatWindow);
+ }
+ SECTION("ConfirmDialog")
+ {
+ ConfirmDialog *dialog;
+ CREATEWIDGETV(dialog, ConfirmDialog,
+ "", "", "", false, Modal_false, nullptr);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("CutinWindow")
+ {
+ CREATEWIDGETV0(cutInWindow, CutInWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(cutInWindow);
+ }
+ SECTION("DebugWindow")
+ {
+ CREATEWIDGETV0(debugWindow, DebugWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(debugWindow);
+ }
+ SECTION("didYouKnowWindow")
+ {
+ CREATEWIDGETV0(didYouKnowWindow, DidYouKnowWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(didYouKnowWindow);
+ }
+ SECTION("EditDialog")
+ {
+ EditDialog *dialog;
+ CREATEWIDGETV(dialog, EditDialog,
+ "", "", "", 100, nullptr, Modal_false);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("EditServerDialog")
+ {
+ ServerInfo mCurrentServer;
+ settings.configDir = VirtFs::getRealDir("test/serverlistplus.xml");
+ ServerDialog *serverDialog = CREATEWIDGETR(ServerDialog,
+ &mCurrentServer,
+ settings.configDir);
+ EditServerDialog *editServerDialog = CREATEWIDGETR(EditServerDialog,
+ serverDialog, mCurrentServer, 0);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(editServerDialog);
+ delete2(serverDialog);
+ }
+ SECTION("EggSelectionDialog")
+ {
+ EggSelectionDialog *dialog = CREATEWIDGETR0(EggSelectionDialog);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("EmoteWindow")
+ {
+ EmoteWindow *dialog = CREATEWIDGETR0(EmoteWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("EquipmentWindow")
+ {
+ Equipment *equipment = new Equipment;
+ Map *map = new Map("test", 100, 100, 32, 32);
+ Being *being = Being::createBeing(BeingId_zero,
+ ActorType::Player,
+ BeingTypeId_zero,
+ map);
+ EquipmentWindow *dialog = CREATEWIDGETR(EquipmentWindow,
+ equipment, being, false);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ delete2(being);
+ delete2(map);
+ delete2(equipment);
+ }
+ SECTION("helpWindow")
+ {
+ CREATEWIDGETV0(helpWindow, HelpWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(helpWindow);
+ }
+ SECTION("InsertCardDialog")
+ {
+ Item *item = new Item(5000,
+ ItemType::Card,
+ 1,
+ 0,
+ ItemColor_one,
+ Identified_true,
+ Damaged_false,
+ Favorite_false,
+ Equipm_true,
+ Equipped_false);
+ InsertCardDialog *dialog = CREATEWIDGETR(InsertCardDialog,
+ 0, item);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ delete2(item);
+ }
+ SECTION("InventoryWindow")
+ {
+ Inventory *inventory = new Inventory(InventoryType::Inventory);
+ InventoryWindow *dialog = CREATEWIDGETR(InventoryWindow,
+ inventory);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ delete2(inventory);
+ }
+ SECTION("ItemAmountWindow")
+ {
+ Item *item = new Item(5000,
+ ItemType::Card,
+ 1,
+ 0,
+ ItemColor_one,
+ Identified_true,
+ Damaged_false,
+ Favorite_false,
+ Equipm_true,
+ Equipped_false);
+ ItemAmountWindow *dialog = CREATEWIDGETR(ItemAmountWindow,
+ ItemAmountWindowUsage::ItemDrop, nullptr, item);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ delete2(item);
+ }
+ SECTION("KillStats")
+ {
+ CREATEWIDGETV0(killStats, KillStats);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(killStats);
+ }
+ SECTION("loginDialog")
+ {
+ ServerInfo mCurrentServer;
+ LoginDialog *loginDialog = CREATEWIDGETR(LoginDialog,
+ loginData,
+ &mCurrentServer,
+ &settings.options.updateHost);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(loginDialog);
+ }
+ SECTION("MailEditWindow")
+ {
+ CREATEWIDGETV0(mailEditWindow, MailEditWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(mailEditWindow);
+ }
+ SECTION("MailViewWindow")
+ {
+ MailMessage *message = new MailMessage;
+ CREATEWIDGETV(mailViewWindow, MailViewWindow,
+ message);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(mailViewWindow);
+ }
+ SECTION("MailWindow")
+ {
+ CREATEWIDGETV0(mailWindow, MailWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(mailWindow);
+ }
+ SECTION("Minimap")
+ {
+ CREATEWIDGETV0(minimap, Minimap);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(minimap);
+ }
+ SECTION("MiniStatusWindow")
+ {
+ CREATEWIDGETV0(miniStatusWindow, MiniStatusWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(miniStatusWindow);
+ }
+ SECTION("NpcDialog")
+ {
+ NpcDialog *dialog = CREATEWIDGETR(NpcDialog, BeingId_zero);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("NpcSellDialog")
+ {
+ NpcSellDialog *dialog = CREATEWIDGETR(NpcSellDialog, BeingId_zero);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("OkDialog")
+ {
+ OkDialog *dialog = CREATEWIDGETR(OkDialog,
+ "", "", "", DialogType::SILENCE, Modal_false,
+ ShowCenter_true, nullptr, 100);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("OutfitWindow")
+ {
+ CREATEWIDGETV0(outfitWindow, OutfitWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(outfitWindow);
+ }
+ SECTION("QuestsWindow")
+ {
+ CREATEWIDGETV0(questsWindow, QuestsWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(questsWindow);
+ }
+ SECTION("QuitDialog")
+ {
+ CREATEWIDGETV(quitDialog, QuitDialog,
+ &quitDialog);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(quitDialog);
+ }
+ SECTION("RegisterDialog")
+ {
+ RegisterDialog *dialog = CREATEWIDGETR(RegisterDialog,
+ loginData);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("serversDialog")
+ {
+ ServerInfo mCurrentServer;
+ settings.configDir = VirtFs::getRealDir("test/serverlistplus.xml");
+ ServerDialog *serverDialog = CREATEWIDGETR(ServerDialog,
+ &mCurrentServer,
+ settings.configDir);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(serverDialog);
+ }
+ SECTION("serversInfoWindow")
+ {
+ ServerInfo mCurrentServer;
+ CREATEWIDGETV(serverInfoWindow, ServerInfoWindow,
+ mCurrentServer);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(serverInfoWindow);
+ }
+ SECTION("setupWindow")
+ {
+ CREATEWIDGETV0(setupWindow, SetupWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(setupWindow);
+ }
+ SECTION("ShopSellDialog")
+ {
+ // only tmwa skipping
+ }
+ SECTION("ShopWindow")
+ {
+ CREATEWIDGETV0(shopWindow, ShopWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(shopWindow);
+ }
+ SECTION("ShortcutWindow1")
+ {
+ EmoteShortcutContainer *container =
+ new EmoteShortcutContainer(nullptr);
+ CREATEWIDGETV(itemShortcutWindow, ShortcutWindow,
+ "name",
+ container);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(itemShortcutWindow);
+ }
+ SECTION("ShortcutWindow2")
+ {
+ CREATEWIDGETV(itemShortcutWindow, ShortcutWindow, "");
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(itemShortcutWindow);
+ }
+ SECTION("SkillDialog")
+ {
+ CREATEWIDGETV0(skillDialog, SkillDialog);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(skillDialog);
+ }
+ SECTION("SocialWindow")
+ {
+ CREATEWIDGETV0(socialWindow, SocialWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(socialWindow);
+ }
+ SECTION("StatusWindow")
+ {
+ CREATEWIDGETV0(statusWindow, StatusWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(statusWindow);
+ }
+ SECTION("TextCommandEditor")
+ {
+ TextCommand *textCommand = new TextCommand(1, "", "", "",
+ CommandTarget::NoTarget, "");
+ TextCommandEditor *dialog = CREATEWIDGETR(TextCommandEditor,
+ textCommand);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ delete2(textCommand);
+ }
+
+ SECTION("TextDialog")
+ {
+ TextDialog *dialog = CREATEWIDGETR(TextDialog,
+ "", "", nullptr, false);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("TextSelectDialog")
+ {
+ TextSelectDialog *dialog = CREATEWIDGETR(TextSelectDialog,
+ "", "", AllowQuit_false);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("TradeWindow")
+ {
+ CREATEWIDGETV0(tradeWindow, TradeWindow);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(tradeWindow);
+ }
+ SECTION("UpdaterWindow")
+ {
+ CREATEWIDGETV(updaterWindow, UpdaterWindow,
+ "", "", false, UpdateType::Skip);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(updaterWindow);
+ }
+ SECTION("WhoIsOnline")
+ {
+ CREATEWIDGETV0(whoIsOnline, WhoIsOnline);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(whoIsOnline);
+ }
+ SECTION("WorldSelectDialog")
+ {
+ Worlds worlds;
+ WorldSelectDialog *dialog = CREATEWIDGETR(WorldSelectDialog,
+ worlds);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(dialog);
+ }
+ SECTION("popupMenu")
+ {
+ CREATEWIDGETV0(popupMenu, PopupMenu);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(popupMenu);
+ }
+ SECTION("skillPopup")
+ {
+ CREATEWIDGETV0(skillPopup, SkillPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(skillPopup);
+ }
+ SECTION("SpeechBubble")
+ {
+ SpeechBubble *bubble = CREATEWIDGETR0(SpeechBubble);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(bubble);
+ }
+ SECTION("beingPopup")
+ {
+ CREATEWIDGETV0(beingPopup, BeingPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(beingPopup);
+ }
+ SECTION("textPopup")
+ {
+ CREATEWIDGETV0(textPopup, TextPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(textPopup);
+ }
+ SECTION("textBoxPopup")
+ {
+ CREATEWIDGETV0(textBoxPopup, TextBoxPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(textBoxPopup);
+ }
+ SECTION("itemPopup")
+ {
+ CREATEWIDGETV0(itemPopup, ItemPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(itemPopup);
+ }
+ SECTION("spellPopup")
+ {
+ CREATEWIDGETV0(spellPopup, SpellPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(spellPopup);
+ }
+ SECTION("StatusPopup")
+ {
+ StatusPopup *status = CREATEWIDGETR0(StatusPopup);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(status);
+ }
+ SECTION("desktop")
+ {
+ CREATEWIDGETV(desktop, Desktop, nullptr);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(desktop);
+ }
+ SECTION("connectionDialog")
+ {
+ ConnectionDialog *connectionDialog = CREATEWIDGETR(ConnectionDialog,
+ // TRANSLATORS: connection dialog header
+ _("Logging in"),
+ State::SWITCH_SERVER);
+ gui->draw();
+ mainGraphics->updateScreen();
+ delete2(connectionDialog);
+ }
+
+ delete2(localPlayer);
+ delete2(userPalette);
+ delete2(client);
+ delete2(serverFeatures);
+ delete2(inventoryHandler);
+ delete2(charServerHandler);
+ delete2(playerHandler);
+ delete2(gui);
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ delete2(logger);
+
+// VirtFs::deinit();
+}
+
+TEST_CASE("WindowManager", "create windows")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ ResourceManager::deleteInstance();
+ ResourceManager::cleanOrphans(true);
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+ paths.setDefaultValues(getPathsDefaults());
+ branding.setValue("onlineServerFile", "test/serverlistplus.xml");
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ config.setValue("fontSize", 16);
+ theme = new Theme;
+ Theme::selectSkin();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ const std::string cfgName = settings.configDir +
+ "/nonexistserver/config.xml";
+ ::remove(cfgName.c_str());
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+ ConfigManager::initServerConfig("nonexistserver");
+
+ localPlayer = new LocalPlayer(static_cast<BeingId>(1),
+ BeingTypeId_zero);
+
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+ touchManager.init();
+ UnitsDb::loadUnits();
+ charServerHandler = new EAthena::CharServerHandler;
+ serverFeatures = new EAthena::ServerFeatures;
+ inventoryHandler = new EAthena::InventoryHandler;
+ playerHandler = new EAthena::PlayerHandler;
+ paths.setValue("itemIcons", "");
+
+ TranslationManager::init();
+
+ mainGraphics->setVideoMode(640, 480, 1, 8, false, false, false, false);
+
+ SECTION("create windows")
+ {
+ WindowManager::createWindows();
+ WindowManager::deleteWindows();
+ }
+
+ SECTION("init")
+ {
+ WindowManager::init();
+ }
+
+ SECTION("initTitle")
+ {
+ WindowManager::initTitle();
+ REQUIRE(settings.windowCaption == strprintf("%s %s",
+ branding.getStringValue("appName").c_str(),
+ SMALL_VERSION));
+ }
+
+ SECTION("updateTitle1")
+ {
+ settings.serverName = std::string();
+ settings.login = std::string();
+ WindowManager::updateTitle();
+ REQUIRE(settings.windowCaption == strprintf("%s %s",
+ branding.getStringValue("appName").c_str(),
+ SMALL_VERSION));
+ }
+
+ SECTION("updateTitle2")
+ {
+ settings.serverName = "server";
+ settings.login = std::string();
+ WindowManager::updateTitle();
+ REQUIRE(settings.windowCaption == strprintf("%s %s - %s",
+ branding.getStringValue("appName").c_str(),
+ SMALL_VERSION,
+ settings.serverName.c_str()));
+ }
+
+ SECTION("updateTitle3")
+ {
+ settings.serverName = "server";
+ settings.login = "login";
+ WindowManager::updateTitle();
+ REQUIRE(settings.windowCaption == strprintf("%s %s - %s %s",
+ branding.getStringValue("appName").c_str(),
+ SMALL_VERSION,
+ settings.login.c_str(),
+ settings.serverName.c_str()));
+ }
+
+ SECTION("setFramerate1")
+ {
+ settings.limitFps = true;
+ WindowManager::setFramerate(60);
+ REQUIRE(WindowManager::getFramerate() == 60);
+ WindowManager::setFramerate(10);
+ REQUIRE(WindowManager::getFramerate() == 10);
+ WindowManager::setFramerate(0);
+ REQUIRE(WindowManager::getFramerate() == 10);
+ }
+
+ SECTION("setFramerate2")
+ {
+ settings.limitFps = false;
+ WindowManager::setFramerate(60);
+ REQUIRE(WindowManager::getFramerate() == 0);
+ WindowManager::setFramerate(10);
+ REQUIRE(WindowManager::getFramerate() == 0);
+ WindowManager::setFramerate(0);
+ REQUIRE(WindowManager::getFramerate() == 0);
+ }
+
+ settings.serverName = std::string();
+ settings.login = std::string();
+ settings.limitFps = true;
+
+ delete2(localPlayer);
+ delete2(client);
+ delete2(serverFeatures);
+ delete2(inventoryHandler);
+ delete2(charServerHandler);
+ delete2(playerHandler);
+ delete2(gui);
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ delete2(logger);
+
+// VirtFs::deinit();
+}
+
+TEST_CASE("windows leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/integrity_unittest.cc b/src/unittests/integrity_unittest.cc
new file mode 100644
index 000000000..b2c234109
--- /dev/null
+++ b/src/unittests/integrity_unittest.cc
@@ -0,0 +1,366 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "logger.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/files.h"
+
+#include "fs/virtfs/fs.h"
+#include "fs/virtfs/rwops.h"
+
+#include "gui/gui.h"
+
+#include "input/inputactionmap.h"
+
+#include "resources/image/image.h"
+
+#include "resources/loaders/imageloader.h"
+
+#include "resources/sdlimagehelper.h"
+#ifdef USE_SDL2
+#include "resources/surfaceimagehelper.h"
+#endif // USE_SDL2
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "utils/env.h"
+#include "utils/delete2.h"
+#include "utils/foreach.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#include <SDL_image.h>
+PRAGMA48(GCC diagnostic pop)
+
+#ifndef UNITTESTS_CATCH
+#include <algorithm>
+#endif // UNITTESTS_CATCH
+
+#include "debug.h"
+
+namespace
+{
+ class InputActionSortFunctorTest final
+ {
+ public:
+ bool operator() (const InputActionT key1,
+ const InputActionT key2) const
+ {
+ REQUIRE(CAST_SIZE(key1) < CAST_SIZE(InputAction::TOTAL));
+ REQUIRE(CAST_SIZE(key2) < CAST_SIZE(InputAction::TOTAL));
+ REQUIRE(key1 < InputAction::TOTAL);
+ REQUIRE(key2 < InputAction::TOTAL);
+ return keys[CAST_SIZE(key1)].priority
+ >= keys[CAST_SIZE(key2)].priority;
+ }
+
+ const InputActionData *keys A_NONNULLPOINTER;
+ };
+ InputActionSortFunctorTest inputActionDataSorterTest;
+} // namespace
+
+static bool compareBuffers(const unsigned char *const buf2)
+{
+ bool isCorrect(true);
+ int sz = 0;
+ const unsigned char *buf1 = reinterpret_cast<const unsigned char*>(
+ VirtFs::loadFile("hide.png", sz));
+ REQUIRE(buf1 != nullptr);
+ REQUIRE(sz == 368);
+ for (int f = 0; f < sz; f ++)
+ {
+ if (buf1[f] != buf2[f])
+ {
+ isCorrect = false;
+ logger->log("Wrong buffer chars: 0x%x vs 0x%x",
+ buf1[f],
+ buf2[f]);
+ }
+ }
+ delete [] buf1;
+ return isCorrect;
+}
+
+TEST_CASE("integrity leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("integrity tests", "integrity")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ std::string name("data/test/test.zip");
+ std::string prefix;
+ if (Files::existsLocal(name) == false)
+ prefix = "../" + prefix;
+
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+#ifdef USE_SDL2
+ imageHelper = new SurfaceImageHelper;
+
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ imageHelper = new SDLImageHelper();
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+ const char *const name1 = "dir/hide.png";
+ const int size1 = 368;
+
+ SECTION("integrity test 1")
+ {
+ REQUIRE(sizeof(inputActionData) / sizeof(InputActionData) ==
+ CAST_SIZE(InputAction::TOTAL));
+ }
+
+ SECTION("integrity test 2")
+ {
+ KeyToActionMap actionMap;
+ const size_t sz = CAST_SIZE(InputAction::TOTAL);
+ for (size_t i = 0; i < sz; i ++)
+ {
+ InputActionT val = static_cast<InputActionT>(i);
+ REQUIRE(val < InputAction::TOTAL);
+ REQUIRE(val > InputAction::NO_VALUE);
+ REQUIRE(val > InputAction::UNDEFINED_VALUE);
+ REQUIRE(CAST_SIZE(val) < CAST_SIZE(InputAction::TOTAL));
+ REQUIRE(CAST_SIZE(val) < CAST_SIZE(InputAction::NO_VALUE));
+ REQUIRE(CAST_SIZE(val) < CAST_SIZE(InputAction::UNDEFINED_VALUE));
+ REQUIRE(CAST_S32(val) < CAST_S32(InputAction::TOTAL));
+ REQUIRE(CAST_S32(val) > CAST_S32(InputAction::NO_VALUE));
+ REQUIRE(CAST_S32(val) > CAST_S32(InputAction::UNDEFINED_VALUE));
+ }
+ }
+
+ SECTION("integrity test 3")
+ {
+ KeyToActionMap actionMap;
+ int cnt = 0;
+ const size_t sz = CAST_SIZE(InputAction::TOTAL);
+ for (size_t i = 0; i < sz; i ++)
+ {
+ actionMap[cnt++].push_back(static_cast<InputActionT>(i));
+ if (cnt > 3)
+ cnt = 0;
+ }
+ FOR_EACH (KeyToActionMapIter, it, actionMap)
+ {
+ KeysVector *const keys = &it->second;
+ FOR_EACHP (KeysVectorIter, itk, keys)
+ {
+ const size_t val = CAST_SIZE(*itk);
+ REQUIRE(val < sz);
+ }
+ }
+ }
+
+ SECTION("integrity test 4")
+ {
+ KeyToActionMap actionMap;
+ KeyTimeMap keyTimeMap;
+ actionMap.clear();
+ keyTimeMap.clear();
+
+ for (size_t i = 0; i < CAST_SIZE(InputAction::TOTAL); i ++)
+ {
+ actionMap[10].push_back(
+ static_cast<InputActionT>(i));
+ }
+
+ KeysVector *const keys = &actionMap[0];
+ inputActionDataSorterTest.keys = &inputActionData[0];
+ std::sort(keys->begin(), keys->end(), inputActionDataSorterTest);
+ }
+
+ SECTION("integrity test 5")
+ {
+ KeyToActionMap mKeyToAction;
+ KeyToIdMap mKeyToId;
+ KeyTimeMap mKeyTimeMap;
+ inputManager.updateKeyActionMap(mKeyToAction, mKeyToId,
+ mKeyTimeMap, InputType::KEYBOARD);
+ }
+
+ SECTION("integrity Loader::getImage test 1")
+ {
+ Image *const image = Loader::getImage(
+ "graphics/images/login_wallpaper.png");
+ REQUIRE(image != nullptr);
+ REQUIRE(image->getSDLSurface() != nullptr);
+ image->decRef();
+ }
+
+ SECTION("integrity Loader::getImage test 2")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+ Image *const image = Loader::getImage(
+ "dir/hide.png");
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(image != nullptr);
+ REQUIRE(image->getSDLSurface() != nullptr);
+ image->decRef();
+ }
+
+ SECTION("integrity Loader::getImage test 3")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+ Image *const image = Loader::getImage(
+ "dir/brimmedhat.png");
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(image != nullptr);
+ REQUIRE(image->getSDLSurface() != nullptr);
+ image->decRef();
+ }
+
+ SECTION("integrity Loader::getImage test 4")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+
+ SDL_RWops *const rw = VirtFs::rwopsOpenRead(name1);
+ REQUIRE(rw != nullptr);
+ unsigned char buf[size1];
+ const size_t sz = SDL_RWread(rw, buf, 1, size1);
+ if (sz != size1)
+ SDL_RWclose(rw);
+ REQUIRE(sz == size1);
+ SDL_RWclose(rw);
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ VirtFs::mountDirSilent(prefix + "data/test", Append_true);
+ REQUIRE(compareBuffers(buf));
+ VirtFs::unmountDirSilent(prefix + "data/test");
+ }
+
+ SECTION("integrity Loader::getImage test 7")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+
+ SDL_RWops *const rw = VirtFs::rwopsOpenRead(name1);
+ REQUIRE(rw != nullptr);
+ int64_t seek = SDL_RWseek(rw, 0, RW_SEEK_END);
+ if (seek == -1)
+ SDL_RWclose(rw);
+ REQUIRE(seek != -1);
+ const int64_t pos = SDL_RWtell(rw);
+ if (pos != size1)
+ SDL_RWclose(rw);
+ REQUIRE(pos == size1);
+
+ seek = SDL_RWseek(rw, 0, RW_SEEK_SET);
+ if (seek == -1)
+ SDL_RWclose(rw);
+ REQUIRE(seek != -1);
+
+ unsigned char buf[size1];
+ const size_t sz = SDL_RWread(rw, buf, 1, pos);
+ if (sz != size1)
+ SDL_RWclose(rw);
+ REQUIRE(sz == size1);
+
+ SDL_RWclose(rw);
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ VirtFs::mountDirSilent("data/test", Append_true);
+ VirtFs::mountDirSilent("../data/test", Append_true);
+ REQUIRE(compareBuffers(buf));
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ }
+
+ SECTION("integrity Loader::getImage test 8")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+
+ SDL_RWops *const rw = VirtFs::rwopsOpenRead(name1);
+ REQUIRE(rw != nullptr);
+ if (IMG_isPNG(rw) == 0)
+ {
+ SDL_RWclose(rw);
+ REQUIRE(false);
+ }
+ SDL_Surface *const tmpImage = IMG_LoadPNG_RW(rw);
+ SDL_RWclose(rw);
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(tmpImage != nullptr);
+ SDL_FreeSurface(tmpImage);
+ }
+
+ SECTION("integrity Loader::getImage test 9")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+
+ SDL_RWops *const rw = VirtFs::rwopsOpenRead(name1);
+ REQUIRE(rw != nullptr);
+ Resource *const res = imageHelper->load(rw);
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(res != nullptr);
+ delete res;
+ }
+
+ SECTION("integrity Loader::getImage test 10")
+ {
+ VirtFs::mountZip(prefix + "data/test/test.zip", Append_false);
+ Image *const image = Loader::getImage(
+ name1);
+ VirtFs::unmountZip(prefix + "data/test/test.zip");
+ REQUIRE(image != nullptr);
+ REQUIRE(image->getSDLSurface() != nullptr);
+ image->decRef();
+ }
+
+ ResourceManager::cleanOrphans(true);
+
+ delete client;
+ client = nullptr;
+
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("integrity leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/render/mockdrawitem.h b/src/unittests/render/mockdrawitem.h
new file mode 100644
index 000000000..75951123e
--- /dev/null
+++ b/src/unittests/render/mockdrawitem.h
@@ -0,0 +1,60 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RENDER_MOCKDRAWITEM_H
+#define RENDER_MOCKDRAWITEM_H
+
+#ifdef UNITTESTS
+
+#include "unittests/enums/render/mockdrawtype.h"
+
+#include "localconsts.h"
+
+class Image;
+
+struct MockDrawItem final
+{
+ MockDrawItem(const MockDrawTypeT type,
+ const Image *const image0,
+ const int x0,
+ const int y0,
+ const int width0,
+ const int height0) :
+ image(image0),
+ drawType(type),
+ x(x0),
+ y(y0),
+ width(width0),
+ height(height0)
+ {
+ }
+
+ A_DEFAULT_COPY(MockDrawItem)
+
+ const Image *image;
+ MockDrawTypeT drawType;
+ int x;
+ int y;
+ int width;
+ int height;
+};
+
+#endif // UNITTESTS
+#endif // RENDER_MOCKDRAWITEM_H
diff --git a/src/unittests/render/mockgraphics.cc b/src/unittests/render/mockgraphics.cc
new file mode 100644
index 000000000..b484ad4d1
--- /dev/null
+++ b/src/unittests/render/mockgraphics.cc
@@ -0,0 +1,301 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/render/mockgraphics.h"
+
+#include "graphicsmanager.h"
+
+#include "utils/sdlcheckutils.h"
+
+#include "render/vertexes/imagecollection.h"
+
+#include "debug.h"
+
+MockGraphics::MockGraphics() :
+ Graphics()
+{
+ mOpenGL = RENDER_SOFTWARE;
+ mName = "Software";
+}
+
+MockGraphics::~MockGraphics()
+{
+}
+
+void MockGraphics::drawRescaledImage(const Image *restrict const image
+ A_UNUSED,
+ int dstX A_UNUSED,
+ int dstY A_UNUSED,
+ const int desiredWidth A_UNUSED,
+ const int desiredHeight A_UNUSED)
+ restrict2
+{
+}
+
+void MockGraphics::drawImage(const Image *restrict const image,
+ int dstX,
+ int dstY) restrict2
+{
+ mDraws.push_back(MockDrawItem(MockDrawType::DrawImage,
+ image,
+ dstX,
+ dstY,
+ 0,
+ 0));
+}
+
+void MockGraphics::drawImageInline(const Image *restrict const image A_UNUSED,
+ int dstX A_UNUSED,
+ int dstY A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::copyImage(const Image *restrict const image A_UNUSED,
+ int dstX A_UNUSED,
+ int dstY A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::drawImageCached(const Image *restrict const image A_UNUSED,
+ int x A_UNUSED,
+ int y A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::drawPatternCached(const Image *restrict const image
+ A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::completeCache() restrict2
+{
+}
+
+void MockGraphics::drawPattern(const Image *restrict const image,
+ const int x,
+ const int y,
+ const int w,
+ const int h) restrict2
+{
+ mDraws.push_back(MockDrawItem(MockDrawType::DrawPattern,
+ image,
+ x,
+ y,
+ w,
+ h));
+}
+
+void MockGraphics::drawPatternInline(const Image *restrict const image
+ A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::drawRescaledPattern(const Image *restrict const image
+ A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED,
+ const int scaledWidth A_UNUSED,
+ const int scaledHeight A_UNUSED)
+ restrict2
+{
+}
+
+void MockGraphics::calcPattern(ImageVertexes *restrict const vert A_UNUSED,
+ const Image *restrict const image A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED) const restrict2
+{
+}
+
+void MockGraphics::calcPatternInline(ImageVertexes *restrict const vert
+ A_UNUSED,
+ const Image *restrict const image
+ A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED) const restrict2
+{
+}
+
+void MockGraphics::calcPattern(ImageCollection *restrict const vertCol
+ A_UNUSED,
+ const Image *restrict const image A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED) const restrict2
+{
+}
+
+void MockGraphics::calcTileVertexes(ImageVertexes *restrict const vert,
+ const Image *restrict const image,
+ int x, int y) const restrict2
+{
+ vert->image = image;
+ calcTileSDL(vert, x, y);
+}
+
+void MockGraphics::calcTileVertexesInline(ImageVertexes *restrict const vert
+ A_UNUSED,
+ const Image *restrict const image
+ A_UNUSED,
+ int x A_UNUSED,
+ int y A_UNUSED) const restrict2
+{
+}
+
+void MockGraphics::calcTileSDL(ImageVertexes *restrict const vert A_UNUSED,
+ int x A_UNUSED,
+ int y A_UNUSED) const restrict2
+{
+}
+
+void MockGraphics::calcTileCollection(ImageCollection *restrict const vertCol
+ A_UNUSED,
+ const Image *restrict const image
+ A_UNUSED,
+ int x A_UNUSED,
+ int y A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::drawTileCollection(const ImageCollection *restrict const
+ vertCol A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::drawTileVertexes(const ImageVertexes *restrict const
+ vert A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::updateScreen() restrict2
+{
+}
+
+void MockGraphics::calcWindow(ImageCollection *restrict const vertCol A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED,
+ const ImageRect &restrict imgRect A_UNUSED)
+ restrict2
+{
+}
+
+void MockGraphics::fillRectangle(const Rect &restrict rectangle A_UNUSED)
+ restrict2
+{
+}
+
+void MockGraphics::beginDraw() restrict2
+{
+ pushClipArea(Rect(0, 0, mRect.w, mRect.h));
+}
+
+void MockGraphics::endDraw() restrict2
+{
+ popClipArea();
+}
+
+void MockGraphics::pushClipArea(const Rect &restrict area) restrict2
+{
+ Graphics::pushClipArea(area);
+}
+
+void MockGraphics::popClipArea() restrict2
+{
+ Graphics::popClipArea();
+}
+
+void MockGraphics::drawPoint(int x A_UNUSED,
+ int y A_UNUSED) restrict2
+{
+}
+
+void MockGraphics::drawRectangle(const Rect &restrict rectangle A_UNUSED)
+ restrict2
+{
+}
+
+void MockGraphics::drawLine(int x1 A_UNUSED,
+ int y1 A_UNUSED,
+ int x2 A_UNUSED,
+ int y2 A_UNUSED) restrict2
+{
+}
+
+bool MockGraphics::setVideoMode(const int w, const int h,
+ const int scale,
+ const int bpp,
+ const bool fs,
+ const bool hwaccel,
+ const bool resize,
+ const bool noFrame) restrict2
+{
+ setMainFlags(w, h, scale, bpp, fs, hwaccel, resize, noFrame);
+
+ if ((mWindow = graphicsManager.createWindow(w, h, bpp,
+ getSoftwareFlags())) == nullptr)
+ {
+ mRect.w = 0;
+ mRect.h = 0;
+ return false;
+ }
+
+ mRect.w = CAST_U16(mRect.w);
+ mRect.h = CAST_U16(mRect.h);
+
+ return videoInfo();
+}
+
+void MockGraphics::drawImageRect(const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED,
+ const ImageRect &restrict imgRect A_UNUSED)
+ restrict2
+{
+}
+
+void MockGraphics::calcImageRect(ImageVertexes *restrict const vert A_UNUSED,
+ const int x A_UNUSED,
+ const int y A_UNUSED,
+ const int w A_UNUSED,
+ const int h A_UNUSED,
+ const ImageRect &restrict imgRect A_UNUSED)
+ restrict2
+{
+}
diff --git a/src/unittests/render/mockgraphics.h b/src/unittests/render/mockgraphics.h
new file mode 100644
index 000000000..ccc6d75e6
--- /dev/null
+++ b/src/unittests/render/mockgraphics.h
@@ -0,0 +1,55 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RENDER_MOCKGRAPHICS_H
+#define RENDER_MOCKGRAPHICS_H
+
+#ifdef UNITTESTS
+
+#include "render/graphics.h"
+
+#include "unittests/render/mockdrawitem.h"
+
+#include "localconsts.h"
+
+#include <vector>
+
+class MockGraphics final : public Graphics
+{
+ public:
+ MockGraphics();
+
+ A_DELETE_COPY(MockGraphics)
+
+ ~MockGraphics();
+
+ #include "render/graphicsdef.hpp"
+ RENDER_GRAPHICSDEF_HPP
+
+ #include "render/softwaregraphicsdef.hpp"
+ RENDER_SOFTWAREGRAPHICSDEF_HPP
+
+ std::vector<MockDrawItem> mDraws;
+};
+
+#endif // UNITTESTS
+#endif // RENDER_MOCKGRAPHICS_H
diff --git a/src/unittests/resources/dye/dye_unittest.cc b/src/unittests/resources/dye/dye_unittest.cc
new file mode 100644
index 000000000..fcdeb7b17
--- /dev/null
+++ b/src/unittests/resources/dye/dye_unittest.cc
@@ -0,0 +1,2020 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "graphicsmanager.h"
+#include "logger.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+
+#include "resources/sdlimagehelper.h"
+#ifdef USE_SDL2
+#include "resources/surfaceimagehelper.h"
+#endif // USE_SDL2
+
+#include "resources/dye/dye.h"
+#include "resources/dye/dyepalette.h"
+
+#include "resources/image/image.h"
+
+#include "resources/loaders/imageloader.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#ifndef USE_SDL2
+#include <SDL.h>
+#endif // USE_SDL2
+PRAGMA48(GCC diagnostic pop)
+
+#include "debug.h"
+
+#ifdef USE_OPENGL
+
+TEST_CASE("Dye leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("Dye replaceSOGLColor 1 1", "")
+{
+ DyePalette palette("#00ff00,000011", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x01, 0x02, 0x03, 0x10);
+ DYEPALETTE(palette, SOGLColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x01, 0x02, 0x03, 0x10));
+}
+
+TEST_CASE("Dye replaceSOGLColor 1 2", "")
+{
+ DyePalette palette("#01ff02,030411", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ DYEPALETTE(palette, SOGLColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+}
+
+TEST_CASE("Dye replaceSOGLColor 1 3", "")
+{
+ DyePalette palette("#404040,200000,0100ee,102030", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, SOGLColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x40, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceSOGLColor 2 1", "")
+{
+ DyePalette palette("#01ff02,030411", 6);
+ uint32_t data[2];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ DYEPALETTE(palette, SOGLColor)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+}
+
+TEST_CASE("Dye replaceSOGLColor 4 1", "")
+{
+ DyePalette palette("#01ff02,030411", 6);
+ uint32_t data[4];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[2] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[3] = buildHex(0x50, 0x02, 0xff, 0x02);
+ DYEPALETTE(palette, SOGLColor)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[2] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[3] == buildHex(0x50, 0x02, 0xff, 0x02));
+}
+
+TEST_CASE("Dye replaceSOGLColor 8 1", "")
+{
+ DyePalette palette("#01ff02,030411,01ee02,010203", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[2] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[3] = buildHex(0x50, 0x02, 0xff, 0x02);
+ data[4] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[5] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[6] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[7] = buildHex(0x60, 0x02, 0xff, 0x02);
+ DYEPALETTE(palette, SOGLColor)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[2] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[3] == buildHex(0x50, 0x02, 0xff, 0x02));
+ REQUIRE(data[4] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[5] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[6] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[7] == buildHex(0x60, 0x02, 0xff, 0x02));
+}
+
+TEST_CASE("Dye replaceSOGLColor 1 1 default", "")
+{
+ DyePalette palette("#00ff00,000011", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x01, 0x02, 0x03, 0x10);
+ palette.replaceSOGLColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x01, 0x02, 0x03, 0x10));
+}
+
+TEST_CASE("Dye replaceSOGLColor 1 2 default", "")
+{
+ DyePalette palette("#01ff02,030411", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ palette.replaceSOGLColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+}
+
+TEST_CASE("Dye replaceSOGLColor 1 3 default", "")
+{
+ DyePalette palette("#404040,200000,0100ee,102030", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ palette.replaceSOGLColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x40, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceSOGLColor 2 1 default", "")
+{
+ DyePalette palette("#01ff02,030411", 6);
+ uint32_t data[2];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ palette.replaceSOGLColorDefault(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+}
+
+TEST_CASE("Dye replaceSOGLColor 4 1 default", "")
+{
+ DyePalette palette("#01ff02,030411", 6);
+ uint32_t data[4];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[2] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[3] = buildHex(0x50, 0x02, 0xff, 0x02);
+ palette.replaceSOGLColorDefault(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[2] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[3] == buildHex(0x50, 0x02, 0xff, 0x02));
+}
+
+TEST_CASE("Dye replaceSOGLColor 8 1 default", "")
+{
+ DyePalette palette("#01ff02,030411,01ee02,010203", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[2] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[3] = buildHex(0x50, 0x02, 0xff, 0x02);
+ data[4] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[5] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[6] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[7] = buildHex(0x60, 0x02, 0xff, 0x02);
+ palette.replaceSOGLColorDefault(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[2] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[3] == buildHex(0x50, 0x02, 0xff, 0x02));
+ REQUIRE(data[4] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[5] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[6] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[7] == buildHex(0x60, 0x02, 0xff, 0x02));
+}
+
+TEST_CASE("Dye replaceSOGLColor 8 1 sse2", "")
+{
+ DyePalette palette("#01ff02,030411,01ee02,010203", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[2] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[3] = buildHex(0x50, 0x02, 0xff, 0x02);
+ data[4] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[5] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[6] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[7] = buildHex(0x60, 0x02, 0xff, 0x02);
+ DYEPALETTE(palette, SOGLColorSse2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[2] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[3] == buildHex(0x50, 0x02, 0xff, 0x02));
+ REQUIRE(data[4] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[5] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[6] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[7] == buildHex(0x60, 0x02, 0xff, 0x02));
+}
+
+TEST_CASE("Dye replaceSOGLColor 8 1 avx2", "")
+{
+ DyePalette palette("#01ff02,030411,01ee02,010203", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[1] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[2] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[3] = buildHex(0x50, 0x02, 0xff, 0x02);
+ data[4] = buildHex(0x20, 0x02, 0xff, 0x01);
+ data[5] = buildHex(0x30, 0x02, 0xff, 0x01);
+ data[6] = buildHex(0x40, 0x02, 0xff, 0x01);
+ data[7] = buildHex(0x60, 0x02, 0xff, 0x02);
+ DYEPALETTE(palette, SOGLColorAvx2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[1] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[2] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[3] == buildHex(0x50, 0x02, 0xff, 0x02));
+ REQUIRE(data[4] == buildHex(0x20, 0x11, 0x04, 0x03));
+ REQUIRE(data[5] == buildHex(0x30, 0x11, 0x04, 0x03));
+ REQUIRE(data[6] == buildHex(0x40, 0x11, 0x04, 0x03));
+ REQUIRE(data[7] == buildHex(0x60, 0x02, 0xff, 0x02));
+}
+
+
+TEST_CASE("Dye replaceAOGLColor 1 1", "")
+{
+ DyePalette palette("#00ff0010,00001120", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, AOGLColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceAOGLColor 1 2", "")
+{
+ DyePalette palette("#00ff0120,020311ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x20, 0x01, 0xff, 0x00);
+ DYEPALETTE(palette, AOGLColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0xff, 0x11, 0x03, 0x02));
+}
+
+TEST_CASE("Dye replaceAOGLColor 1 3", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, AOGLColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 2 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[2];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, AOGLColor)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 4 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[4];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[2] = buildHex(0x41, 0xee, 0x00, 0x01);
+ data[3] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, AOGLColor)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[2] == buildHex(0x41, 0xee, 0x00, 0x01));
+ REQUIRE(data[3] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 8 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[2] = buildHex(0x41, 0xee, 0x00, 0x01);
+ data[3] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[4] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[5] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[6] = buildHex(0x41, 0xe0, 0x00, 0x01);
+ data[7] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, AOGLColor)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[2] == buildHex(0x41, 0xee, 0x00, 0x01));
+ REQUIRE(data[3] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[4] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[5] == buildHex(0x00, 0x00, 0x00, 0x20));
+ REQUIRE(data[6] == buildHex(0x41, 0xe0, 0x00, 0x01));
+ REQUIRE(data[7] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 1 1 default", "")
+{
+ DyePalette palette("#00ff0010,00001120", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ palette.replaceAOGLColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceAOGLColor 1 2 default", "")
+{
+ DyePalette palette("#00ff0120,020311ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x20, 0x01, 0xff, 0x00);
+ palette.replaceAOGLColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0xff, 0x11, 0x03, 0x02));
+}
+
+TEST_CASE("Dye replaceAOGLColor 1 3 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ palette.replaceAOGLColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 2 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[2];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ palette.replaceAOGLColorDefault(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 4 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[4];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[2] = buildHex(0x41, 0xee, 0x00, 0x01);
+ data[3] = buildHex(0x40, 0xee, 0x00, 0x01);
+ palette.replaceAOGLColorDefault(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[2] == buildHex(0x41, 0xee, 0x00, 0x01));
+ REQUIRE(data[3] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 8 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[2] = buildHex(0x41, 0xee, 0x00, 0x01);
+ data[3] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[4] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[5] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[6] = buildHex(0x41, 0xe0, 0x00, 0x01);
+ data[7] = buildHex(0x40, 0xee, 0x00, 0x01);
+ palette.replaceAOGLColorDefault(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[2] == buildHex(0x41, 0xee, 0x00, 0x01));
+ REQUIRE(data[3] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[4] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[5] == buildHex(0x00, 0x00, 0x00, 0x20));
+ REQUIRE(data[6] == buildHex(0x41, 0xe0, 0x00, 0x01));
+ REQUIRE(data[7] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 8 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[2] = buildHex(0x41, 0xee, 0x00, 0x01);
+ data[3] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[4] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[5] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[6] = buildHex(0x41, 0xe0, 0x00, 0x01);
+ data[7] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, AOGLColorSse2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[2] == buildHex(0x41, 0xee, 0x00, 0x01));
+ REQUIRE(data[3] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[4] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[5] == buildHex(0x00, 0x00, 0x00, 0x20));
+ REQUIRE(data[6] == buildHex(0x41, 0xe0, 0x00, 0x01));
+ REQUIRE(data[7] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+
+TEST_CASE("Dye replaceAOGLColor 8 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[1] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[2] = buildHex(0x41, 0xee, 0x00, 0x01);
+ data[3] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[4] = buildHex(0x40, 0xee, 0x00, 0x01);
+ data[5] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[6] = buildHex(0x41, 0xe0, 0x00, 0x01);
+ data[7] = buildHex(0x40, 0xee, 0x00, 0x01);
+ DYEPALETTE(palette, AOGLColorAvx2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[1] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[2] == buildHex(0x41, 0xee, 0x00, 0x01));
+ REQUIRE(data[3] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[4] == buildHex(0xff, 0x30, 0x20, 0x10));
+ REQUIRE(data[5] == buildHex(0x00, 0x00, 0x00, 0x20));
+ REQUIRE(data[6] == buildHex(0x41, 0xe0, 0x00, 0x01));
+ REQUIRE(data[7] == buildHex(0xff, 0x30, 0x20, 0x10));
+}
+#endif // USE_OPENGL
+
+
+TEST_CASE("Dye replaceSColor 1 1", "")
+{
+ DyePalette palette("#00ff00,000011", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, SColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceSColor 1 2", "")
+{
+ DyePalette palette("#403020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0x30, 0x20, 0x10);
+ DYEPALETTE(palette, SColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 1 3", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ DYEPALETTE(palette, SColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 2 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[2];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColor)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 3 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[3];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x30, 0x20, 0x30);
+ DYEPALETTE(palette, SColor)(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30));
+}
+
+TEST_CASE("Dye replaceSColor 4 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[4];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColor)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 5 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[5];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x30);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColor)(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x30));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 7 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[7];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ DYEPALETTE(palette, SColor)(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+}
+
+TEST_CASE("Dye replaceSColor 8 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ DYEPALETTE(palette, SColor)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+}
+
+TEST_CASE("Dye replaceSColor 9 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[9];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0xff, 0x30, 0x20, 0x70);
+ DYEPALETTE(palette, SColor)(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x70, 0x60, 0x50, 0x70));
+}
+
+TEST_CASE("Dye replaceSColor 10 1", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[10];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0x12, 0x34, 0x56, 0x70);
+ data[9] = buildHex(0xff, 0x30, 0x20, 0x80);
+ DYEPALETTE(palette, SColor)(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x00, 0x00, 0x00, 0x70));
+ REQUIRE(data[9] == buildHex(0x70, 0x60, 0x50, 0x80));
+}
+
+TEST_CASE("Dye replaceSColor 1 1 default", "")
+{
+ DyePalette palette("#00ff00,000011", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ palette.replaceSColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceSColor 1 2 default", "")
+{
+ DyePalette palette("#403020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0x30, 0x20, 0x10);
+ palette.replaceSColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 1 3 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ palette.replaceSColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 2 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[2];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ palette.replaceSColorDefault(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 3 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[3];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x30, 0x20, 0x30);
+ palette.replaceSColorDefault(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30));
+}
+
+TEST_CASE("Dye replaceSColor 4 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[4];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ palette.replaceSColorDefault(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 5 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[5];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x30);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x20);
+ palette.replaceSColorDefault(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x30));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 7 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[7];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ palette.replaceSColorDefault(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+}
+
+TEST_CASE("Dye replaceSColor 8 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ palette.replaceSColorDefault(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+}
+
+TEST_CASE("Dye replaceSColor 9 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[9];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0xff, 0x30, 0x20, 0x70);
+ palette.replaceSColorDefault(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x70, 0x60, 0x50, 0x70));
+}
+
+TEST_CASE("Dye replaceSColor 10 1 default", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[10];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0x12, 0x34, 0x56, 0x70);
+ data[9] = buildHex(0xff, 0x30, 0x20, 0x80);
+ palette.replaceSColorDefault(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x00, 0x00, 0x00, 0x70));
+ REQUIRE(data[9] == buildHex(0x70, 0x60, 0x50, 0x80));
+}
+
+TEST_CASE("Dye replaceSColor 1 1 sse2", "")
+{
+ DyePalette palette("#00ff00,000011", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceSColor 1 2 sse2", "")
+{
+ DyePalette palette("#403020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0x30, 0x20, 0x10);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 1 3 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 2 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[2];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 3 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[3];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x30, 0x20, 0x30);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30));
+}
+
+TEST_CASE("Dye replaceSColor 4 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[4];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 5 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[5];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x30);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x30));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 7 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[7];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+}
+
+TEST_CASE("Dye replaceSColor 8 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+}
+
+TEST_CASE("Dye replaceSColor 9 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[9];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0xff, 0x30, 0x20, 0x70);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x70, 0x60, 0x50, 0x70));
+}
+
+TEST_CASE("Dye replaceSColor 10 1 sse2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[10];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0x12, 0x34, 0x56, 0x70);
+ data[9] = buildHex(0xff, 0x30, 0x20, 0x80);
+ DYEPALETTE(palette, SColorSse2)(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x00, 0x00, 0x00, 0x70));
+ REQUIRE(data[9] == buildHex(0x70, 0x60, 0x50, 0x80));
+}
+
+TEST_CASE("Dye replaceSColor 1 1 avx2", "")
+{
+ DyePalette palette("#00ff00,000011", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceSColor 1 2 avx2", "")
+{
+ DyePalette palette("#403020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0x40, 0x30, 0x20, 0x10);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 1 3 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[1];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+}
+
+TEST_CASE("Dye replaceSColor 2 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[2];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 3 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[3];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x30, 0x20, 0x30);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30));
+}
+
+TEST_CASE("Dye replaceSColor 4 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[4];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 5 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[5];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x30);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x20);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x30));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x20));
+}
+
+TEST_CASE("Dye replaceSColor 7 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[7];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+}
+
+TEST_CASE("Dye replaceSColor 8 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[8];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+}
+
+TEST_CASE("Dye replaceSColor 9 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[9];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0xff, 0x30, 0x20, 0x70);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x70, 0x60, 0x50, 0x70));
+}
+
+TEST_CASE("Dye replaceSColor 10 1 avx2", "")
+{
+ DyePalette palette("#123456,000000,ff3020,706050", 6);
+ uint32_t data[10];
+ data[0] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[1] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[2] = buildHex(0xff, 0x40, 0x20, 0x10);
+ data[3] = buildHex(0xff, 0x30, 0x20, 0x20);
+ data[4] = buildHex(0xff, 0x30, 0x20, 0x10);
+ data[5] = buildHex(0xff, 0x30, 0x20, 0x40);
+ data[6] = buildHex(0xff, 0x40, 0x20, 0x50);
+ data[7] = buildHex(0xff, 0x30, 0x20, 0x60);
+ data[8] = buildHex(0x12, 0x34, 0x56, 0x70);
+ data[9] = buildHex(0xff, 0x30, 0x20, 0x80);
+ DYEPALETTE(palette, SColorAvx2)(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10));
+ REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20));
+ REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10));
+ REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40));
+ REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50));
+ REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60));
+ REQUIRE(data[8] == buildHex(0x00, 0x00, 0x00, 0x70));
+ REQUIRE(data[9] == buildHex(0x70, 0x60, 0x50, 0x80));
+}
+
+
+TEST_CASE("Dye replaceAColor 1 1", "")
+{
+ DyePalette palette("#00ff0010,00001120", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, AColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceAColor 1 2", "")
+{
+ DyePalette palette("#02ff0120,040311ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x02, 0xff, 0x01, 0x20);
+ DYEPALETTE(palette, AColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x04, 0x03, 0x11, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 3", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 2 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[2];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 3 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[3];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x50, 0x40, 0x40, 0x30);
+ data[2] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x50, 0x40, 0x40, 0x30));
+ REQUIRE(data[2] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 4 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[4];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 5 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[5];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x50, 0x40, 0x40, 0x60);
+ data[4] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x50, 0x40, 0x40, 0x60));
+ REQUIRE(data[4] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 7 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[7];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ DYEPALETTE(palette, AColor)(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+}
+
+TEST_CASE("Dye replaceAColor 8 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 9 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[9];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 10 1", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[10];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[9] = buildHex(0x01, 0x00, 0xee, 0x40);
+ DYEPALETTE(palette, AColor)(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[9] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 1 default", "")
+{
+ DyePalette palette("#00ff0010,00001120", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ palette.replaceAColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceAColor 1 2 default", "")
+{
+ DyePalette palette("#02ff0120,040311ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x02, 0xff, 0x01, 0x20);
+ palette.replaceAColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x04, 0x03, 0x11, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 3 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ palette.replaceAColorDefault(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 2 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[2];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ palette.replaceAColorDefault(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 3 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[3];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x50, 0x40, 0x40, 0x30);
+ data[2] = buildHex(0x40, 0x40, 0x40, 0x40);
+ palette.replaceAColorDefault(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x50, 0x40, 0x40, 0x30));
+ REQUIRE(data[2] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 4 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[4];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ palette.replaceAColorDefault(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 5 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[5];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x50, 0x40, 0x40, 0x60);
+ data[4] = buildHex(0x40, 0x40, 0x40, 0x40);
+ palette.replaceAColorDefault(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x50, 0x40, 0x40, 0x60));
+ REQUIRE(data[4] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 7 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[7];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ palette.replaceAColorDefault(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+}
+
+TEST_CASE("Dye replaceAColor 8 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x40, 0x40, 0x40, 0x40);
+ palette.replaceAColorDefault(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 9 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[9];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ palette.replaceAColorDefault(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 10 1 default", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[10];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[9] = buildHex(0x01, 0x00, 0xee, 0x40);
+ palette.replaceAColorDefault(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[9] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 1 sse2", "")
+{
+ DyePalette palette("#00ff0010,00001120", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceAColor 1 2 sse2", "")
+{
+ DyePalette palette("#02ff0120,040311ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x02, 0xff, 0x01, 0x20);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x04, 0x03, 0x11, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 3 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 2 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[2];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 3 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[3];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x50, 0x40, 0x40, 0x30);
+ data[2] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x50, 0x40, 0x40, 0x30));
+ REQUIRE(data[2] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 4 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[4];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 5 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[5];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x50, 0x40, 0x40, 0x60);
+ data[4] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x50, 0x40, 0x40, 0x60));
+ REQUIRE(data[4] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 7 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[7];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+}
+
+TEST_CASE("Dye replaceAColor 8 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 9 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[9];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 10 1 sse2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[10];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[9] = buildHex(0x01, 0x00, 0xee, 0x40);
+ DYEPALETTE(palette, AColorSse2)(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[9] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 1 avx2", "")
+{
+ DyePalette palette("#00ff0010,00001120", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x10, 0x03, 0x02, 0x01);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01));
+}
+
+TEST_CASE("Dye replaceAColor 1 2 avx2", "")
+{
+ DyePalette palette("#02ff0120,040311ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x02, 0xff, 0x01, 0x20);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x04, 0x03, 0x11, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 1 3 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[1];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+TEST_CASE("Dye replaceAColor 2 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[2];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 2);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 3 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[3];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x50, 0x40, 0x40, 0x30);
+ data[2] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 3);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x50, 0x40, 0x40, 0x30));
+ REQUIRE(data[2] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 4 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[4];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 4);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 5 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[5];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x50, 0x40, 0x40, 0x60);
+ data[4] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 5);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x50, 0x40, 0x40, 0x60));
+ REQUIRE(data[4] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 7 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[7];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 7);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+}
+
+TEST_CASE("Dye replaceAColor 8 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[8];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 8);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 9 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[9];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 9);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+}
+
+TEST_CASE("Dye replaceAColor 10 1 avx2", "")
+{
+ DyePalette palette("#40404040,20000000,0100ee40,102030ff", 8);
+ uint32_t data[10];
+ data[0] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[1] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[2] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[3] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[4] = buildHex(0x01, 0x00, 0xee, 0x40);
+ data[5] = buildHex(0x40, 0x40, 0x41, 0x40);
+ data[6] = buildHex(0x01, 0x00, 0xee, 0x50);
+ data[7] = buildHex(0x02, 0x40, 0x40, 0x40);
+ data[8] = buildHex(0x40, 0x40, 0x40, 0x40);
+ data[9] = buildHex(0x01, 0x00, 0xee, 0x40);
+ DYEPALETTE(palette, AColorAvx2)(&data[0], 10);
+ REQUIRE(data[0] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[1] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[2] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[3] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[4] == buildHex(0x10, 0x20, 0x30, 0xff));
+ REQUIRE(data[5] == buildHex(0x40, 0x40, 0x41, 0x40));
+ REQUIRE(data[6] == buildHex(0x01, 0x00, 0xee, 0x50));
+ REQUIRE(data[7] == buildHex(0x02, 0x40, 0x40, 0x40));
+ REQUIRE(data[8] == buildHex(0x20, 0x00, 0x00, 0x00));
+ REQUIRE(data[9] == buildHex(0x10, 0x20, 0x30, 0xff));
+}
+
+
+TEST_CASE("Dye normalDye 1", "")
+{
+ Dye dye("R:#203040,506070");
+ uint32_t data[1];
+ data[0] = buildHex(0x50, 0x00, 0x00, 0x55);
+ dye.normalDye(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x14, 0x1e, 0x28, 0x55));
+}
+
+TEST_CASE("Dye normalDye 2", "")
+{
+ Dye dye("G:#203040,506070");
+ uint32_t data[1];
+ data[0] = buildHex(0x00, 0x50, 0x00, 0x60);
+ dye.normalDye(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x14, 0x1e, 0x28, 0x60));
+}
+
+
+#ifdef USE_OPENGL
+TEST_CASE("Dye normalOGLDye 1", "")
+{
+ Dye dye("R:#203040,506070");
+ uint32_t data[1];
+ data[0] = buildHex(0x50, 0x00, 0x00, 0x55);
+ dye.normalOGLDye(&data[0], 1);
+ REQUIRE(data[0] == buildHex(0x50, 0x2a, 0x20, 0x15));
+}
+#endif // USE_OPENGL
+
+static void dyeCheck(const std::string &dyeString,
+ const std::string &dstName)
+{
+ const std::string srcName = "arrow_up.png";
+
+ Image *const image1 = Loader::getImage(srcName + dyeString);
+ Image *const image2 = Loader::getImage(dstName);
+ REQUIRE(image1 != nullptr);
+ REQUIRE(image2 != nullptr);
+ SDL_Surface *const surface1 = image1->getSDLSurface();
+ SDL_Surface *const surface2 = image2->getSDLSurface();
+ REQUIRE(surface1 != nullptr);
+ REQUIRE(surface2 != nullptr);
+ REQUIRE(surface1->w == surface2->w);
+ REQUIRE(surface1->h == surface2->h);
+ REQUIRE(surface1->pixels != nullptr);
+ REQUIRE(surface2->pixels != nullptr);
+ const uint32_t *const ptr1 = static_cast<const uint32_t *>(
+ surface1->pixels);
+ const uint32_t *const ptr2 = static_cast<const uint32_t *>(
+ surface2->pixels);
+ const size_t sz = surface1->w * surface1->h;
+ for (size_t idx = 0; idx < sz; idx ++)
+ {
+ REQUIRE(ptr1[idx] == ptr2[idx]);
+ }
+ image2->decRef();
+ image1->decRef();
+}
+
+TEST_CASE("Dye real dye", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+#ifdef USE_SDL2
+ imageHelper = new SurfaceImageHelper;
+
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ imageHelper = new SDLImageHelper;
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ SECTION("B dye")
+ {
+ dyeCheck("|B:#FFC88A", "arrow_up_B.png");
+ }
+
+ SECTION("S dye")
+ {
+ dyeCheck("|S:#0000FF,FF0000", "arrow_up_S.png");
+ }
+
+ SECTION("A dye")
+ {
+ dyeCheck("|A:#0000FFFF,FF000050", "arrow_up_A.png");
+ }
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("Dye leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/resources/dye/dyepalette_unittest.cc b/src/unittests/resources/dye/dyepalette_unittest.cc
new file mode 100644
index 000000000..0e99e9871
--- /dev/null
+++ b/src/unittests/resources/dye/dyepalette_unittest.cc
@@ -0,0 +1,422 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "configmanager.h"
+#include "dirs.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/db/palettedb.h"
+
+#include "resources/dye/dyepalette.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#ifndef USE_SDL2
+#include <SDL.h>
+#endif // USE_SDL2
+PRAGMA48(GCC diagnostic pop)
+
+#include "debug.h"
+
+TEST_CASE("DyePalette leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("DyePalette tests", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ theme = new Theme;
+ Theme::selectSkin();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+ paths.setDefaultValues(getPathsDefaults());
+ PaletteDB::load();
+
+ SECTION("simple test 1")
+ {
+ DyePalette palette("#12ff34", 6);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x00);
+ }
+
+ SECTION("simple test 2")
+ {
+ DyePalette palette("#12ff3456", 8);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x56);
+ }
+
+ SECTION("simple test 3")
+ {
+ DyePalette palette("#12ff34,002211", 6);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x00);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x00);
+ REQUIRE(palette.mColors[1].value[1] == 0x22);
+ REQUIRE(palette.mColors[1].value[2] == 0x11);
+ REQUIRE(palette.mColors[1].value[3] == 0x00);
+ }
+
+ SECTION("simple test 4")
+ {
+ DyePalette palette("#12ff3412,00221133", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x12);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x00);
+ REQUIRE(palette.mColors[1].value[1] == 0x22);
+ REQUIRE(palette.mColors[1].value[2] == 0x11);
+ REQUIRE(palette.mColors[1].value[3] == 0x33);
+ }
+
+ SECTION("simple test 5")
+ {
+ DyePalette palette("#12ff34,", 6);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x00);
+ }
+
+ SECTION("simple test 6")
+ {
+ DyePalette palette("#12ff3456,", 8);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x56);
+ }
+
+ SECTION("simple test 7")
+ {
+ DyePalette palette("#,,,12ff3412,,00221133", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x12);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x00);
+ REQUIRE(palette.mColors[1].value[1] == 0x22);
+ REQUIRE(palette.mColors[1].value[2] == 0x11);
+ REQUIRE(palette.mColors[1].value[3] == 0x33);
+ }
+
+ SECTION("palette test 1")
+ {
+ DyePalette palette("@Untitled1", 6);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 255);
+ }
+
+ SECTION("palette test 2")
+ {
+ DyePalette palette("@Untitled1,Untitled8", 6);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 255);
+
+ REQUIRE(palette.mColors[1].value[0] == 0);
+ REQUIRE(palette.mColors[1].value[1] == 0);
+ REQUIRE(palette.mColors[1].value[2] == 255);
+ REQUIRE(palette.mColors[1].value[3] == 255);
+ }
+
+ SECTION("palette test 3")
+ {
+ DyePalette palette("@Untitled1,", 6);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 255);
+ }
+
+ SECTION("palette test 4")
+ {
+ DyePalette palette("@,,,Untitled1,,Untitled8", 6);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 255);
+
+ REQUIRE(palette.mColors[1].value[0] == 0);
+ REQUIRE(palette.mColors[1].value[1] == 0);
+ REQUIRE(palette.mColors[1].value[2] == 255);
+ REQUIRE(palette.mColors[1].value[3] == 255);
+ }
+
+ SECTION("palette test 5")
+ {
+ DyePalette palette("@12ff34", 6);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x00);
+ }
+
+ SECTION("palette test 6")
+ {
+ DyePalette palette("@12ff3456", 8);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x56);
+ }
+
+ SECTION("palette test 7")
+ {
+ DyePalette palette("@12ff34,002211", 6);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x00);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x00);
+ REQUIRE(palette.mColors[1].value[1] == 0x22);
+ REQUIRE(palette.mColors[1].value[2] == 0x11);
+ REQUIRE(palette.mColors[1].value[3] == 0x00);
+ }
+
+ SECTION("palette test 8")
+ {
+ DyePalette palette("@12ff3412,00221133", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x12);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x00);
+ REQUIRE(palette.mColors[1].value[1] == 0x22);
+ REQUIRE(palette.mColors[1].value[2] == 0x11);
+ REQUIRE(palette.mColors[1].value[3] == 0x33);
+ }
+
+ SECTION("palette test 9")
+ {
+ DyePalette palette("@12ff34,", 6);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x00);
+ }
+
+ SECTION("palette test 10")
+ {
+ DyePalette palette("@12ff3456,", 8);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x56);
+ }
+
+ SECTION("palette test 11")
+ {
+ DyePalette palette("@,,,12ff3412,,00221133", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 0x12);
+ REQUIRE(palette.mColors[0].value[1] == 0xff);
+ REQUIRE(palette.mColors[0].value[2] == 0x34);
+ REQUIRE(palette.mColors[0].value[3] == 0x12);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x00);
+ REQUIRE(palette.mColors[1].value[1] == 0x22);
+ REQUIRE(palette.mColors[1].value[2] == 0x11);
+ REQUIRE(palette.mColors[1].value[3] == 0x33);
+ }
+
+ SECTION("palette test 12")
+ {
+ DyePalette palette("@Untitled1,334455", 6);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 255);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x33);
+ REQUIRE(palette.mColors[1].value[1] == 0x44);
+ REQUIRE(palette.mColors[1].value[2] == 0x55);
+ REQUIRE(palette.mColors[1].value[3] == 0x00);
+ }
+
+ SECTION("palette test 13")
+ {
+ DyePalette palette("@Untitled1,33445566", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 255);
+
+ REQUIRE(palette.mColors[1].value[0] == 0x33);
+ REQUIRE(palette.mColors[1].value[1] == 0x44);
+ REQUIRE(palette.mColors[1].value[2] == 0x55);
+ REQUIRE(palette.mColors[1].value[3] == 0x66);
+ }
+
+ SECTION("palette test 14")
+ {
+ DyePalette palette("@+77,Untitled1", 8);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 0x77);
+ }
+
+ SECTION("palette test 15")
+ {
+ DyePalette palette("@+87,Untitled1,Untitled8", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 0x87);
+
+ REQUIRE(palette.mColors[1].value[0] == 0);
+ REQUIRE(palette.mColors[1].value[1] == 0);
+ REQUIRE(palette.mColors[1].value[2] == 255);
+ REQUIRE(palette.mColors[1].value[3] == 0x87);
+ }
+
+ SECTION("palette test 16")
+ {
+ DyePalette palette("@+87,Untitled1,+34,Untitled8", 8);
+ REQUIRE(palette.mColors.size() == 2);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 0x87);
+
+ REQUIRE(palette.mColors[1].value[0] == 0);
+ REQUIRE(palette.mColors[1].value[1] == 0);
+ REQUIRE(palette.mColors[1].value[2] == 255);
+ REQUIRE(palette.mColors[1].value[3] == 0x34);
+ }
+
+ SECTION("palette test 17")
+ {
+ DyePalette palette("@+12,+23,+77,Untitled1", 8);
+ REQUIRE(palette.mColors.size() == 1);
+ REQUIRE(palette.mColors[0].value[0] == 47);
+ REQUIRE(palette.mColors[0].value[1] == 56);
+ REQUIRE(palette.mColors[0].value[2] == 46);
+ REQUIRE(palette.mColors[0].value[3] == 0x77);
+ }
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("DyePalette leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/resources/map/maplayer_unittest.cc b/src/unittests/resources/map/maplayer_unittest.cc
new file mode 100644
index 000000000..85d8c4f09
--- /dev/null
+++ b/src/unittests/resources/map/maplayer_unittest.cc
@@ -0,0 +1,3213 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "graphicsmanager.h"
+
+#include "being/localplayer.h"
+
+#include "enums/resources/map/blockmask.h"
+#include "enums/resources/map/mapitemtype.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/theme.h"
+
+#include "unittests/render/mockgraphics.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/image/image.h"
+
+#include "resources/map/map.h"
+#include "resources/map/maplayer.h"
+#include "resources/map/speciallayer.h"
+
+#include "debug.h"
+
+TEST_CASE("MapLayer getTileDrawWidth", "")
+{
+ Image *const img1 = new Image(32, 32);
+ Image *const img2 = new Image(32, 32);
+ Image *const img3 = new Image(32, 32);
+ MapLayer *layer = nullptr;
+ int width;
+ int nextTile;
+
+ SECTION("simple 1")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 2")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 2,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 1);
+ }
+
+ SECTION("simple 3")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 1,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 4")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 2,
+ width,
+ nextTile) == 1);
+ REQUIRE(width == 64);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 1,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 4.2")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(2, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 3,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 2,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 5")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 3,
+ width,
+ nextTile) == 1);
+ REQUIRE(width == 64);
+ REQUIRE(nextTile == 2);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 1,
+ 2,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 1);
+ }
+
+ SECTION("simple 6")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 3,
+ width,
+ nextTile) == 1);
+ REQUIRE(width == 64);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 1,
+ 2,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 2,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 7")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ tiles[1].isEnabled = false;
+ REQUIRE(layer->getTileDrawWidth(tiles,
+ 3,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 1);
+
+// REQUIRE(layer->getTileDrawWidth(tiles + 1,
+// 2,
+// width,
+// nextTile) == 0);
+// REQUIRE(width == 32);
+// REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 2,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 8")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ tiles[0].isEnabled = false;
+// REQUIRE(layer->getTileDrawWidth(tiles,
+// 3,
+// width,
+// nextTile) == 1);
+// REQUIRE(width == 0);
+// REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 1,
+ 2,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 2,
+ 1,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("normal 1")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 100,
+ false,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ TileInfo *const tiles = layer->getTiles();
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 1,
+ 100 - 1,
+ width,
+ nextTile) == 2);
+ REQUIRE(width == 96);
+ REQUIRE(nextTile == 2);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 2,
+ 100 - 2,
+ width,
+ nextTile) == 1);
+ REQUIRE(width == 64);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 3,
+ 100 - 3,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 4,
+ 100 - 4,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 6,
+ 100 - 6,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 2);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 9,
+ 100 - 9,
+ width,
+ nextTile) == 1);
+ REQUIRE(width == 64);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 10,
+ 100 - 10,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 11,
+ 100 - 11,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 3);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 15,
+ 100 - 15,
+ width,
+ nextTile) == 2);
+ REQUIRE(width == 96);
+ REQUIRE(nextTile == 84);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 16,
+ 100 - 16,
+ width,
+ nextTile) == 1);
+ REQUIRE(width == 64);
+ REQUIRE(nextTile == 83);
+
+ REQUIRE(layer->getTileDrawWidth(tiles + 10 * 100 + 17,
+ 100 - 17,
+ width,
+ nextTile) == 0);
+ REQUIRE(width == 32);
+ REQUIRE(nextTile == 82);
+ }
+
+ delete layer;
+ delete img1;
+ delete img2;
+ delete img3;
+}
+
+
+TEST_CASE("MapLayer getEmptyTileDrawWidth", "")
+{
+ Image *const img1 = new Image(32, 32);
+ Image *const img2 = new Image(32, 32);
+ Image *const img3 = new Image(32, 32);
+ MapLayer *layer = nullptr;
+ int nextTile;
+
+ SECTION("simple 2")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 1,
+ 1,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 4")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(2, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 1,
+ 2,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("simple 5")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 2,
+ 1,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+ }
+
+ SECTION("normal 1")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 100,
+ false,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ TileInfo *const tiles = layer->getTiles();
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 0,
+ 100 - 0,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 5,
+ 100 - 5,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 7,
+ 100 - 7,
+ nextTile) == 1);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 8,
+ 100 - 8,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 12,
+ 100 - 12,
+ nextTile) == 2);
+ REQUIRE(nextTile == 2);
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 13,
+ 100 - 13,
+ nextTile) == 1);
+ REQUIRE(nextTile == 1);
+
+ REQUIRE(layer->getEmptyTileDrawWidth(tiles + 10 * 100 + 14,
+ 100 - 14,
+ nextTile) == 0);
+ REQUIRE(nextTile == 0);
+ }
+
+ delete layer;
+ delete img1;
+ delete img2;
+ delete img3;
+}
+
+
+TEST_CASE("MapLayer updateCache", "")
+{
+ Image *const img1 = new Image(32, 32);
+ Image *const img2 = new Image(32, 32);
+ Image *const img3 = new Image(32, 32);
+ MapLayer *layer = nullptr;
+
+ SECTION("simple 1")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(1, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 32);
+ REQUIRE(tiles[0].count == 0);
+ REQUIRE(tiles[0].nextTile == 0);
+ }
+
+ SECTION("simple 2")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(2, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 32);
+ REQUIRE(tiles[0].count == 0);
+ REQUIRE(tiles[0].nextTile == 1);
+ REQUIRE(tiles[1].isEnabled == false);
+ REQUIRE(tiles[1].width == 0);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 0);
+ }
+
+ SECTION("simple 3")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(2, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 32);
+ REQUIRE(tiles[0].count == 0);
+ REQUIRE(tiles[0].nextTile == 0);
+ REQUIRE(tiles[1].isEnabled == true);
+ REQUIRE(tiles[1].width == 32);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 0);
+ }
+
+ SECTION("simple 4")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(2, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 64);
+ REQUIRE(tiles[0].count == 1);
+ REQUIRE(tiles[0].nextTile == 1);
+ REQUIRE(tiles[1].isEnabled == true);
+ REQUIRE(tiles[1].width == 32);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 0);
+ }
+
+ SECTION("simple 4.2")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(2, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(3, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 32);
+ REQUIRE(tiles[0].count == 0);
+ REQUIRE(tiles[0].nextTile == 1);
+ REQUIRE(tiles[1].isEnabled == false);
+ REQUIRE(tiles[1].width == 0);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 0);
+ REQUIRE(tiles[2].isEnabled == true);
+ REQUIRE(tiles[2].width == 32);
+ REQUIRE(tiles[2].count == 0);
+ REQUIRE(tiles[2].nextTile == 0);
+ }
+
+ SECTION("simple 5")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(3, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 64);
+ REQUIRE(tiles[0].count == 1);
+ REQUIRE(tiles[0].nextTile == 2);
+ REQUIRE(tiles[1].isEnabled == true);
+ REQUIRE(tiles[1].width == 32);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 1);
+ REQUIRE(tiles[2].isEnabled == false);
+ REQUIRE(tiles[2].width == 0);
+ REQUIRE(tiles[2].count == 0);
+ REQUIRE(tiles[2].nextTile == 0);
+ }
+
+ SECTION("simple 6")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(3, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ REQUIRE(tiles[0].width == 64);
+ REQUIRE(tiles[0].count == 1);
+ REQUIRE(tiles[0].nextTile == 1);
+ REQUIRE(tiles[1].isEnabled == true);
+ REQUIRE(tiles[1].width == 32);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 0);
+ REQUIRE(tiles[2].isEnabled == true);
+ REQUIRE(tiles[2].width == 32);
+ REQUIRE(tiles[2].count == 0);
+ REQUIRE(tiles[2].nextTile == 0);
+ }
+
+ SECTION("simple 7")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ TileInfo *const tiles = layer->getTiles();
+ tiles[0].isEnabled = false;
+ layer->updateCache(3, 1);
+ REQUIRE(tiles[0].isEnabled == false);
+ REQUIRE(tiles[0].width == 0);
+ REQUIRE(tiles[0].count == 0);
+ REQUIRE(tiles[0].nextTile == 0);
+ REQUIRE(tiles[1].isEnabled == true);
+ REQUIRE(tiles[1].width == 32);
+ REQUIRE(tiles[1].count == 0);
+ REQUIRE(tiles[1].nextTile == 0);
+ REQUIRE(tiles[2].isEnabled == true);
+ REQUIRE(tiles[2].width == 32);
+ REQUIRE(tiles[2].count == 0);
+ REQUIRE(tiles[2].nextTile == 0);
+ }
+
+ SECTION("normal 1")
+ {
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 100,
+ false,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ TileInfo *const tiles = layer->getTiles();
+ layer->updateCache(100, 100);
+
+ REQUIRE(tiles[0 * 100 + 0].isEnabled == false);
+ REQUIRE(tiles[0 * 100 + 0].width == 0);
+ REQUIRE(tiles[0 * 100 + 0].count == 99);
+ REQUIRE(tiles[0 * 100 + 0].nextTile == 99);
+
+ REQUIRE(tiles[0 * 100 + 1].isEnabled == false);
+ REQUIRE(tiles[0 * 100 + 1].width == 0);
+ REQUIRE(tiles[0 * 100 + 1].count == 98);
+ REQUIRE(tiles[0 * 100 + 1].nextTile == 98);
+
+ REQUIRE(tiles[10 * 100 + 0].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 0].width == 0);
+ REQUIRE(tiles[10 * 100 + 0].count == 0);
+ REQUIRE(tiles[10 * 100 + 0].nextTile == 0);
+
+ REQUIRE(tiles[10 * 100 + 1].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 1].width == 96);
+ REQUIRE(tiles[10 * 100 + 1].count == 2);
+ REQUIRE(tiles[10 * 100 + 1].nextTile == 2);
+
+ REQUIRE(tiles[10 * 100 + 2].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 2].width == 64);
+ REQUIRE(tiles[10 * 100 + 2].count == 1);
+ REQUIRE(tiles[10 * 100 + 2].nextTile == 1);
+
+ REQUIRE(tiles[10 * 100 + 3].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 3].width == 32);
+ REQUIRE(tiles[10 * 100 + 3].count == 0);
+ REQUIRE(tiles[10 * 100 + 3].nextTile == 0);
+
+ REQUIRE(tiles[10 * 100 + 4].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 4].width == 32);
+ REQUIRE(tiles[10 * 100 + 4].count == 0);
+ REQUIRE(tiles[10 * 100 + 4].nextTile == 1);
+
+ REQUIRE(tiles[10 * 100 + 5].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 5].width == 0);
+ REQUIRE(tiles[10 * 100 + 5].count == 0);
+ REQUIRE(tiles[10 * 100 + 5].nextTile == 0);
+
+ REQUIRE(tiles[10 * 100 + 6].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 6].width == 32);
+ REQUIRE(tiles[10 * 100 + 6].count == 0);
+ REQUIRE(tiles[10 * 100 + 6].nextTile == 2);
+
+ REQUIRE(tiles[10 * 100 + 7].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 7].width == 0);
+ REQUIRE(tiles[10 * 100 + 7].count == 1);
+ REQUIRE(tiles[10 * 100 + 7].nextTile == 1);
+
+ REQUIRE(tiles[10 * 100 + 8].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 8].width == 0);
+ REQUIRE(tiles[10 * 100 + 8].count == 0);
+ REQUIRE(tiles[10 * 100 + 8].nextTile == 0);
+
+ REQUIRE(tiles[10 * 100 + 9].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 9].width == 64);
+ REQUIRE(tiles[10 * 100 + 9].count == 1);
+ REQUIRE(tiles[10 * 100 + 9].nextTile == 1);
+
+ REQUIRE(tiles[10 * 100 + 10].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 10].width == 32);
+ REQUIRE(tiles[10 * 100 + 10].count == 0);
+ REQUIRE(tiles[10 * 100 + 10].nextTile == 0);
+
+ REQUIRE(tiles[10 * 100 + 11].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 11].width == 32);
+ REQUIRE(tiles[10 * 100 + 11].count == 0);
+ REQUIRE(tiles[10 * 100 + 11].nextTile == 3);
+
+ REQUIRE(tiles[10 * 100 + 12].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 12].width == 0);
+ REQUIRE(tiles[10 * 100 + 12].count == 2);
+ REQUIRE(tiles[10 * 100 + 12].nextTile == 2);
+
+ REQUIRE(tiles[10 * 100 + 13].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 13].width == 0);
+ REQUIRE(tiles[10 * 100 + 13].count == 1);
+ REQUIRE(tiles[10 * 100 + 13].nextTile == 1);
+
+ REQUIRE(tiles[10 * 100 + 14].isEnabled == false);
+ REQUIRE(tiles[10 * 100 + 14].width == 0);
+ REQUIRE(tiles[10 * 100 + 14].count == 0);
+ REQUIRE(tiles[10 * 100 + 14].nextTile == 0);
+
+ REQUIRE(tiles[10 * 100 + 15].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 15].width == 96);
+ REQUIRE(tiles[10 * 100 + 15].count == 2);
+ REQUIRE(tiles[10 * 100 + 15].nextTile == 84);
+
+ REQUIRE(tiles[10 * 100 + 16].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 16].width == 64);
+ REQUIRE(tiles[10 * 100 + 16].count == 1);
+ REQUIRE(tiles[10 * 100 + 16].nextTile == 83);
+
+ REQUIRE(tiles[10 * 100 + 17].isEnabled == true);
+ REQUIRE(tiles[10 * 100 + 17].width == 32);
+ REQUIRE(tiles[10 * 100 + 17].count == 0);
+ REQUIRE(tiles[10 * 100 + 17].nextTile == 82);
+ }
+
+ SECTION("normal2")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ false,
+ 0,
+ 0);
+ TileInfo *const tiles = layer->getTiles();
+ for (int x = 0; x < maxX; x ++)
+ {
+ for (int y = 0; y < maxY; y ++)
+ {
+ layer->setTile(x, y, img1);
+ tiles[y * maxX + x].isEnabled = false;
+ }
+ }
+ tiles[10 * maxX + 41].isEnabled = true;
+ layer->updateCache(maxX, maxY);
+
+ REQUIRE(tiles[10 * maxX + 0].isEnabled == false);
+ REQUIRE(tiles[10 * maxX + 0].width == 0);
+ REQUIRE(tiles[10 * maxX + 0].count == 40);
+ REQUIRE(tiles[10 * maxX + 0].nextTile == 40);
+
+ REQUIRE(tiles[10 * maxX + 1].isEnabled == false);
+ REQUIRE(tiles[10 * maxX + 1].width == 0);
+ REQUIRE(tiles[10 * maxX + 1].count == 39);
+ REQUIRE(tiles[10 * maxX + 1].nextTile == 39);
+ }
+
+ delete layer;
+ delete img1;
+ delete img2;
+ delete img3;
+}
+
+TEST_CASE("MapLayer updateConditionTiles", "")
+{
+ Image *const img1 = new Image(32, 32);
+ Map *map = nullptr;
+ MapLayer *layer = nullptr;
+
+ SECTION("simple 1")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ map->addLayer(layer);
+ layer->setTileCondition(BlockMask::WATER);
+ TileInfo *const tiles = layer->getTiles();
+
+ map->addBlockMask(0, 0, BlockType::NONE);
+ layer->updateConditionTiles(map->getMetaTiles(),
+ 1, 1);
+ REQUIRE(tiles[0].isEnabled == false);
+
+ map->addBlockMask(0, 0, BlockType::WATER);
+ layer->updateConditionTiles(map->getMetaTiles(),
+ 1, 1);
+ REQUIRE(tiles[0].isEnabled == true);
+ }
+
+ SECTION("normal 1")
+ {
+ map = new Map("map",
+ 100, 200,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 200,
+ false,
+ 0,
+ 0);
+ layer->setTile(10, 10, img1);
+ layer->setTile(10, 20, img1);
+ layer->setTile(10, 30, img1);
+ map->addLayer(layer);
+ layer->setTileCondition(BlockMask::WATER);
+ TileInfo *const tiles = layer->getTiles();
+
+ map->addBlockMask(10, 10, BlockType::NONE);
+ map->addBlockMask(10, 20, BlockType::NONE);
+ map->addBlockMask(20, 20, BlockType::NONE);
+ layer->updateConditionTiles(map->getMetaTiles(),
+ 100, 200);
+ for (int x = 0; x < 100; x ++)
+ {
+ for (int y = 0; y < 200; y ++)
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == false);
+ }
+ }
+ }
+
+ SECTION("normal 2")
+ {
+ map = new Map("map",
+ 100, 200,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 200,
+ false,
+ 0,
+ 0);
+ layer->setTile(10, 10, img1);
+ layer->setTile(10, 20, img1);
+ layer->setTile(10, 30, img1);
+ map->addLayer(layer);
+ layer->setTileCondition(BlockMask::WATER);
+ TileInfo *const tiles = layer->getTiles();
+
+ map->addBlockMask(10, 10, BlockType::WATER);
+ map->addBlockMask(10, 20, BlockType::WATER);
+ map->addBlockMask(20, 20, BlockType::WATER);
+ layer->updateConditionTiles(map->getMetaTiles(),
+ 100, 200);
+ for (int x = 0; x < 100; x ++)
+ {
+ for (int y = 0; y < 200; y ++)
+ {
+ if ((x == 10 && y == 10) || (x == 10 && y == 20))
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == true);
+ }
+ else
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == false);
+ }
+ }
+ }
+ }
+
+ SECTION("normal 3")
+ {
+ map = new Map("map",
+ 100, 200,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 200,
+ false,
+ 0,
+ 0);
+ for (int x = 0; x < 100; x ++)
+ {
+ for (int y = 0; y < 200; y ++)
+ {
+ layer->setTile(x, y, img1);
+ }
+ }
+ map->addLayer(layer);
+ layer->setTileCondition(BlockMask::WATER);
+ TileInfo *const tiles = layer->getTiles();
+
+ map->addBlockMask(10, 10, BlockType::WATER);
+ map->addBlockMask(10, 20, BlockType::WATER);
+ layer->updateConditionTiles(map->getMetaTiles(),
+ 100, 200);
+ for (int x = 0; x < 100; x ++)
+ {
+ for (int y = 0; y < 200; y ++)
+ {
+ if ((x == 10 && y == 10) || (x == 10 && y == 20))
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == true);
+ }
+ else
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == false);
+ }
+ }
+ }
+ }
+
+ SECTION("normal 4")
+ {
+ map = new Map("map",
+ 100, 200,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 100, 200,
+ false,
+ 0,
+ 0);
+ layer->setTile(10, 10, img1);
+ layer->setTile(10, 20, img1);
+ map->addLayer(layer);
+ layer->setTileCondition(BlockMask::WATER);
+ TileInfo *const tiles = layer->getTiles();
+
+ for (int x = 0; x < 100; x ++)
+ {
+ for (int y = 0; y < 200; y ++)
+ {
+ map->addBlockMask(x, y, BlockType::WATER);
+ }
+ }
+
+ layer->updateConditionTiles(map->getMetaTiles(),
+ 100, 200);
+ for (int x = 0; x < 100; x ++)
+ {
+ for (int y = 0; y < 200; y ++)
+ {
+ if ((x == 10 && y == 10) || (x == 10 && y == 20))
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == true);
+ }
+ else
+ {
+ REQUIRE(tiles[y * 100 + x].isEnabled == false);
+ }
+ }
+ }
+ }
+
+ delete map;
+ delete img1;
+}
+
+TEST_CASE("MapLayer draw", "")
+{
+ Image *const img1 = new Image(32, 32);
+ Image *const img2 = new Image(32, 32);
+ Image *const img3 = new Image(32, 32);
+ Map *map = nullptr;
+ MapLayer *layer = nullptr;
+ MockGraphics *const mock = new MockGraphics;
+
+ SECTION("simple 1")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ map->addLayer(layer);
+ layer->updateCache(1, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 1, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 1, 1,
+ 10, 5);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == -10);
+ REQUIRE(mock->mDraws[0].y == -5);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 1, 1,
+ -10, -5);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == 5);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 2")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ map->addLayer(layer);
+ layer->updateCache(2, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ 0, 0);
+
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ 10, 5);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == -10);
+ REQUIRE(mock->mDraws[0].y == -5);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ -10, -5);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == 5);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 3")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img2);
+ map->addLayer(layer);
+ layer->updateCache(2, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img2);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ -10, -20);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == 20);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 42);
+ REQUIRE(mock->mDraws[1].y == 20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ }
+
+ SECTION("simple 4")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ map->addLayer(layer);
+ layer->updateCache(2, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 2, 1,
+ -10, 20);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 4.2")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(2, 0, img1);
+ map->addLayer(layer);
+ layer->updateCache(3, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ 10, -20);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == -10);
+ REQUIRE(mock->mDraws[0].y == 20);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 54);
+ REQUIRE(mock->mDraws[1].y == 20);
+ REQUIRE(mock->mDraws[1].image == img1);
+ }
+
+ SECTION("simple 5")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ map->addLayer(layer);
+ layer->updateCache(3, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ -10, 20);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 6")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ map->addLayer(layer);
+ layer->updateCache(3, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img2);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ -10, 20);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 74);
+ REQUIRE(mock->mDraws[1].y == -20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ }
+
+ SECTION("simple 7")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ false,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ map->addLayer(layer);
+ TileInfo *const tiles = layer->getTiles();
+ tiles[0].isEnabled = false;
+ layer->updateCache(3, 1);
+
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img2);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ 3, 1,
+ -10, 20);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 42);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 74);
+ REQUIRE(mock->mDraws[1].y == -20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ }
+
+ SECTION("normal 1")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ false,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ map->addLayer(layer);
+ layer->updateCache(maxX, maxY);
+
+ layer->draw(mock,
+ 0, 0,
+ maxX, maxY,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 6);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 32 * 1);
+ REQUIRE(mock->mDraws[0].y == 32 * 10);
+ REQUIRE(mock->mDraws[0].width == 96);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32 * 4);
+ REQUIRE(mock->mDraws[1].y == 32 * 10);
+ REQUIRE(mock->mDraws[1].image == img2);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 6);
+ REQUIRE(mock->mDraws[2].y == 32 * 10);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[3].x == 32 * 9);
+ REQUIRE(mock->mDraws[3].y == 32 * 10);
+ REQUIRE(mock->mDraws[3].width == 64);
+ REQUIRE(mock->mDraws[3].height == 32);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[4].x == 32 * 11);
+ REQUIRE(mock->mDraws[4].y == 32 * 10);
+ REQUIRE(mock->mDraws[4].image == img3);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[5].x == 32 * 15);
+ REQUIRE(mock->mDraws[5].y == 32 * 10);
+ REQUIRE(mock->mDraws[5].width == 96);
+ REQUIRE(mock->mDraws[5].height == 32);
+ REQUIRE(mock->mDraws[5].image == img1);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ maxX, maxY,
+ -10, 20);
+ REQUIRE(mock->mDraws.size() == 6);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 32 * 1 + 10);
+ REQUIRE(mock->mDraws[0].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[0].width == 96);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32 * 4 + 10);
+ REQUIRE(mock->mDraws[1].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 6 + 10);
+ REQUIRE(mock->mDraws[2].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[3].x == 32 * 9 + 10);
+ REQUIRE(mock->mDraws[3].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[3].width == 64);
+ REQUIRE(mock->mDraws[3].height == 32);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[4].x == 32 * 11 + 10);
+ REQUIRE(mock->mDraws[4].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[4].image == img3);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[5].x == 32 * 15 + 10);
+ REQUIRE(mock->mDraws[5].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[5].width == 96);
+ REQUIRE(mock->mDraws[5].height == 32);
+ REQUIRE(mock->mDraws[5].image == img1);
+ }
+
+ SECTION("normal2")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ false,
+ 0,
+ 0);
+ TileInfo *const tiles = layer->getTiles();
+ map->addLayer(layer);
+ for (int x = 0; x < maxX; x ++)
+ {
+ for (int y = 0; y < maxY; y ++)
+ {
+ layer->setTile(x, y, img1);
+ tiles[y * maxX + x].isEnabled = false;
+ }
+ }
+ tiles[10 * maxX + 41].isEnabled = true;
+ layer->updateCache(maxX, maxY);
+
+ layer->draw(mock,
+ 0, 0,
+ maxX, maxY,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32 * 41);
+ REQUIRE(mock->mDraws[0].y == 32 * 10);
+
+ mock->mDraws.clear();
+ layer->draw(mock,
+ 0, 0,
+ maxX, maxY,
+ -10, 20);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32 * 41 + 10);
+ REQUIRE(mock->mDraws[0].y == 32 * 10 - 20);
+ }
+
+ delete map;
+ delete img1;
+ delete img2;
+ delete img3;
+ delete mock;
+}
+
+TEST_CASE("MapLayer drawSpecialLayer (specialLayer)", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ logger = new Logger;
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ Map *map = nullptr;
+ MapLayer *layer = nullptr;
+ SpecialLayer *specialLayer = nullptr;
+ MockGraphics *const mock = new MockGraphics;
+ const Actors actors;
+
+ SECTION("simple 1")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.empty());
+
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 1,
+ 0, 0);
+// REQUIRE(mock->mDraws.size() == 1);
+ }
+
+ SECTION("simple 2")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ }
+
+ SECTION("simple 3")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 2,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ }
+
+ SECTION("simple 4")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(1, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 2,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32);
+ REQUIRE(mock->mDraws[0].y == 0);
+ }
+
+ SECTION("simple 5")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(1, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 2,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32);
+ REQUIRE(mock->mDraws[1].y == 0);
+ }
+
+ SECTION("simple 6")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(2, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 3,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ }
+
+ SECTION("simple 7")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(1, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(2, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 3,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ }
+
+ SECTION("simple 8")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(1, 0, MapItemType::ARROW_DOWN);
+ specialLayer->setTile(2, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 3,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 3);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 64);
+ REQUIRE(mock->mDraws[2].y == 0);
+ }
+
+ SECTION("normal 1")
+ {
+ const int maxX = 100;
+ const int maxY = 50;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getSpecialLayer();
+ specialLayer->setTile(0, 5, MapItemType::ARROW_UP);
+ specialLayer->setTile(1, 5, MapItemType::ARROW_DOWN);
+ specialLayer->setTile(2, 5, MapItemType::ARROW_UP);
+ specialLayer->setTile(3, 5, MapItemType::EMPTY);
+ specialLayer->setTile(4, 5, MapItemType::EMPTY);
+ specialLayer->setTile(6, 5, MapItemType::ARROW_LEFT);
+ specialLayer->setTile(10, 20, MapItemType::ARROW_LEFT);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 5,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 4);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0 * 32);
+ REQUIRE(mock->mDraws[0].y == 5 * 32);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 1 * 32);
+ REQUIRE(mock->mDraws[1].y == 5 * 32);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 2 * 32);
+ REQUIRE(mock->mDraws[2].y == 5 * 32);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[3].x == 6 * 32);
+ REQUIRE(mock->mDraws[3].y == 5 * 32);
+
+ mock->mDraws.clear();
+ layer->drawSpecialLayer(mock,
+ 4,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.empty());
+
+ layer->drawSpecialLayer(mock,
+ 6,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.empty());
+
+ layer->drawSpecialLayer(mock,
+ 20,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10 * 32);
+ REQUIRE(mock->mDraws[0].y == 20 * 32);
+ }
+
+ delete map;
+ delete mock;
+ GraphicsManager::deleteRenderers();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("MapLayer drawSpecialLayer (tempLayer)", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ logger = new Logger;
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ Map *map = nullptr;
+ MapLayer *layer = nullptr;
+ SpecialLayer *specialLayer = nullptr;
+ MockGraphics *const mock = new MockGraphics;
+ const Actors actors;
+
+ SECTION("simple 1")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.empty());
+
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 1,
+ 0, 0);
+// REQUIRE(mock->mDraws.size() == 1);
+ }
+
+ SECTION("simple 2")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 1,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ }
+
+ SECTION("simple 3")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 2,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ }
+
+ SECTION("simple 4")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ const int *const cache = specialLayer->getCache();
+ REQUIRE(cache[0] == 10000);
+ REQUIRE(cache[1] == 10000);
+
+ specialLayer->setTile(1, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+ REQUIRE(cache[0] == 0);
+ REQUIRE(cache[1] == 10000);
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 2,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32);
+ REQUIRE(mock->mDraws[0].y == 0);
+ }
+
+ SECTION("simple 5")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(1, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 2,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32);
+ REQUIRE(mock->mDraws[1].y == 0);
+ }
+
+ SECTION("simple 6")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(2, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 3,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ }
+
+ SECTION("simple 7")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(1, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(2, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 3,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ }
+
+ SECTION("simple 8")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(0, 0, MapItemType::ARROW_UP);
+ specialLayer->setTile(1, 0, MapItemType::ARROW_DOWN);
+ specialLayer->setTile(2, 0, MapItemType::ARROW_UP);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 0,
+ 0, 3,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 3);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 64);
+ REQUIRE(mock->mDraws[2].y == 0);
+ }
+
+ SECTION("normal 1")
+ {
+ const int maxX = 100;
+ const int maxY = 50;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ true,
+ 0,
+ 0);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ specialLayer = map->getTempLayer();
+ specialLayer->setTile(0, 5, MapItemType::ARROW_UP);
+ specialLayer->setTile(1, 5, MapItemType::ARROW_DOWN);
+ specialLayer->setTile(2, 5, MapItemType::ARROW_UP);
+ specialLayer->setTile(3, 5, MapItemType::EMPTY);
+ specialLayer->setTile(4, 5, MapItemType::EMPTY);
+ specialLayer->setTile(6, 5, MapItemType::ARROW_LEFT);
+ specialLayer->setTile(10, 20, MapItemType::ARROW_LEFT);
+ specialLayer->updateCache();
+
+ layer->drawSpecialLayer(mock,
+ 5,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 4);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0 * 32);
+ REQUIRE(mock->mDraws[0].y == 5 * 32);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 1 * 32);
+ REQUIRE(mock->mDraws[1].y == 5 * 32);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 2 * 32);
+ REQUIRE(mock->mDraws[2].y == 5 * 32);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[3].x == 6 * 32);
+ REQUIRE(mock->mDraws[3].y == 5 * 32);
+
+ mock->mDraws.clear();
+ layer->drawSpecialLayer(mock,
+ 4,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.empty());
+
+ layer->drawSpecialLayer(mock,
+ 6,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.empty());
+
+ layer->drawSpecialLayer(mock,
+ 20,
+ 0, maxX,
+ 0, 0);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10 * 32);
+ REQUIRE(mock->mDraws[0].y == 20 * 32);
+ }
+
+ delete map;
+ delete mock;
+ GraphicsManager::deleteRenderers();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("MapLayer drawFringe", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ logger = new Logger;
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ theme = new Theme;
+ Theme::selectSkin();
+
+ localPlayer = new LocalPlayer(static_cast<BeingId>(1),
+ BeingTypeId_zero);
+
+ Image *const img1 = new Image(32, 32);
+ Image *const img2 = new Image(32, 32);
+ Image *const img3 = new Image(32, 32);
+ Map *map = nullptr;
+ MapLayer *layer = nullptr;
+ MockGraphics *const mock = new MockGraphics;
+ const Actors actors;
+
+ SECTION("simple 1")
+ {
+ map = new Map("map",
+ 1, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 1, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(1, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 1, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 1, 1,
+ 10, 5,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == -10);
+ REQUIRE(mock->mDraws[0].y == -5);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 1, 1,
+ -10, -5,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == 5);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 2")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(2, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ 0, 0,
+ actors);
+
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ 10, 5,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == -10);
+ REQUIRE(mock->mDraws[0].y == -5);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ -10, -5,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == 5);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 3")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img2);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(2, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img2);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ -10, -20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == 20);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 42);
+ REQUIRE(mock->mDraws[1].y == 20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ }
+
+ SECTION("simple 4")
+ {
+ map = new Map("map",
+ 2, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 2, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(2, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 2, 1,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 4.2")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(2, 0, img1);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(3, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ 10, -20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == -10);
+ REQUIRE(mock->mDraws[0].y == 20);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 54);
+ REQUIRE(mock->mDraws[1].y == 20);
+ REQUIRE(mock->mDraws[1].image == img1);
+ }
+
+ SECTION("simple 5")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(3, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ }
+
+ SECTION("simple 6")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(3, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 0);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img2);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 10);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].width == 64);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 74);
+ REQUIRE(mock->mDraws[1].y == -20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ }
+
+ SECTION("simple 7")
+ {
+ map = new Map("map",
+ 3, 1,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ 3, 1,
+ true,
+ 0,
+ 0);
+ layer->setTile(0, 0, img1);
+ layer->setTile(1, 0, img1);
+ layer->setTile(2, 0, img2);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ TileInfo *const tiles = layer->getTiles();
+ tiles[0].isEnabled = false;
+ layer->updateCache(3, 1);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32);
+ REQUIRE(mock->mDraws[0].y == 0);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 64);
+ REQUIRE(mock->mDraws[1].y == 0);
+ REQUIRE(mock->mDraws[1].image == img2);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ 3, 1,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 2);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 42);
+ REQUIRE(mock->mDraws[0].y == -20);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 74);
+ REQUIRE(mock->mDraws[1].y == -20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ }
+
+ SECTION("normal 1")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ true,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ layer->updateCache(maxX, maxY);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX, maxY,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 6);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 32 * 1);
+ REQUIRE(mock->mDraws[0].y == 32 * 10);
+ REQUIRE(mock->mDraws[0].width == 96);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32 * 4);
+ REQUIRE(mock->mDraws[1].y == 32 * 10);
+ REQUIRE(mock->mDraws[1].image == img2);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 6);
+ REQUIRE(mock->mDraws[2].y == 32 * 10);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[3].x == 32 * 9);
+ REQUIRE(mock->mDraws[3].y == 32 * 10);
+ REQUIRE(mock->mDraws[3].width == 64);
+ REQUIRE(mock->mDraws[3].height == 32);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[4].x == 32 * 11);
+ REQUIRE(mock->mDraws[4].y == 32 * 10);
+ REQUIRE(mock->mDraws[4].image == img3);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[5].x == 32 * 15);
+ REQUIRE(mock->mDraws[5].y == 32 * 10);
+ REQUIRE(mock->mDraws[5].width == 96);
+ REQUIRE(mock->mDraws[5].height == 32);
+ REQUIRE(mock->mDraws[5].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX, maxY,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 6);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 32 * 1 + 10);
+ REQUIRE(mock->mDraws[0].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[0].width == 96);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32 * 4 + 10);
+ REQUIRE(mock->mDraws[1].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[1].image == img2);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 6 + 10);
+ REQUIRE(mock->mDraws[2].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[3].x == 32 * 9 + 10);
+ REQUIRE(mock->mDraws[3].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[3].width == 64);
+ REQUIRE(mock->mDraws[3].height == 32);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[4].x == 32 * 11 + 10);
+ REQUIRE(mock->mDraws[4].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[4].image == img3);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[5].x == 32 * 15 + 10);
+ REQUIRE(mock->mDraws[5].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[5].width == 96);
+ REQUIRE(mock->mDraws[5].height == 32);
+ REQUIRE(mock->mDraws[5].image == img1);
+ }
+
+ SECTION("normal2")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ true,
+ 0,
+ 0);
+ TileInfo *const tiles = layer->getTiles();
+ map->addLayer(layer);
+ layer->setSpecialLayer(map->getSpecialLayer());
+ layer->setTempLayer(map->getTempLayer());
+ for (int x = 0; x < maxX; x ++)
+ {
+ for (int y = 0; y < maxY; y ++)
+ {
+ layer->setTile(x, y, img1);
+ tiles[y * maxX + x].isEnabled = false;
+ }
+ }
+ tiles[10 * maxX + 41].isEnabled = true;
+ layer->updateCache(maxX, maxY);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX, maxY,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32 * 41);
+ REQUIRE(mock->mDraws[0].y == 32 * 10);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX, maxY,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 1);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32 * 41 + 10);
+ REQUIRE(mock->mDraws[0].y == 32 * 10 - 20);
+ }
+
+ SECTION("normal 3")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ true,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ map->addLayer(layer);
+ SpecialLayer *const specialLayer = map->getSpecialLayer();
+ SpecialLayer *const tempLayer = map->getTempLayer();
+ layer->setSpecialLayer(specialLayer);
+ layer->setTempLayer(tempLayer);
+ specialLayer->setTile(1, 10, MapItemType::ARROW_UP);
+ specialLayer->setTile(10, 10, MapItemType::ARROW_DOWN);
+ specialLayer->updateCache();
+ layer->updateCache(maxX, maxY);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX, maxY,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 8);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 32 * 1);
+ REQUIRE(mock->mDraws[0].y == 32 * 10);
+ REQUIRE(mock->mDraws[0].width == 96);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32 * 1);
+ REQUIRE(mock->mDraws[1].y == 32 * 10);
+// REQUIRE(mock->mDraws[1].image == img2);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 4);
+ REQUIRE(mock->mDraws[2].y == 32 * 10);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[3].x == 32 * 6);
+ REQUIRE(mock->mDraws[3].y == 32 * 10);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[4].x == 32 * 9);
+ REQUIRE(mock->mDraws[4].y == 32 * 10);
+ REQUIRE(mock->mDraws[4].width == 64);
+ REQUIRE(mock->mDraws[4].height == 32);
+ REQUIRE(mock->mDraws[4].image == img2);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[5].x == 32 * 10);
+ REQUIRE(mock->mDraws[5].y == 32 * 10);
+// REQUIRE(mock->mDraws[5].image == img2);
+ REQUIRE(mock->mDraws[6].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[6].x == 32 * 11);
+ REQUIRE(mock->mDraws[6].y == 32 * 10);
+ REQUIRE(mock->mDraws[6].image == img3);
+ REQUIRE(mock->mDraws[7].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[7].x == 32 * 15);
+ REQUIRE(mock->mDraws[7].y == 32 * 10);
+ REQUIRE(mock->mDraws[7].width == 96);
+ REQUIRE(mock->mDraws[7].height == 32);
+ REQUIRE(mock->mDraws[7].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX, maxY,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 8);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[0].x == 32 * 1 + 10);
+ REQUIRE(mock->mDraws[0].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[0].width == 96);
+ REQUIRE(mock->mDraws[0].height == 32);
+ REQUIRE(mock->mDraws[0].image == img1);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[1].x == 32 * 1 + 10);
+ REQUIRE(mock->mDraws[1].y == 32 * 10 - 20);
+// REQUIRE(mock->mDraws[1].image == img2);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 4 + 10);
+ REQUIRE(mock->mDraws[2].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[3].x == 32 * 6 + 10);
+ REQUIRE(mock->mDraws[3].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[4].x == 32 * 9 + 10);
+ REQUIRE(mock->mDraws[4].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[4].width == 64);
+ REQUIRE(mock->mDraws[4].height == 32);
+ REQUIRE(mock->mDraws[4].image == img2);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[5].x == 32 * 10 + 10);
+ REQUIRE(mock->mDraws[5].y == 32 * 10 - 20);
+// REQUIRE(mock->mDraws[5].image == img2);
+ REQUIRE(mock->mDraws[6].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[6].x == 32 * 11 + 10);
+ REQUIRE(mock->mDraws[6].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[6].image == img3);
+ REQUIRE(mock->mDraws[7].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[7].x == 32 * 15 + 10);
+ REQUIRE(mock->mDraws[7].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[7].width == 96);
+ REQUIRE(mock->mDraws[7].height == 32);
+ REQUIRE(mock->mDraws[7].image == img1);
+ }
+
+ SECTION("normal 4")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ map = new Map("map",
+ maxX, maxY,
+ 32, 32);
+ layer = new MapLayer("test",
+ 0, 0,
+ maxX, maxY,
+ true,
+ 0,
+ 0);
+ layer->setTile(1, 10, img1);
+ layer->setTile(2, 10, img1);
+ layer->setTile(3, 10, img1);
+ layer->setTile(4, 10, img2);
+ layer->setTile(5, 10, nullptr);
+ layer->setTile(6, 10, img2);
+ layer->setTile(7, 10, nullptr);
+ layer->setTile(8, 10, nullptr);
+ layer->setTile(9, 10, img2);
+ layer->setTile(10, 10, img2);
+ layer->setTile(11, 10, img3);
+ layer->setTile(12, 10, nullptr);
+ layer->setTile(13, 10, nullptr);
+ layer->setTile(14, 10, nullptr);
+ layer->setTile(15, 10, img1);
+ layer->setTile(16, 10, img1);
+ layer->setTile(17, 10, img1);
+ map->addLayer(layer);
+ SpecialLayer *const specialLayer = map->getSpecialLayer();
+ SpecialLayer *const tempLayer = map->getTempLayer();
+ layer->setSpecialLayer(specialLayer);
+ layer->setTempLayer(tempLayer);
+ specialLayer->setTile(0, 10, MapItemType::ARROW_UP);
+ specialLayer->setTile(10, 10, MapItemType::ARROW_DOWN);
+ specialLayer->setTile(90, 10, MapItemType::ARROW_DOWN);
+ specialLayer->updateCache();
+ layer->updateCache(maxX, maxY);
+
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX - 20, maxY,
+ 0, 0,
+ actors);
+ REQUIRE(mock->mDraws.size() == 8);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32 * 0);
+ REQUIRE(mock->mDraws[0].y == 32 * 10);
+// REQUIRE(mock->mDraws[0].image == img2);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[1].x == 32 * 1);
+ REQUIRE(mock->mDraws[1].y == 32 * 10);
+ REQUIRE(mock->mDraws[1].width == 96);
+ REQUIRE(mock->mDraws[1].height == 32);
+ REQUIRE(mock->mDraws[1].image == img1);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 4);
+ REQUIRE(mock->mDraws[2].y == 32 * 10);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[3].x == 32 * 6);
+ REQUIRE(mock->mDraws[3].y == 32 * 10);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[4].x == 32 * 9);
+ REQUIRE(mock->mDraws[4].y == 32 * 10);
+ REQUIRE(mock->mDraws[4].width == 64);
+ REQUIRE(mock->mDraws[4].height == 32);
+ REQUIRE(mock->mDraws[4].image == img2);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[5].x == 32 * 10);
+ REQUIRE(mock->mDraws[5].y == 32 * 10);
+// REQUIRE(mock->mDraws[5].image == img2);
+ REQUIRE(mock->mDraws[6].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[6].x == 32 * 11);
+ REQUIRE(mock->mDraws[6].y == 32 * 10);
+ REQUIRE(mock->mDraws[6].image == img3);
+ REQUIRE(mock->mDraws[7].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[7].x == 32 * 15);
+ REQUIRE(mock->mDraws[7].y == 32 * 10);
+ REQUIRE(mock->mDraws[7].width == 96);
+ REQUIRE(mock->mDraws[7].height == 32);
+ REQUIRE(mock->mDraws[7].image == img1);
+
+ mock->mDraws.clear();
+ layer->drawFringe(mock,
+ 0, 0,
+ maxX - 20, maxY,
+ -10, 20,
+ actors);
+ REQUIRE(mock->mDraws.size() == 8);
+ REQUIRE(mock->mDraws[0].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[0].x == 32 * 0 + 10);
+ REQUIRE(mock->mDraws[0].y == 32 * 10 - 20);
+// REQUIRE(mock->mDraws[0].image == img2);
+ REQUIRE(mock->mDraws[1].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[1].x == 32 * 1 + 10);
+ REQUIRE(mock->mDraws[1].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[1].width == 96);
+ REQUIRE(mock->mDraws[1].height == 32);
+ REQUIRE(mock->mDraws[1].image == img1);
+ REQUIRE(mock->mDraws[2].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[2].x == 32 * 4 + 10);
+ REQUIRE(mock->mDraws[2].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[2].image == img2);
+ REQUIRE(mock->mDraws[3].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[3].x == 32 * 6 + 10);
+ REQUIRE(mock->mDraws[3].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[3].image == img2);
+ REQUIRE(mock->mDraws[4].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[4].x == 32 * 9 + 10);
+ REQUIRE(mock->mDraws[4].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[4].width == 64);
+ REQUIRE(mock->mDraws[4].height == 32);
+ REQUIRE(mock->mDraws[4].image == img2);
+ REQUIRE(mock->mDraws[5].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[5].x == 32 * 10 + 10);
+ REQUIRE(mock->mDraws[5].y == 32 * 10 - 20);
+// REQUIRE(mock->mDraws[5].image == img2);
+ REQUIRE(mock->mDraws[6].drawType == MockDrawType::DrawImage);
+ REQUIRE(mock->mDraws[6].x == 32 * 11 + 10);
+ REQUIRE(mock->mDraws[6].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[6].image == img3);
+ REQUIRE(mock->mDraws[7].drawType == MockDrawType::DrawPattern);
+ REQUIRE(mock->mDraws[7].x == 32 * 15 + 10);
+ REQUIRE(mock->mDraws[7].y == 32 * 10 - 20);
+ REQUIRE(mock->mDraws[7].width == 96);
+ REQUIRE(mock->mDraws[7].height == 32);
+ REQUIRE(mock->mDraws[7].image == img1);
+ }
+
+ delete2(localPlayer);
+ delete map;
+ delete img1;
+ delete img2;
+ delete img3;
+ delete mock;
+ delete2(theme);
+ GraphicsManager::deleteRenderers();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
diff --git a/src/unittests/resources/map/speciallayer_unittest.cc b/src/unittests/resources/map/speciallayer_unittest.cc
new file mode 100644
index 000000000..0461a98c4
--- /dev/null
+++ b/src/unittests/resources/map/speciallayer_unittest.cc
@@ -0,0 +1,291 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "logger.h"
+
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "enums/resources/map/mapitemtype.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/map/speciallayer.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "debug.h"
+
+TEST_CASE("SpecialLayer leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("SpecialLayer updateCache", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ logger = new Logger;
+ client = new Client;
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ SpecialLayer *layer = nullptr;
+
+ SECTION("simple 1")
+ {
+ layer = new SpecialLayer("test",
+ 1, 1);
+ const int *const cache = layer->getCache();
+ REQUIRE(cache[0] == 10000);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->updateCache();
+ REQUIRE(cache[0] == 10000);
+ }
+
+ SECTION("simple 2")
+ {
+ layer = new SpecialLayer("test",
+ 2, 1);
+ const int *const cache = layer->getCache();
+ REQUIRE(cache[0] == 10000);
+ REQUIRE(cache[1] == 10000);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->updateCache();
+ REQUIRE(cache[0] == 10000);
+ REQUIRE(cache[1] == 10000);
+ }
+
+ SECTION("simple 3")
+ {
+ layer = new SpecialLayer("test",
+ 2, 1);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->setTile(1, 0, MapItemType::ARROW_DOWN);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 0);
+ REQUIRE(cache[1] == 10000);
+ }
+
+ SECTION("simple 4")
+ {
+ layer = new SpecialLayer("test",
+ 2, 1);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->setTile(1, 0, MapItemType::ARROW_UP);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 0);
+ REQUIRE(cache[1] == 10000);
+ }
+
+ SECTION("simple 4.2")
+ {
+ layer = new SpecialLayer("test",
+ 3, 1);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->setTile(2, 0, MapItemType::ARROW_UP);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 1);
+ REQUIRE(cache[1] == 0);
+ REQUIRE(cache[2] == 10000);
+ }
+
+ SECTION("simple 5")
+ {
+ layer = new SpecialLayer("test",
+ 3, 1);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->setTile(1, 0, MapItemType::ARROW_UP);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 0);
+ REQUIRE(cache[1] == 10000);
+ REQUIRE(cache[2] == 10000);
+ }
+
+ SECTION("simple 6")
+ {
+ layer = new SpecialLayer("test",
+ 3, 1);
+ layer->setTile(0, 0, MapItemType::ARROW_UP);
+ layer->setTile(1, 0, MapItemType::ARROW_UP);
+ layer->setTile(2, 0, MapItemType::ARROW_DOWN);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 0);
+ REQUIRE(cache[1] == 0);
+ REQUIRE(cache[2] == 10000);
+ }
+
+ SECTION("simple 7")
+ {
+ layer = new SpecialLayer("test",
+ 3, 1);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 10000);
+ REQUIRE(cache[1] == 10000);
+ REQUIRE(cache[2] == 10000);
+ }
+
+ SECTION("simple 8")
+ {
+ layer = new SpecialLayer("test",
+ 3, 1);
+ layer->setTile(0, 0, MapItemType::EMPTY);
+ layer->setTile(1, 0, MapItemType::EMPTY);
+ layer->setTile(2, 0, MapItemType::EMPTY);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+ REQUIRE(cache[0] == 10000);
+ REQUIRE(cache[1] == 10000);
+ REQUIRE(cache[2] == 10000);
+ }
+
+ SECTION("simple 9")
+ {
+ layer = new SpecialLayer("test",
+ 2, 1);
+ const int *const cache = layer->getCache();
+ REQUIRE(cache[0] == 10000);
+ REQUIRE(cache[1] == 10000);
+ layer->setTile(1, 0, MapItemType::ARROW_UP);
+ layer->updateCache();
+ REQUIRE(cache[0] == 0);
+ REQUIRE(cache[1] == 10000);
+ }
+
+ SECTION("normal 1")
+ {
+ layer = new SpecialLayer("test",
+ 100, 100);
+ layer->setTile(1, 10, MapItemType::ARROW_UP);
+ layer->setTile(2, 10, MapItemType::ARROW_UP);
+ layer->setTile(3, 10, MapItemType::ARROW_UP);
+ layer->setTile(4, 10, MapItemType::ARROW_DOWN);
+ layer->setTile(5, 10, MapItemType::EMPTY);
+ layer->setTile(6, 10, MapItemType::ARROW_DOWN);
+ layer->setTile(7, 10, MapItemType::EMPTY);
+ layer->setTile(8, 10, MapItemType::EMPTY);
+ layer->setTile(9, 10, MapItemType::ARROW_DOWN);
+ layer->setTile(10, 10, MapItemType::ARROW_DOWN);
+ layer->setTile(11, 10, MapItemType::ARROW_LEFT);
+ layer->setTile(12, 10, MapItemType::EMPTY);
+ layer->setTile(13, 10, MapItemType::EMPTY);
+ layer->setTile(14, 10, MapItemType::EMPTY);
+ layer->setTile(15, 10, MapItemType::ARROW_UP);
+ layer->setTile(16, 10, MapItemType::ARROW_UP);
+ layer->setTile(17, 10, MapItemType::ARROW_UP);
+ const int *const cache = layer->getCache();
+ layer->updateCache();
+
+ REQUIRE(cache[10 * 100 + 0] == 0);
+ REQUIRE(cache[10 * 100 + 1] == 0);
+ REQUIRE(cache[10 * 100 + 2] == 0);
+ REQUIRE(cache[10 * 100 + 3] == 0);
+ REQUIRE(cache[10 * 100 + 4] == 1);
+ REQUIRE(cache[10 * 100 + 5] == 0);
+ REQUIRE(cache[10 * 100 + 6] == 2);
+ REQUIRE(cache[10 * 100 + 7] == 1);
+ REQUIRE(cache[10 * 100 + 8] == 0);
+ REQUIRE(cache[10 * 100 + 9] == 0);
+ REQUIRE(cache[10 * 100 + 10] == 0);
+ REQUIRE(cache[10 * 100 + 11] == 3);
+ REQUIRE(cache[10 * 100 + 12] == 2);
+ REQUIRE(cache[10 * 100 + 13] == 1);
+ REQUIRE(cache[10 * 100 + 14] == 0);
+ REQUIRE(cache[10 * 100 + 15] == 0);
+ REQUIRE(cache[10 * 100 + 16] == 0);
+ REQUIRE(cache[10 * 100 + 17] == 10000);
+ }
+
+ SECTION("normal2")
+ {
+ const int maxX = 100;
+ const int maxY = 100;
+ layer = new SpecialLayer("test",
+ maxX, maxY);
+ const int *const cache = layer->getCache();
+ for (int x = 0; x < maxX; x ++)
+ {
+ for (int y = 0; y < maxY; y ++)
+ {
+ layer->setTile(x, y, MapItemType::ARROW_UP);
+ REQUIRE(layer->getTiles()[x + y * maxX] != nullptr);
+ }
+ }
+ layer->updateCache();
+
+ for (int y = 0; y < maxY; y ++)
+ {
+ for (int x = 0; x < maxX - 1; x ++)
+ {
+ REQUIRE(cache[y * maxX + x] == 0);
+ }
+ REQUIRE(cache[y * maxX + maxX - 1] == 10000);
+ }
+ }
+
+ delete layer;
+ ResourceManager::cleanOrphans();
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+TEST_CASE("SpecialLayer leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/resources/mstack_unittest.cc b/src/unittests/resources/mstack_unittest.cc
new file mode 100644
index 000000000..1d2233803
--- /dev/null
+++ b/src/unittests/resources/mstack_unittest.cc
@@ -0,0 +1,165 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2015-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "gui/cliprect.h"
+
+#include "resources/mstack.h"
+
+#include "debug.h"
+
+TEST_CASE("mstack push 1", "")
+{
+ MStack<ClipRect> stack(10);
+ REQUIRE(-1 == (stack.mPointer - stack.mStack));
+ REQUIRE(0 == stack.mStack[0].xOffset);
+
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+ ClipRect &val2 = stack.top();
+ REQUIRE(0 == stack.mPointer - stack.mStack);
+ REQUIRE(10 == val2.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(0 == stack.mStack[1].xOffset);
+
+ val2.yOffset = 2;
+ REQUIRE(2 == val1.yOffset);
+}
+
+TEST_CASE("mstack push 2", "")
+{
+ MStack<ClipRect> stack(10);
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+ const ClipRect &val2 = stack.top();
+ REQUIRE(10 == val2.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+
+ val1.yOffset = 2;
+ REQUIRE(2 == val2.yOffset);
+ REQUIRE(2 == stack.mStack[0].yOffset);
+}
+
+TEST_CASE("mstack push 3", "")
+{
+ MStack<ClipRect> stack(10);
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+ ClipRect &val2 = stack.top();
+ REQUIRE(10 == val2.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+}
+
+TEST_CASE("mstack push 4", "")
+{
+ MStack<ClipRect> stack(10);
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+ REQUIRE(10 == val1.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(0 == stack.mStack[1].xOffset);
+ REQUIRE(0 == stack.mStack[2].xOffset);
+
+ ClipRect &val2 = stack.push();
+ val2.xOffset = 20;
+ REQUIRE(20 == val2.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(20 == stack.mStack[1].xOffset);
+ REQUIRE(0 == stack.mStack[2].xOffset);
+
+ ClipRect &val3 = stack.push();
+ val3.xOffset = 30;
+ REQUIRE(30 == val3.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(20 == stack.mStack[1].xOffset);
+ REQUIRE(30 == stack.mStack[2].xOffset);
+}
+
+TEST_CASE("mstack pop 1", "")
+{
+ MStack<ClipRect> stack(10);
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+ REQUIRE(10 == stack.mStack[0].xOffset);
+
+ stack.pop();
+ REQUIRE(-1 == stack.mPointer - stack.mStack);
+}
+
+TEST_CASE("mstack pop 2", "")
+{
+ MStack<ClipRect> stack(10);
+ ClipRect &val1 = stack.push();
+ REQUIRE(0 == stack.mPointer - stack.mStack);
+
+ val1.xOffset = 10;
+ REQUIRE(10 == stack.mStack[0].xOffset);
+
+ ClipRect &val2 = stack.push();
+ REQUIRE(1 == stack.mPointer - stack.mStack);
+
+ val2.xOffset = 20;
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(20 == stack.mStack[1].xOffset);
+
+ stack.pop();
+ REQUIRE(0 == stack.mPointer - stack.mStack);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(20 == stack.mStack[1].xOffset);
+
+ ClipRect &val3 = stack.top();
+ REQUIRE(0 == stack.mPointer - stack.mStack);
+ REQUIRE(10 == val1.xOffset);
+ REQUIRE(20 == val2.xOffset);
+ REQUIRE(10 == val3.xOffset);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(20 == stack.mStack[1].xOffset);
+ REQUIRE(0 == stack.mStack[2].xOffset);
+}
+
+TEST_CASE("mstack clear 1", "")
+{
+ MStack<ClipRect> stack(10);
+ REQUIRE(-1 == stack.mPointer - stack.mStack);
+ REQUIRE(0 == stack.mStack[0].xOffset);
+
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+
+ stack.clear();
+ REQUIRE(-1 == stack.mPointer - stack.mStack);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(0 == stack.mStack[1].xOffset);
+}
+
+TEST_CASE("mstack getpop 1", "")
+{
+ MStack<ClipRect> stack(10);
+ ClipRect &val1 = stack.push();
+ val1.xOffset = 10;
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(10 == val1.xOffset);
+
+ ClipRect &val2 = stack.getPop();
+ REQUIRE(-1 == stack.mPointer - stack.mStack);
+ REQUIRE(10 == stack.mStack[0].xOffset);
+ REQUIRE(10 == val2.xOffset);
+}
diff --git a/src/unittests/resources/resourcemanager/resourcemanager_unittest.cc b/src/unittests/resources/resourcemanager/resourcemanager_unittest.cc
new file mode 100644
index 000000000..90bc873ab
--- /dev/null
+++ b/src/unittests/resources/resourcemanager/resourcemanager_unittest.cc
@@ -0,0 +1,701 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "dirs.h"
+#include "logger.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "utils/env.h"
+#include "utils/delete2.h"
+
+#include <unistd.h>
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#ifndef USE_SDL2
+#include <SDL.h>
+#endif // USE_SDL2
+PRAGMA48(GCC diagnostic pop)
+
+#include "debug.h"
+
+namespace
+{
+ int testResouceCounter = 0;
+
+ class TestResource : public Resource
+ {
+ public:
+ TestResource() :
+ Resource()
+ {
+ testResouceCounter ++;
+ }
+
+ ~TestResource()
+ {
+ testResouceCounter --;
+ }
+ };
+
+ struct TestLoader final
+ {
+ std::string path;
+ static Resource *load(const void *const v)
+ {
+ BLOCK_START("TestLoader::load")
+ if (v == nullptr)
+ {
+ BLOCK_END("TestLoader::load")
+ return nullptr;
+ }
+
+ Resource *const res = new TestResource();
+ BLOCK_END("TestLoader::load")
+ return res;
+ }
+ };
+
+} // namespace
+
+TEST_CASE("resourcemanager leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("resourcemanager", "resourcemanager")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+// ConfigManager::initConfiguration();
+// getConfigDefaults2(config.getDefaultValues());
+
+ while (ResourceManager::cleanOrphans(true))
+ continue;
+
+ testResouceCounter = 0;
+ const size_t resSize = ResourceManager::getResources().size();
+
+ SECTION("resourcemanager get 0")
+ {
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ }
+
+ SECTION("resourcemanager get 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager get 2")
+ {
+ TestLoader rl = { "test1" };
+ Resource *const res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ res->mSource = "source 1";
+ REQUIRE(res->mSource == "source 1");
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ Resource *const res2 = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 2);
+ REQUIRE(res2->mRefCount == 2);
+ REQUIRE(res->mIdPath == res2->mIdPath);
+ REQUIRE(res2->mSource == "source 1");
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ res2->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager get 3")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->mSource = "source 1";
+ res->decRef();
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources()["test1"] == res);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager get 4")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->mSource = "source 1";
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources()["test1"] == res);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ Resource *const res2 = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res2->mRefCount == 1);
+ REQUIRE(res->mIdPath == res2->mIdPath);
+ REQUIRE(res2->mSource == "source 1");
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res2->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager get 5")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(ResourceManager::isInCache("test1") == true);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->mSource = "source 1";
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().size() == 1);
+ REQUIRE(ResourceManager::getOrphanedResources()["test1"] == res);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ sleep(33);
+ ResourceManager::cleanOrphans();
+ REQUIRE(ResourceManager::isInCache("test1") == false);
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ Resource *const res2 = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(ResourceManager::isInCache("test1") == true);
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res2->mRefCount == 1);
+ REQUIRE(res2->mSource.empty());
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res2->decRef();
+ REQUIRE(res2->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager get 6")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ res->mSource = "source 1";
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ Resource *const res2 = ResourceManager::get("test2",
+ TestLoader::load, &rl);
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 2);
+ REQUIRE(res2->mRefCount == 1);
+ REQUIRE(res2->mSource.empty());
+ REQUIRE(ResourceManager::getResources().size() == 2 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getResources()["test2"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ res2->decRef();
+ REQUIRE(res->mRefCount == 0);
+ REQUIRE(res2->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager getFromCache 1")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ Resource *const res2 = ResourceManager::getFromCache("test1");
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res2->mRefCount == 2);
+ REQUIRE(res == res2);
+ REQUIRE(res2->mSource.empty());
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager getFromCache 2")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ Resource *const res2 = ResourceManager::getFromCache("test1");
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res2->mRefCount == 1);
+ REQUIRE(res == res2);
+ REQUIRE(res2->mSource.empty());
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager getFromCache 3")
+ {
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ res->mSource = "source 1";
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ Resource *const res2 = ResourceManager::get("test2",
+ TestLoader::load, &rl);
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 2);
+ REQUIRE(res2->mRefCount == 1);
+ REQUIRE(res2->mSource.empty());
+ REQUIRE(ResourceManager::getResources().size() == 2 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getResources()["test2"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ Resource *const resC = ResourceManager::getFromCache("test1");
+ Resource *const res2C = ResourceManager::getFromCache("test2");
+ REQUIRE(resC != nullptr);
+ REQUIRE(res2C != nullptr);
+ REQUIRE(testResouceCounter == 2);
+ REQUIRE(res == resC);
+ REQUIRE(res2 == res2C);
+ REQUIRE(resC->mRefCount == 2);
+ REQUIRE(res2C->mRefCount == 2);
+ REQUIRE(ResourceManager::getResources().size() == 2 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == resC);
+ REQUIRE(ResourceManager::getResources()["test2"] == res2C);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ res->decRef();
+ res->decRef();
+ res2->decRef();
+ res2->decRef();
+ REQUIRE(res->mRefCount == 0);
+ REQUIRE(res2->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager addResource 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ Resource *res = new TestResource();
+ REQUIRE(testResouceCounter == 1);
+ ResourceManager::addResource("test1", res);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager isInCache 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ REQUIRE(ResourceManager::isInCache("test1") == false);
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(ResourceManager::isInCache("test1") == true);
+ REQUIRE(ResourceManager::isInCache("test2") == false);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager getTempResource 1")
+ {
+ TestLoader rl = { "test1" };
+ REQUIRE(ResourceManager::getTempResource("test1") == nullptr);
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(res != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ Resource *const res2 = ResourceManager::getTempResource("test1");
+ REQUIRE(ResourceManager::getTempResource("test2") == nullptr);
+ REQUIRE(res2 != nullptr);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res2->mRefCount == 1);
+ REQUIRE(res == res2);
+ REQUIRE(res2->mSource.empty());
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res2);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ REQUIRE(res->mRefCount == 0);
+ }
+
+ SECTION("resourcemanager moveToDeleted 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ ResourceManager::moveToDeleted(res);
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ }
+
+ SECTION("resourcemanager moveToDeleted 2")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ res->incRef();
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 2);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ ResourceManager::moveToDeleted(res);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().size() == 1);
+ res->decRef();
+ }
+
+ SECTION("resourcemanager moveToDeleted 3")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ res->decRef();
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().size() == 1);
+ REQUIRE(ResourceManager::getOrphanedResources()["test1"] == res);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ ResourceManager::moveToDeleted(res);
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ }
+
+ SECTION("resourcemanager decRefDelete 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+
+ ResourceManager::decRefDelete(res);
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ }
+
+ SECTION("resourcemanager cleanUp 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+
+ ResourceManager::cleanUp(res);
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().size() == 1);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ ResourceManager::getOrphanedResources().clear();
+ }
+
+ SECTION("resourcemanager cleanProtected 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->mProtected = true;
+ ResourceManager::cleanProtected();
+
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().size() == 1);
+ REQUIRE(ResourceManager::getOrphanedResources()["test1"] == res);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ res->decRef();
+ }
+
+ SECTION("resourcemanager clearDeleted 1")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ res->incRef();
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 2);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ ResourceManager::moveToDeleted(res);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().size() == 1);
+
+ ResourceManager::clearDeleted();
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().size() == 1);
+ res->decRef();
+ }
+
+ SECTION("resourcemanager clearDeleted 2")
+ {
+ REQUIRE(testResouceCounter == 0);
+ TestLoader rl = { "test1" };
+ Resource *res = ResourceManager::get("test1",
+ TestLoader::load, &rl);
+ res->incRef();
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res != nullptr);
+ REQUIRE(res->mRefCount == 2);
+ REQUIRE(ResourceManager::getResources().size() == 1 + resSize);
+ REQUIRE(ResourceManager::getResources()["test1"] == res);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ ResourceManager::moveToDeleted(res);
+ REQUIRE(testResouceCounter == 1);
+ REQUIRE(res->mRefCount == 1);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().size() == 1);
+
+ res->decRef();
+ ResourceManager::clearDeleted();
+ REQUIRE(testResouceCounter == 0);
+ REQUIRE(ResourceManager::getResources().size() == 0 + resSize);
+ REQUIRE(ResourceManager::getOrphanedResources().empty() == true);
+ REQUIRE(ResourceManager::getDeletedResources().empty() == true);
+ }
+
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("resourcemanager leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/resources/sdlimagehelper_unittest.cc b/src/unittests/resources/sdlimagehelper_unittest.cc
new file mode 100644
index 000000000..2a3aec45b
--- /dev/null
+++ b/src/unittests/resources/sdlimagehelper_unittest.cc
@@ -0,0 +1,541 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2014-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef USE_SDL2
+#include "localconsts.h"
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#include <SDL_endian.h>
+PRAGMA48(GCC diagnostic pop)
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "debug.h"
+
+static SDL_Surface *createSoftware32BitSurface(int width,
+ int height)
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ const int rmask = 0xff000000;
+ const int gmask = 0x00ff0000;
+ const int bmask = 0x0000ff00;
+ const int amask = 0x000000ff;
+#else // SDL_BYTEORDER == SDL_BIG_ENDIAN
+
+ const int rmask = 0x000000ff;
+ const int gmask = 0x0000ff00;
+ const int bmask = 0x00ff0000;
+ const int amask = 0xff000000;
+#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
+
+ return MSDL_CreateRGBSurface(SDL_SWSURFACE,
+ width, height, 32, rmask, gmask, bmask, amask);
+}
+
+TEST_CASE("sdlimagehelper combineSurface", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper;
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ SECTION("empty copy1")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ for (int f = 0; f < 2 * 2; f ++)
+ ptr1[f] = 0xff000000;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0xff000000;
+ ptr2[1] = 0x00ff0000;
+ ptr2[2] = 0x0000ff00;
+ ptr2[3] = 0x000000ff;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ // src image test
+ REQUIRE(ptr2[0] == 0xff000000);
+ REQUIRE(ptr2[1] == 0x00ff0000);
+ REQUIRE(ptr2[2] == 0x0000ff00);
+ REQUIRE(ptr2[3] == 0x000000ff);
+
+ REQUIRE(ptr1[0] == 0xff000000);
+ REQUIRE(ptr1[1] == 0xff000000);
+ REQUIRE(ptr1[2] == 0xff000000);
+ REQUIRE(ptr1[3] == 0xff000000);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("empty copy2")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ for (int f = 0; f < 2 * 2; f ++)
+ ptr1[f] = 0xff000000;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0xff112233;
+ ptr2[1] = 0xff003344;
+ ptr2[2] = 0xff330055;
+ ptr2[3] = 0xff445500;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0xff112233);
+ REQUIRE(ptr1[1] == 0xff003344);
+ REQUIRE(ptr1[2] == 0xff330055);
+ REQUIRE(ptr1[3] == 0xff445500);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("empty copy3")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ for (int f = 0; f < 2 * 2; f ++)
+ ptr1[f] = 0x00000000;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0xff112233;
+ ptr2[1] = 0xff003344;
+ ptr2[2] = 0xff330055;
+ ptr2[3] = 0xff445500;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0xff112233);
+ REQUIRE(ptr1[1] == 0xff003344);
+ REQUIRE(ptr1[2] == 0xff330055);
+ REQUIRE(ptr1[3] == 0xff445500);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("empty copy4")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ for (int f = 0; f < 2 * 2; f ++)
+ ptr1[f] = 0xff000000;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50112233;
+ ptr2[1] = 0x50003344;
+ ptr2[2] = 0x50330055;
+ ptr2[3] = 0x50445500;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0xff09121c);
+ REQUIRE(ptr1[1] == 0xff001c25);
+ REQUIRE(ptr1[2] == 0xff1c002f);
+ REQUIRE(ptr1[3] == 0xff252f00);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("empty copy5")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ for (int f = 0; f < 2 * 2; f ++)
+ ptr1[f] = 0x00000000;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50112233;
+ ptr2[1] = 0x50003344;
+ ptr2[2] = 0x50330055;
+ ptr2[3] = 0x50445500;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0x8e09121c);
+ REQUIRE(ptr1[1] == 0x8e001c25);
+ REQUIRE(ptr1[2] == 0x8e1c002f);
+ REQUIRE(ptr1[3] == 0x8e252f00);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("empty copy6")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ ptr1[0] = 0x50112233;
+ ptr1[1] = 0x50003344;
+ ptr1[2] = 0x50330055;
+ ptr1[3] = 0x50445500;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ for (int f = 0; f < 2 * 2; f ++)
+ ptr2[f] = 0x00000000;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0x50112233);
+ REQUIRE(ptr1[1] == 0x50003344);
+ REQUIRE(ptr1[2] == 0x50330055);
+ REQUIRE(ptr1[3] == 0x50445500);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("mix 1")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ ptr1[0] = 0x50112233;
+ ptr1[1] = 0x50003344;
+ ptr1[2] = 0x50330055;
+ ptr1[3] = 0x50445500;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50003344;
+ ptr2[1] = 0x50330055;
+ ptr2[2] = 0x50445500;
+ ptr2[3] = 0x50112233;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0xdf082b3c);
+ REQUIRE(ptr1[1] == 0xdf1d174d);
+ REQUIRE(ptr1[2] == 0xdf3d2f26);
+ REQUIRE(ptr1[3] == 0xdf29391c);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("mix 2")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ ptr1[0] = 0x10112233;
+ ptr1[1] = 0x20003344;
+ ptr1[2] = 0x30330055;
+ ptr1[3] = 0x40445500;
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50003344;
+ ptr2[1] = 0x60330055;
+ ptr2[2] = 0x70445500;
+ ptr2[3] = 0x80112233;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0x9f082b3c);
+ REQUIRE(ptr1[1] == 0xbd1f144e);
+ REQUIRE(ptr1[2] == 0xb93f391e);
+ REQUIRE(ptr1[3] == 0xf5213224);
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("part mix 1")
+ {
+// 11 11 00 00
+// 11 11 00 00
+// 00 00 00 00
+// 00 00 00 00
+
+ SDL_Surface *surface1 = createSoftware32BitSurface(4, 4);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+ ptr1[0] = 0x10112233;
+ ptr1[1] = 0x20003344;
+ ptr1[2] = 0x10203040;
+ ptr1[3] = 0x20304050;
+ ptr1[4] = 0x30330055;
+ ptr1[5] = 0x40445500;
+ ptr1[6] = 0x30405060;
+ ptr1[7] = 0x708090a0;
+
+ ptr1[8] = 0x8090a0b0;
+ ptr1[9] = 0x90a0b0c0;
+ ptr1[10] = 0xa0b0c0d0;
+ ptr1[11] = 0xb0c0d0e0;
+ ptr1[12] = 0xc0d0e0f0;
+ ptr1[13] = 0xd0e0f000;
+ ptr1[14] = 0xe0f00010;
+ ptr1[15] = 0xf0001020;
+
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50003344;
+ ptr2[1] = 0x60330055;
+ ptr2[2] = 0x70445500;
+ ptr2[3] = 0x80112233;
+
+ SDLImageHelper::combineSurface(surface2,
+ nullptr,
+ surface1,
+ nullptr);
+
+ REQUIRE(ptr1[0] == 0x9f082b3c);
+ REQUIRE(ptr1[1] == 0xbd1f144e);
+ REQUIRE(ptr1[2] == 0x10203040);
+ REQUIRE(ptr1[3] == 0x20304050);
+ REQUIRE(ptr1[4] == 0xb93f391e);
+ REQUIRE(ptr1[5] == 0xf5213224);
+ REQUIRE(ptr1[6] == 0x30405060);
+ REQUIRE(ptr1[7] == 0x708090a0);
+
+ REQUIRE(ptr1[8] == 0x8090a0b0);
+ REQUIRE(ptr1[9] == 0x90a0b0c0);
+ REQUIRE(ptr1[10] == 0xa0b0c0d0);
+ REQUIRE(ptr1[11] == 0xb0c0d0e0);
+ REQUIRE(ptr1[12] == 0xc0d0e0f0);
+ REQUIRE(ptr1[13] == 0xd0e0f000);
+ REQUIRE(ptr1[14] == 0xe0f00010);
+ REQUIRE(ptr1[15] == 0xf0001020);
+
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("part mix 2")
+ {
+// 00 00 00 00
+// 00 11 11 00
+// 00 11 11 00
+// 00 00 00 00
+
+ SDL_Surface *surface1 = createSoftware32BitSurface(4, 4);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+
+ ptr1[0] = 0x10203040;
+ ptr1[1] = 0x20304050;
+ ptr1[2] = 0x30405060;
+ ptr1[3] = 0x708090a0;
+ ptr1[4] = 0x8090a0b0;
+
+ ptr1[5] = 0x10112233; // +
+ ptr1[6] = 0x20003344; // +
+
+ ptr1[7] = 0x90a0b0c0;
+ ptr1[8] = 0xa0b0c0d0;
+
+ ptr1[9] = 0x30330055; // +
+ ptr1[10] = 0x40445500; // +
+
+ ptr1[11] = 0xb0c0d0e0;
+ ptr1[12] = 0xc0d0e0f0;
+ ptr1[13] = 0xd0e0f000;
+ ptr1[14] = 0xe0f00010;
+ ptr1[15] = 0xf0001020;
+
+ SDL_Surface *surface2 = createSoftware32BitSurface(2, 2);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50003344;
+ ptr2[1] = 0x60330055;
+ ptr2[2] = 0x70445500;
+ ptr2[3] = 0x80112233;
+
+ SDL_Rect rect1;
+ SDL_Rect rect2;
+ rect1.x = 1;
+ rect1.y = 1;
+ rect1.w = 2;
+ rect1.h = 2;
+ rect2.x = 0;
+ rect2.y = 0;
+ rect2.w = 2;
+ rect2.h = 2;
+ SDLImageHelper::combineSurface(surface2,
+ &rect2,
+ surface1,
+ &rect1);
+
+ REQUIRE(ptr1[0] == 0x10203040);
+ REQUIRE(ptr1[1] == 0x20304050);
+ REQUIRE(ptr1[2] == 0x30405060);
+ REQUIRE(ptr1[3] == 0x708090a0);
+ REQUIRE(ptr1[4] == 0x8090a0b0);
+
+ REQUIRE(ptr1[5] == 0x9f082b3c); // +
+ REQUIRE(ptr1[6] == 0xbd1f144e); // +
+
+ REQUIRE(ptr1[7] == 0x90a0b0c0);
+ REQUIRE(ptr1[8] == 0xa0b0c0d0);
+
+ REQUIRE(ptr1[9] == 0xb93f391e); // +
+ REQUIRE(ptr1[10] == 0xf5213224); // +
+
+ REQUIRE(ptr1[11] == 0xb0c0d0e0);
+ REQUIRE(ptr1[12] == 0xc0d0e0f0);
+ REQUIRE(ptr1[13] == 0xd0e0f000);
+ REQUIRE(ptr1[14] == 0xe0f00010);
+ REQUIRE(ptr1[15] == 0xf0001020);
+
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ SECTION("part mix 3")
+ {
+ SDL_Surface *surface1 = createSoftware32BitSurface(4, 4);
+ uint32_t *ptr1 = static_cast<uint32_t*>(surface1->pixels);
+
+ ptr1[0] = 0x10203040;
+ ptr1[1] = 0x20304050;
+ ptr1[2] = 0x30405060;
+ ptr1[3] = 0x708090a0;
+ ptr1[4] = 0x8090a0b0;
+ ptr1[5] = 0x10112233;
+ ptr1[6] = 0x20003344;
+ ptr1[7] = 0x90a0b0c0;
+ ptr1[8] = 0xa0b0c0d0;
+ ptr1[9] = 0x30330055;
+ ptr1[10] = 0x40445500;
+ ptr1[11] = 0xb0c0d0e0;
+ ptr1[12] = 0xc0d0e0f0;
+ ptr1[13] = 0xd0e0f000;
+ ptr1[14] = 0xe0f00010;
+ ptr1[15] = 0xf0001020;
+
+ SDL_Surface *surface2 = createSoftware32BitSurface(4, 4);
+ uint32_t *ptr2 = static_cast<uint32_t*>(surface2->pixels);
+
+ ptr2[0] = 0x50003344;
+ ptr2[1] = 0x60330055;
+ ptr2[2] = 0x70445500;
+ ptr2[3] = 0x80112233;
+ ptr2[4] = 0x90111111;
+ ptr2[5] = 0x90111111;
+ ptr2[6] = 0xff000000;
+ ptr2[7] = 0xff000000;
+ ptr2[8] = 0xff000000;
+ ptr2[9] = 0xff000000;
+ ptr2[10] = 0xff000000;
+ ptr2[11] = 0xff000000;
+ ptr2[12] = 0xff000000;
+ ptr2[13] = 0xff000000;
+ ptr2[14] = 0xff000000;
+ ptr2[15] = 0xff000000;
+
+ SDL_Rect rect1;
+ SDL_Rect rect2;
+ rect1.x = 1;
+ rect1.y = 1;
+ rect1.w = 2;
+ rect1.h = 2;
+ rect2.x = 0;
+ rect2.y = 0;
+ rect2.w = 2;
+ rect2.h = 2;
+ SDLImageHelper::combineSurface(surface2,
+ &rect2,
+ surface1,
+ &rect1);
+
+ REQUIRE(ptr1[0] == 0x10203040);
+ REQUIRE(ptr1[1] == 0x20304050);
+ REQUIRE(ptr1[2] == 0x30405060);
+ REQUIRE(ptr1[3] == 0x708090a0);
+ REQUIRE(ptr1[4] == 0x8090a0b0);
+ REQUIRE(ptr1[5] == 0x9f082b3c);
+ REQUIRE(ptr1[6] == 0xbd1f144e);
+ REQUIRE(ptr1[7] == 0x90a0b0c0);
+ REQUIRE(ptr1[8] == 0xa0b0c0d0);
+ REQUIRE(ptr1[9] == 0xbf1b0d23);
+ REQUIRE(ptr1[10] == 0xff1f230c);
+ REQUIRE(ptr1[11] == 0xb0c0d0e0);
+ REQUIRE(ptr1[12] == 0xc0d0e0f0);
+ REQUIRE(ptr1[13] == 0xd0e0f000);
+ REQUIRE(ptr1[14] == 0xe0f00010);
+ REQUIRE(ptr1[15] == 0xf0001020);
+
+ MSDL_FreeSurface(surface1);
+ MSDL_FreeSurface(surface2);
+ }
+
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+}
+
+#endif // SDL_BYTEORDER == SDL_LIL_ENDIAN
+#endif // USE_SDL2
diff --git a/src/unittests/resources/sprite/animatedsprite_unittest.cc b/src/unittests/resources/sprite/animatedsprite_unittest.cc
new file mode 100644
index 000000000..3e4a1826c
--- /dev/null
+++ b/src/unittests/resources/sprite/animatedsprite_unittest.cc
@@ -0,0 +1,220 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "configuration.h"
+#include "configmanager.h"
+#include "client.h"
+#include "dirs.h"
+#include "graphicsmanager.h"
+
+#include "const/resources/spriteaction.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/animation/animation.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "resources/sprite/animatedsprite.h"
+
+#include "utils/env.h"
+#include "utils/delete2.h"
+#include "utils/mrand.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#ifndef USE_SDL2
+#include <SDL.h>
+#endif // USE_SDL2
+PRAGMA48(GCC diagnostic pop)
+
+#include "debug.h"
+
+TEST_CASE("AnimatedSprite leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("AnimatedSprite tests", "animatedsprite")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ initRand();
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ theme = new Theme;
+ Theme::selectSkin();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+
+ SECTION("basic test 1")
+ {
+ AnimatedSprite *sprite = AnimatedSprite::load(
+ "graphics/sprites/error.xml", 0);
+ sprite->play(SpriteAction::DEFAULT);
+
+ REQUIRE_FALSE(sprite == nullptr);
+ REQUIRE_FALSE(sprite->getSprite() == nullptr);
+ REQUIRE_FALSE(sprite->getAnimation() == nullptr);
+ REQUIRE_FALSE(sprite->getFrame() == nullptr);
+ REQUIRE(0 == sprite->getFrameIndex());
+ REQUIRE(0 == sprite->getFrameTime());
+ REQUIRE(false == sprite->update(1));
+ REQUIRE(0 == sprite->getFrameTime());
+ REQUIRE(false == sprite->update(11));
+ REQUIRE(10 == sprite->getFrameTime());
+ REQUIRE(0 == sprite->getFrameIndex());
+ delete sprite;
+ logger->log("test4");
+ }
+
+ SECTION("basic test 2")
+ {
+ AnimatedSprite *sprite = AnimatedSprite::load(
+ "graphics/sprites/test.xml", 0);
+ sprite->play(SpriteAction::STAND);
+
+ REQUIRE(10 == const_cast<Animation*>(sprite->getAnimation())
+ ->getFrames().size());
+
+ REQUIRE_FALSE(nullptr == sprite);
+
+ REQUIRE(false == sprite->update(1));
+ REQUIRE(0 == sprite->getFrameTime());
+ REQUIRE(10 == sprite->getFrame()->delay);
+
+ REQUIRE(false == sprite->update(1 + 10));
+ REQUIRE(0 == sprite->getFrameIndex());
+ REQUIRE(10 == sprite->getFrameTime());
+
+ REQUIRE(true == sprite->update(1 + 10 + 5));
+ REQUIRE(1 == sprite->getFrameIndex());
+ REQUIRE(5 == sprite->getFrameTime());
+
+ REQUIRE(false == sprite->update(1 + 10 + 5));
+ REQUIRE(1 == sprite->getFrameIndex());
+ REQUIRE(5 == sprite->getFrameTime());
+
+ REQUIRE(false == sprite->update(1 + 10 + 20));
+ REQUIRE(1 == sprite->getFrameIndex());
+ REQUIRE(20 == sprite->getFrameTime());
+
+ REQUIRE(true == sprite->update(1 + 10 + 20 + 1));
+ REQUIRE(2 == sprite->getFrameIndex());
+ REQUIRE(1 == sprite->getFrameTime());
+
+ REQUIRE(false == sprite->update(1 + 10 + 20 + 10));
+ REQUIRE(2 == sprite->getFrameIndex());
+ REQUIRE(10 == sprite->getFrameTime());
+
+ REQUIRE(true == sprite->update(1 + 10 + 20 + 10 + 1));
+ REQUIRE(4 == sprite->getFrameIndex());
+ REQUIRE(1 == sprite->getFrameTime());
+
+ REQUIRE(false == sprite->update(1 + 10 + 20 + 10 + 25));
+ REQUIRE(4 == sprite->getFrameIndex());
+ REQUIRE(25 == sprite->getFrameTime());
+
+ REQUIRE(true == sprite->update(1 + 10 + 20 + 10 + 25 + 1));
+ REQUIRE(6 == sprite->getFrameIndex());
+ REQUIRE(1 == sprite->getFrameTime());
+
+ REQUIRE(true == sprite->update(1 + 10 + 20 + 10 + 25 + 10 + 1));
+ REQUIRE(8 == sprite->getFrameIndex());
+ REQUIRE(1 == sprite->getFrameTime());
+
+ REQUIRE(true == sprite->update(1 + 10 + 20 + 10 + 25 + 10 + 10 + 1));
+ REQUIRE(4 == sprite->getFrameIndex());
+ REQUIRE(1 == sprite->getFrameTime());
+ delete sprite;
+ }
+
+ SECTION("basic test 3")
+ {
+ AnimatedSprite *sprite2 = AnimatedSprite::load(
+ "graphics/sprites/test.xml", 0);
+ sprite2->play(SpriteAction::SIT);
+
+ REQUIRE(false == sprite2->update(1));
+ REQUIRE(2 == const_cast<Animation*>(sprite2->getAnimation())
+ ->getFrames().size());
+ REQUIRE(0 == sprite2->getFrameTime());
+ REQUIRE(85 == sprite2->getFrame()->delay);
+
+ REQUIRE(true == sprite2->update(1 + 10 + 20 + 10 + 25 + 10 + 10 + 1));
+ REQUIRE(1 == sprite2->getFrameIndex());
+ REQUIRE(1 == sprite2->getFrameTime());
+ delete sprite2;
+ }
+
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("AnimatedSprite leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/unittests.h b/src/unittests/unittests.h
new file mode 100644
index 000000000..13be1b9c0
--- /dev/null
+++ b/src/unittests/unittests.h
@@ -0,0 +1,52 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UNITTESTS_H
+#define UNITTESTS_H
+
+#include "localconsts.h"
+
+#ifdef UNITTESTS_CATCH
+#include "test/catch.hpp"
+#endif // UNITTESTS_CATCH
+
+#ifdef UNITTESTS_DOCTEST
+
+#ifdef __GNUC__
+#if GCC_VERSION >= 50000
+#define PRAGMA5(str) _Pragma(#str)
+#elif defined(__clang__)
+#define PRAGMA5(str) _Pragma(#str)
+#else // GCC_VERSION > 50000
+#define PRAGMA5(str)
+#endif // GCC_VERSION > 50000
+#endif // __GNUC__
+
+PRAGMA5(GCC diagnostic push)
+PRAGMA5(GCC diagnostic ignored "-Wsuggest-override")
+#include "test/doctest.h"
+PRAGMA5(GCC diagnostic pop)
+
+#undef TEST_CASE
+#define TEST_CASE(name, tags) DOCTEST_TEST_CASE(tags " " name)
+#define SECTION(name) DOCTEST_SUBCASE(name)
+#endif // UNITTESTS_DOCTEST
+
+#endif // UNITTESTS_H
diff --git a/src/unittests/utils/chatutils_unittest.cc b/src/unittests/utils/chatutils_unittest.cc
new file mode 100644
index 000000000..681d91d3e
--- /dev/null
+++ b/src/unittests/utils/chatutils_unittest.cc
@@ -0,0 +1,287 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "configmanager.h"
+#include "dirs.h"
+
+#include "actormanager.h"
+#include "graphicsmanager.h"
+#include "party.h"
+
+#include "being/localplayer.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "utils/chatutils.h"
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#ifndef USE_SDL2
+#include <SDL.h>
+#endif // USE_SDL2
+PRAGMA48(GCC diagnostic pop)
+
+#include "debug.h"
+
+TEST_CASE("chatutils leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("chatutils replaceVars", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ SDL_Init(SDL_INIT_VIDEO);
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ theme = new Theme;
+ Theme::selectSkin();
+ imageHelper = new SDLImageHelper();
+ mainGraphics = new SDLGraphics;
+
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+
+ ActorSprite::load();
+ localPlayer = new LocalPlayer(static_cast<BeingId>(1),
+ BeingTypeId_zero);
+ actorManager = new ActorManager;
+ std::string str;
+
+ SECTION("empty")
+ {
+ replaceVars(str);
+ REQUIRE(str.empty());
+
+ str = "test line";
+ replaceVars(str);
+ REQUIRE(str == "test line");
+
+ str = "test <PLAYER>";
+ replaceVars(str);
+ REQUIRE(str == "test ");
+
+ str = "test <MONSTER>";
+ replaceVars(str);
+ REQUIRE(str == "test ");
+
+ str = "test <PEOPLE>";
+ replaceVars(str);
+ REQUIRE(str == "test ");
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test ");
+
+ str = "test <SOMETHING>";
+ replaceVars(str);
+ REQUIRE(str == "test <SOMETHING>");
+ }
+
+ SECTION("player")
+ {
+ Being *player1 = Being::createBeing(static_cast<BeingId>(2),
+ ActorType::Player,
+ BeingTypeId_zero,
+ nullptr);
+ player1->setName("player1");
+ actorManager->mActors.insert(player1);
+
+ localPlayer->setTarget(player1);
+ str = "test <PLAYER>";
+ replaceVars(str);
+ REQUIRE(str == "test player1");
+ }
+
+ SECTION("monster")
+ {
+ Being *const monster = Being::createBeing(static_cast<BeingId>(3),
+ ActorType::Monster,
+ BeingTypeId_zero,
+ nullptr);
+ monster->setName("monster1");
+ actorManager->mActors.insert(monster);
+
+ localPlayer->setTarget(monster);
+ str = "test <MONSTER>";
+ replaceVars(str);
+ REQUIRE(str == "test monster1");
+ }
+
+ SECTION("people")
+ {
+ actorManager->mActors.insert(localPlayer);
+ str = "test <PEOPLE>";
+ replaceVars(str);
+ REQUIRE(str == "test ");
+
+ Being *const player1 = Being::createBeing(static_cast<BeingId>(2),
+ ActorType::Player,
+ BeingTypeId_zero,
+ nullptr);
+ player1->setName("player1");
+ actorManager->mActors.insert(player1);
+
+ str = "test <PEOPLE>";
+ replaceVars(str);
+ REQUIRE(str == "test player1");
+
+ Being *const player2 = Being::createBeing(static_cast<BeingId>(4),
+ ActorType::Player,
+ BeingTypeId_zero,
+ nullptr);
+ player2->setName("player2");
+ actorManager->mActors.insert(player2);
+
+ str = "test <PEOPLE>";
+ replaceVars(str);
+ const bool correct = str == "test player1,player2" ||
+ str == "test player2,player1";
+ REQUIRE(correct == true);
+ }
+
+ SECTION("party")
+ {
+ actorManager->mActors.insert(localPlayer);
+
+ Party *const party1 = Party::getParty(1);
+ localPlayer->setParty(party1);
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test ");
+
+ Being *const player1 = Being::createBeing(static_cast<BeingId>(2),
+ ActorType::Player,
+ BeingTypeId_zero,
+ nullptr);
+ player1->setName("player1");
+ actorManager->mActors.insert(player1);
+ player1->setParty(party1);
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test player1");
+
+ Being *const player2 = Being::createBeing(static_cast<BeingId>(4),
+ ActorType::Player,
+ BeingTypeId_zero,
+ nullptr);
+ player2->setName("player2");
+ actorManager->mActors.insert(player2);
+ player2->setParty(party1);
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test player1,player2");
+
+ Party *const party2 = Party::getParty(2);
+
+ Being *const player3 = Being::createBeing(static_cast<BeingId>(5),
+ ActorType::Player,
+ BeingTypeId_zero,
+ nullptr);
+ player3->setName("player3");
+ actorManager->mActors.insert(player3);
+ player3->setParty(party2);
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test player1,player2");
+
+ player3->setParty(party1);
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test player1,player2,player3");
+
+ player2->setParty(party2);
+
+ str = "test <PARTY>";
+ replaceVars(str);
+ REQUIRE(str == "test player1,player3");
+
+ Party::clearParties();
+ }
+
+ delete2(actorManager);
+ delete2(localPlayer);
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("chatutils textToMe", "")
+{
+ REQUIRE(textToMe("") == "**");
+ REQUIRE(textToMe("123") == "*123*");
+ REQUIRE(textToMe("*") == "***");
+ REQUIRE(textToMe("test line") == "*test line*");
+}
+
+TEST_CASE("chatutils leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/utils/checkutils_unittest.cc b/src/unittests/utils/checkutils_unittest.cc
new file mode 100644
index 000000000..c54dcf9fc
--- /dev/null
+++ b/src/unittests/utils/checkutils_unittest.cc
@@ -0,0 +1,179 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "utils/checkutils.h"
+#include "utils/delete2.h"
+
+#include "debug.h"
+
+namespace
+{
+ bool flag = false;
+} // namespace
+
+static void testReturnFalseV(const bool val)
+{
+ flag = false;
+ returnFalseVReal(val);
+ flag = true;
+}
+
+static void testReturnTrueV(const bool val)
+{
+ flag = false;
+ returnTrueVReal(val);
+ flag = true;
+}
+
+static int testReturnFalse(const bool val)
+{
+ returnFalseReal(0, val);
+ return 1;
+}
+
+static int testReturnTrue(const bool val)
+{
+ returnTrueReal(0, val);
+ return 1;
+}
+
+static int testReturnNullptr(void *val)
+{
+ returnNullptrReal(0, val);
+ return 1;
+}
+
+static void testReturnNullptrV(void *val)
+{
+ flag = false;
+ returnNullptrVReal(val);
+ flag = true;
+}
+
+static bool testFailAlways1()
+{
+ failAlways("test fail");
+ return false;
+}
+
+static bool testFailAlways2()
+{
+ reportAlways("test fail");
+ return false;
+}
+
+TEST_CASE("CheckUtils", "")
+{
+ logger = new Logger;
+
+ SECTION("reportFalse")
+ {
+ REQUIRE(reportFalseReal(false) == false);
+ REQUIRE(reportFalseReal(true) == true);
+ }
+
+ SECTION("reportTrue")
+ {
+ REQUIRE(reportTrueReal(false) == false);
+ REQUIRE(reportTrueReal(true) == true);
+ }
+
+ SECTION("reportAlways")
+ {
+ reportAlwaysReal("test report");
+ }
+
+ SECTION("failFalse")
+ {
+PRAGMA4(GCC diagnostic push)
+PRAGMA4(GCC diagnostic ignored "-Wunused-value")
+ REQUIRE_THROWS(failFalse(false));
+ REQUIRE(failFalse(true) == true);
+ REQUIRE_THROWS(reportFalse(false));
+ REQUIRE(reportFalse(true) == true);
+PRAGMA4(GCC diagnostic pop)
+ }
+
+ SECTION("failTrue")
+ {
+PRAGMA4(GCC diagnostic push)
+PRAGMA4(GCC diagnostic ignored "-Wunused-value")
+ REQUIRE(failTrue(false) == false);
+ REQUIRE_THROWS(failTrue(true));
+ REQUIRE(reportTrue(false) == false);
+ REQUIRE_THROWS(reportTrue(true));
+PRAGMA4(GCC diagnostic pop)
+ }
+
+ SECTION("failAlways")
+ {
+PRAGMA4(GCC diagnostic push)
+PRAGMA4(GCC diagnostic ignored "-Wunused-value")
+ REQUIRE_THROWS(testFailAlways1());
+ REQUIRE_THROWS(testFailAlways2());
+PRAGMA4(GCC diagnostic pop)
+ }
+
+ SECTION("returnFalseV")
+ {
+ testReturnFalseV(false);
+ REQUIRE(flag == false);
+ testReturnFalseV(true);
+ REQUIRE(flag == true);
+ }
+
+ SECTION("returnTrueV")
+ {
+ testReturnTrueV(false);
+ REQUIRE(flag == true);
+ testReturnTrueV(true);
+ REQUIRE(flag == false);
+ }
+
+ SECTION("returnFalse")
+ {
+ REQUIRE(testReturnFalse(false) == 0);
+ REQUIRE(testReturnFalse(true) == 1);
+ }
+
+ SECTION("returnTrue")
+ {
+ REQUIRE(testReturnTrue(false) == 1);
+ REQUIRE(testReturnTrue(true) == 0);
+ }
+
+ SECTION("returnNullptr")
+ {
+ REQUIRE(testReturnNullptr(nullptr) == 0);
+ REQUIRE(testReturnNullptr(reinterpret_cast<void*>(1)) == 1);
+ }
+
+ SECTION("returnNullptrV")
+ {
+ testReturnNullptrV(nullptr);
+ REQUIRE(flag == false);
+ testReturnNullptrV(reinterpret_cast<void*>(1));
+ REQUIRE(flag == true);
+ }
+
+ delete2(logger);
+}
diff --git a/src/unittests/utils/dumplibs_unittest.cc b/src/unittests/utils/dumplibs_unittest.cc
new file mode 100644
index 000000000..35b80c710
--- /dev/null
+++ b/src/unittests/utils/dumplibs_unittest.cc
@@ -0,0 +1,145 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "logger.h"
+
+#include "utils/delete2.h"
+#include "utils/stringutils.h"
+
+PRAGMA48(GCC diagnostic push)
+PRAGMA48(GCC diagnostic ignored "-Wshadow")
+#include <SDL_image.h>
+#include <SDL_mixer.h>
+PRAGMACLANG6GCC(GCC diagnostic push)
+PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast")
+#include <SDL_net.h>
+PRAGMACLANG6GCC(GCC diagnostic pop)
+#include <SDL_ttf.h>
+PRAGMA48(GCC diagnostic pop)
+
+#include <zlib.h>
+
+#include "debug.h"
+
+TEST_CASE("dumplibs tests", "")
+{
+ logger = new Logger();
+
+ SECTION("zlib")
+ {
+ const std::string build = ZLIB_VERSION;
+ const std::string link = zlibVersion();
+ REQUIRE(build == link);
+ }
+
+ SECTION("sdl")
+ {
+ const SDL_version *linkVersion = nullptr;
+#ifdef USE_SDL2
+ SDL_version sdlVersion;
+ sdlVersion.major = 0;
+ sdlVersion.minor = 0;
+ sdlVersion.patch = 0;
+ SDL_GetVersion(&sdlVersion);
+ linkVersion = &sdlVersion;
+#else // USE_SDL2
+ linkVersion = SDL_Linked_Version();
+#endif // USE_SDL2
+
+ const std::string build = strprintf("%d.%d.%d",
+ SDL_MAJOR_VERSION,
+ SDL_MINOR_VERSION,
+ SDL_PATCHLEVEL);
+ const std::string link = strprintf("%d.%d.%d",
+ linkVersion->major,
+ linkVersion->minor,
+ linkVersion->patch);
+
+ REQUIRE(build == link);
+ }
+
+ SECTION("sdl_net")
+ {
+ const SDL_version *const linkVersion = SDLNet_Linked_Version();
+
+ const std::string build = strprintf("%d.%d.%d",
+ SDL_NET_MAJOR_VERSION,
+ SDL_NET_MINOR_VERSION,
+ SDL_NET_PATCHLEVEL);
+ const std::string link = strprintf("%d.%d.%d",
+ linkVersion->major,
+ linkVersion->minor,
+ linkVersion->patch);
+
+ REQUIRE(build == link);
+ }
+
+ SECTION("sdl_image")
+ {
+ const SDL_version *const linkVersion = IMG_Linked_Version();
+
+ const std::string build = strprintf("%d.%d.%d",
+ SDL_IMAGE_MAJOR_VERSION,
+ SDL_IMAGE_MINOR_VERSION,
+ SDL_IMAGE_PATCHLEVEL);
+ const std::string link = strprintf("%d.%d.%d",
+ linkVersion->major,
+ linkVersion->minor,
+ linkVersion->patch);
+
+ REQUIRE(build == link);
+ }
+
+ SECTION("sdl_mixer")
+ {
+ const SDL_version *const linkVersion = Mix_Linked_Version();
+
+ const std::string build = strprintf("%d.%d.%d",
+ SDL_MIXER_MAJOR_VERSION,
+ SDL_MIXER_MINOR_VERSION,
+ SDL_MIXER_PATCHLEVEL);
+ const std::string link = strprintf("%d.%d.%d",
+ linkVersion->major,
+ linkVersion->minor,
+ linkVersion->patch);
+
+ REQUIRE(build == link);
+ }
+
+ SECTION("sdl_ttf")
+ {
+ const SDL_version *const linkVersion = TTF_Linked_Version();
+
+ const std::string build = strprintf("%d.%d.%d",
+ SDL_TTF_MAJOR_VERSION,
+ SDL_TTF_MINOR_VERSION,
+ SDL_TTF_PATCHLEVEL);
+ const std::string link = strprintf("%d.%d.%d",
+ linkVersion->major,
+ linkVersion->minor,
+ linkVersion->patch);
+
+ REQUIRE(build == link);
+ }
+
+ delete2(logger);
+}
diff --git a/src/unittests/utils/langs_unittest.cc b/src/unittests/utils/langs_unittest.cc
new file mode 100644
index 000000000..d9ff6eded
--- /dev/null
+++ b/src/unittests/utils/langs_unittest.cc
@@ -0,0 +1,115 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "configuration.h"
+
+#include "utils/env.h"
+#include "utils/langs.h"
+
+#include "debug.h"
+
+TEST_CASE("Langs getLang", "")
+{
+ LangVect langs;
+
+ config.setValue("lang", "C");
+ langs = getLang();
+ REQUIRE(langs.size() == 1);
+ REQUIRE(langs[0] == "C");
+
+ config.setValue("lang", "ru_RU");
+ langs = getLang();
+ REQUIRE(langs.size() == 2);
+ REQUIRE(langs[0] == "ru_RU");
+ REQUIRE(langs[1] == "ru");
+
+ config.setValue("lang", "ru_RU.UTF-8");
+ langs = getLang();
+ REQUIRE(langs.size() == 2);
+ REQUIRE(langs[0] == "ru_RU");
+ REQUIRE(langs[1] == "ru");
+
+ config.setValue("lang", "");
+
+ setEnv("LANG", "C");
+ langs = getLang();
+ REQUIRE(langs.size() == 1);
+ REQUIRE(langs[0] == "C");
+
+ setEnv("LANG", "ru_RU");
+ langs = getLang();
+ REQUIRE(langs.size() == 2);
+ REQUIRE(langs[0] == "ru_RU");
+ REQUIRE(langs[1] == "ru");
+
+ setEnv("LANG", "ru_RU.UTF-8");
+ langs = getLang();
+ REQUIRE(langs.size() == 2);
+ REQUIRE(langs[0] == "ru_RU");
+ REQUIRE(langs[1] == "ru");
+}
+
+TEST_CASE("Langs getLangSimple", "")
+{
+ config.setValue("lang", "C");
+ REQUIRE(getLangSimple() == "C");
+
+ config.setValue("lang", "ru_RU");
+ REQUIRE(getLangSimple() == "ru_RU");
+
+ config.setValue("lang", "ru_RU.UTF-8");
+ REQUIRE(getLangSimple() == "ru_RU.UTF-8");
+
+ config.setValue("lang", "");
+
+ setEnv("LANG", "C");
+ REQUIRE(getLangSimple() == "C");
+
+ setEnv("LANG", "ru_RU");
+ REQUIRE(getLangSimple() == "ru_RU");
+
+ setEnv("LANG", "ru_RU.UTF-8");
+ REQUIRE(getLangSimple() == "ru_RU.UTF-8");
+}
+
+TEST_CASE("Langs getLangShort", "")
+{
+ config.setValue("lang", "C");
+ REQUIRE(getLangShort() == "C");
+
+ config.setValue("lang", "ru_RU");
+ REQUIRE(getLangShort() == "ru");
+
+ config.setValue("lang", "ru_RU.UTF-8");
+ REQUIRE(getLangShort() == "ru");
+
+ config.setValue("lang", "");
+
+ setEnv("LANG", "C");
+ REQUIRE(getLangShort() == "C");
+
+ setEnv("LANG", "ru_RU");
+ REQUIRE(getLangShort() == "ru");
+
+ setEnv("LANG", "ru_RU.UTF-8");
+ REQUIRE(getLangShort() == "ru");
+}
diff --git a/src/unittests/utils/mathutils_unittest.cc b/src/unittests/utils/mathutils_unittest.cc
new file mode 100644
index 000000000..3eb0214ef
--- /dev/null
+++ b/src/unittests/utils/mathutils_unittest.cc
@@ -0,0 +1,102 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2013-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "utils/mathutils.h"
+
+#include "debug.h"
+
+TEST_CASE("MathUtils powerOfTwo", "")
+{
+ REQUIRE(powerOfTwo(0) == 1);
+ REQUIRE(powerOfTwo(1) == 1);
+ REQUIRE(powerOfTwo(2) == 2);
+ REQUIRE(powerOfTwo(3) == 4);
+ REQUIRE(powerOfTwo(4) == 4);
+ REQUIRE(powerOfTwo(5) == 8);
+ REQUIRE(powerOfTwo(6) == 8);
+ REQUIRE(powerOfTwo(7) == 8);
+ REQUIRE(powerOfTwo(8) == 8);
+ REQUIRE(powerOfTwo(9) == 16);
+ REQUIRE(powerOfTwo(10) == 16);
+ REQUIRE(powerOfTwo(11) == 16);
+ REQUIRE(powerOfTwo(12) == 16);
+ REQUIRE(powerOfTwo(13) == 16);
+ REQUIRE(powerOfTwo(14) == 16);
+ REQUIRE(powerOfTwo(15) == 16);
+ REQUIRE(powerOfTwo(16) == 16);
+ REQUIRE(powerOfTwo(17) == 32);
+ REQUIRE(powerOfTwo(18) == 32);
+ REQUIRE(powerOfTwo(19) == 32);
+ REQUIRE(powerOfTwo(20) == 32);
+ REQUIRE(powerOfTwo(21) == 32);
+ REQUIRE(powerOfTwo(22) == 32);
+ REQUIRE(powerOfTwo(23) == 32);
+ REQUIRE(powerOfTwo(24) == 32);
+ REQUIRE(powerOfTwo(25) == 32);
+ REQUIRE(powerOfTwo(26) == 32);
+ REQUIRE(powerOfTwo(27) == 32);
+ REQUIRE(powerOfTwo(28) == 32);
+ REQUIRE(powerOfTwo(29) == 32);
+ REQUIRE(powerOfTwo(30) == 32);
+ REQUIRE(powerOfTwo(31) == 32);
+ REQUIRE(powerOfTwo(32) == 32);
+ REQUIRE(powerOfTwo(33) == 64);
+ REQUIRE(powerOfTwo(34) == 64);
+ REQUIRE(powerOfTwo(35) == 64);
+ REQUIRE(powerOfTwo(36) == 64);
+ REQUIRE(powerOfTwo(37) == 64);
+ REQUIRE(powerOfTwo(38) == 64);
+ REQUIRE(powerOfTwo(39) == 64);
+ REQUIRE(powerOfTwo(41) == 64);
+ REQUIRE(powerOfTwo(42) == 64);
+ REQUIRE(powerOfTwo(43) == 64);
+ REQUIRE(powerOfTwo(44) == 64);
+ REQUIRE(powerOfTwo(45) == 64);
+ REQUIRE(powerOfTwo(46) == 64);
+ REQUIRE(powerOfTwo(47) == 64);
+ REQUIRE(powerOfTwo(48) == 64);
+ REQUIRE(powerOfTwo(49) == 64);
+ REQUIRE(powerOfTwo(50) == 64);
+ REQUIRE(powerOfTwo(51) == 64);
+ REQUIRE(powerOfTwo(52) == 64);
+ REQUIRE(powerOfTwo(53) == 64);
+ REQUIRE(powerOfTwo(54) == 64);
+ REQUIRE(powerOfTwo(55) == 64);
+ REQUIRE(powerOfTwo(56) == 64);
+ REQUIRE(powerOfTwo(57) == 64);
+ REQUIRE(powerOfTwo(58) == 64);
+ REQUIRE(powerOfTwo(59) == 64);
+ REQUIRE(powerOfTwo(60) == 64);
+ REQUIRE(powerOfTwo(61) == 64);
+ REQUIRE(powerOfTwo(62) == 64);
+ REQUIRE(powerOfTwo(63) == 64);
+ REQUIRE(powerOfTwo(64) == 64);
+ REQUIRE(powerOfTwo(65) == 128);
+
+ REQUIRE(powerOfTwo(1000000) == 1048576);
+}
+
+TEST_CASE("MathUtils tests fastSqrtInt", "")
+{
+ for (int f = 0; f < 1005; f ++)
+ REQUIRE(fastSqrtInt(f) == CAST_S32(sqrt(f)));
+}
diff --git a/src/unittests/utils/parameters_unittest.cc b/src/unittests/utils/parameters_unittest.cc
new file mode 100644
index 000000000..90d872d5a
--- /dev/null
+++ b/src/unittests/utils/parameters_unittest.cc
@@ -0,0 +1,327 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "utils/parameters.h"
+
+#include "debug.h"
+
+TEST_CASE("parameters basic 1", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "", ",", '\"') == true);
+ REQUIRE(pars.empty());
+}
+
+TEST_CASE("parameters basic 2", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "one,two, tree", ",", '\"') == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "one");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters basic 3", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, ", ,,,", ",", '\"') == true);
+ REQUIRE(pars.empty());
+}
+
+TEST_CASE("parameters basic 4", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "one,,two, tree", ",", '\"') == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "one");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters escape 1", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\\\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters escape 2", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\\\", test", ",", '\"') == true);
+ REQUIRE(pars.size() == 2);
+ REQUIRE(pars[0] == "\"");
+ REQUIRE(pars[1] == "test");
+}
+
+TEST_CASE("parameters escape 3", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "test,\\\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 2);
+ REQUIRE(pars[0] == "test");
+ REQUIRE(pars[1] == "\"");
+}
+
+TEST_CASE("parameters quote 1", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\",,two, tree", ",", '\"') == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "one");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 2", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"\",,two, tree", ",", '\"') == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0].empty());
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 3", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one test\",,two, tree", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "one test");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 4", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"\\\"one test\\\"\",,two, tree", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "\"one test\"");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 5", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"\\\"one \\\"test\\\"\",,two, tree",
+ ",", '\"') == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "\"one \"test\"");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 6", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one, test\",,two, tree", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "one, test");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 7", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"\\\"one, test\\\"\",,two, tree",
+ ",", '\"') == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "\"one, test\"");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 8", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"\\\"\",,two, tree", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 3);
+ REQUIRE(pars[0] == "\"");
+ REQUIRE(pars[1] == "two");
+ REQUIRE(pars[2] == "tree");
+}
+
+TEST_CASE("parameters quote 9", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"\\\",,two, tree", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"\",,two, tree");
+}
+
+TEST_CASE("parameters quote 10", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters quote 11", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\\\"", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters quote 12", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, ",\"", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters quote 13", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\",", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\",");
+}
+
+TEST_CASE("parameters quote 14", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\\\",", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters quote 15", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, ",\\\"", ",", '\"')
+ == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters quote 16", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one test");
+}
+
+TEST_CASE("parameters quote 17", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one, test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one, test");
+}
+
+TEST_CASE("parameters quote 18", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\\\" test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one\" test");
+}
+
+TEST_CASE("parameters quote 19", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\\\" ,test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one\" ,test");
+}
+
+TEST_CASE("parameters quote 20", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\\\" test,\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one\" test,");
+}
+
+TEST_CASE("parameters complex 1", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"test\" \"line\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "test\" \"line");
+}
+
+TEST_CASE("parameters complex 2", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"test\", \"line\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 2);
+ REQUIRE(pars[0] == "test");
+ REQUIRE(pars[1] == "line");
+}
+
+TEST_CASE("parameters complex 3", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"test,\" \"line\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "test,\" \"line");
+}
+
+TEST_CASE("parameters broken 1", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters broken 2", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, ",", ",", '\"') == true);
+ REQUIRE(pars.empty());
+}
+
+TEST_CASE("parameters broken 3", "")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars,
+ ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,", ",", '\"') == true);
+ REQUIRE(pars.empty());
+}
diff --git a/src/unittests/utils/stringutils_unittest.cc b/src/unittests/utils/stringutils_unittest.cc
new file mode 100644
index 000000000..b137ef30d
--- /dev/null
+++ b/src/unittests/utils/stringutils_unittest.cc
@@ -0,0 +1,1724 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "configuration.h"
+#include "logger.h"
+
+#include "const/utils/utf8.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "utils/delete2.h"
+#include "utils/dtor.h"
+
+#include "resources/iteminfo.h"
+
+#include "resources/db/itemdb.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "debug.h"
+
+TEST_CASE("stringuntils trim 1", "")
+{
+ std::string str = "str";
+ REQUIRE("str" == trim(str));
+
+ str = " str";
+ REQUIRE("str" == trim(str));
+ REQUIRE("str" == trim(str));
+
+ str = " str this IS Long Стринг "
+ "~!@#$%^&*()_+`-=[]\\{}|;':\",./<>? ";
+ REQUIRE("str this IS Long Стринг ~!@#$%^&*()_+`-=[]\\{}|;':\",./<>?" ==
+ trim(str));
+
+ str = "";
+ REQUIRE(trim(str).empty());
+}
+
+TEST_CASE("stringuntils toLower 1", "")
+{
+ std::string str = "str";
+ REQUIRE("str" == toLower(str));
+
+ str = " StR";
+ REQUIRE(" str" == toLower(str));
+
+ str = " str this IS Long "
+ "~!@#$%^&*()_+`-=[]\\{}|;':\",./<>? ";
+
+ REQUIRE(" str this is long ~!@#$%^&*()_+`-=[]\\{}|;':\",./<>? " ==
+ toLower(str));
+
+ str = "";
+ REQUIRE(toLower(str).empty());
+}
+
+TEST_CASE("stringuntils toUpper 1", "")
+{
+ std::string str = "str";
+ REQUIRE("STR" == toUpper(str));
+
+ str = " StR";
+ REQUIRE(" STR" == toUpper(str));
+
+ str = " str this IS Long "
+ "~!@#$%^&*()_+`-=[]\\{}|;':,./<>? ";
+
+ REQUIRE(" STR THIS IS LONG ~!@#$%^&*()_+`-=[]\\{}|;':,./<>? " ==
+ toUpper(str));
+
+ str = "";
+ REQUIRE(toUpper(str).empty());
+}
+
+TEST_CASE("stringuntils atox 1", "")
+{
+ std::string str = "0x10";
+ REQUIRE(16 == atox(str));
+
+ str = "0x0";
+ REQUIRE(0 == atox(str));
+
+ str = "0x1";
+ REQUIRE(1 == atox(str));
+
+ str = "0x0x0x0x0x0x0x0";
+ REQUIRE(0 == atox(str));
+
+ str = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const int k = atox(str);
+ printf("%d\n", k); // for avoid warning
+
+ str = "";
+ REQUIRE(0 == atox(str));
+
+ str = "0";
+ REQUIRE(0 == atox(str));
+
+ str = "0x";
+ REQUIRE(0 == atox(str));
+
+ str = "zzz";
+ REQUIRE(0 == atox(str));
+}
+
+TEST_CASE("stringuntils ipToString 1", "")
+{
+ REQUIRE("0.0.0.0" == std::string(ipToString(0)));
+ REQUIRE("219.255.210.73" == std::string(ipToString(1238564827)));
+}
+
+TEST_CASE("stringuntils toString 1", "")
+{
+ REQUIRE(strprintf("%d", 0) == toString(0));
+ REQUIRE(strprintf("%d", -1) == toString(-1));
+ REQUIRE(strprintf("%d", 30000000) == toString(30000000));
+ REQUIRE(strprintf("%d", -10000000) == toString(-10000000));
+ REQUIRE(strprintf("%d", 30000000) == toString(
+ static_cast<signed int>(30000000)));
+ REQUIRE(strprintf("%d", 3000) == toString(CAST_U16(3000)));
+ REQUIRE(strprintf("%d", 123) == toString(CAST_U8(123)));
+ REQUIRE(strprintf("%u", static_cast<uint32_t>(30000000)) == toString(
+ static_cast<uint32_t>(30000000)));
+ REQUIRE(strprintf("%f", 3.1f) == toString(3.1f));
+ REQUIRE(strprintf("%f", 3.1) == toString(3.1));
+}
+
+TEST_CASE("stringuntils toStringPrint 1", "")
+{
+ REQUIRE(toStringPrint(0) == "0 0x0");
+ REQUIRE(toStringPrint(10) == "10 0xa");
+ REQUIRE(toStringPrint(255) == "255 0xff");
+}
+
+TEST_CASE("stringuntils parse2Int 1", "")
+{
+ int a = -1;
+ int b = -1;
+
+ REQUIRE(parse2Int("", a, b) == false);
+ REQUIRE(a == -1);
+ REQUIRE(b == -1);
+
+ a = -1;
+ b = -1;
+ REQUIRE(parse2Int(",", a, b) == false);
+ REQUIRE(a == -1);
+ REQUIRE(b == -1);
+
+ a = -1;
+ b = -1;
+ REQUIRE(parse2Int("10,20", a, b) == true);
+ REQUIRE(a == 10);
+ REQUIRE(b == 20);
+
+ a = -1;
+ b = -1;
+ REQUIRE(parse2Int("10 20", a, b) == true);
+ REQUIRE(a == 10);
+ REQUIRE(b == 20);
+
+ a = -1;
+ b = -1;
+ REQUIRE(parse2Int("10 z20", a, b) == true);
+ REQUIRE(a == 10);
+ REQUIRE(b == 0);
+}
+
+TEST_CASE("stringuntils parse2Str 1", "")
+{
+ std::string str1 = "-";
+ std::string str2 = "-";
+
+ REQUIRE(parse2Str("", str1, str2) == false);
+ REQUIRE(str1 == "-");
+ REQUIRE(str2 == "-");
+
+ REQUIRE(parse2Str(",", str1, str2) == false);
+ REQUIRE(str1 == "-");
+ REQUIRE(str2 == "-");
+
+ str1 = "-";
+ str2 = "-";
+ REQUIRE(parse2Str("test line", str1, str2) == true);
+ REQUIRE(str1 == "test");
+ REQUIRE(str2 == "line");
+
+ str1 = "-";
+ str2 = "-";
+ REQUIRE(parse2Str("test,line", str1, str2) == true);
+ REQUIRE(str1 == "test");
+ REQUIRE(str2 == "line");
+}
+
+TEST_CASE("stringuntils parseNumber 1", "")
+{
+ REQUIRE(parseNumber("") == 0);
+ REQUIRE(parseNumber("0x") == 0);
+ REQUIRE(parseNumber("10") == 10);
+ REQUIRE(parseNumber("h10") == 16);
+ REQUIRE(parseNumber("x100") == 256);
+ REQUIRE(parseNumber("0x20") == 32);
+}
+
+TEST_CASE("stringuntils removeToken 1", "")
+{
+ std::string str;
+
+ REQUIRE(removeToken(str, " ").empty());
+ REQUIRE(str.empty());
+
+ str = "test";
+ REQUIRE(removeToken(str, " ").empty());
+ REQUIRE(str.empty());
+
+ str = "test line";
+ REQUIRE(removeToken(str, " ") == "line");
+ REQUIRE(str == "line");
+
+ str = "test,line";
+ REQUIRE(removeToken(str, ",") == "line");
+ REQUIRE(str == "line");
+
+ str = "test line";
+ REQUIRE(removeToken(str, ",").empty());
+ REQUIRE(str.empty());
+
+ str = ",line";
+ REQUIRE(removeToken(str, ",").empty());
+ REQUIRE(str.empty());
+}
+
+TEST_CASE("stringuntils strprintf 1", "")
+{
+ REQUIRE(strprintf("%s very long string. 123456789012345678901234567890"
+ "+++++++++++++++++++++++++++++++++++++++"
+ "________________________________"
+ "***********************************"
+ "----------------------------------------"
+ "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| %s",
+ "test", "end of test") ==
+ "test very long string. 123456789012345678901234567890"
+ "+++++++++++++++++++++++++++++++++++++++"
+ "________________________________"
+ "***********************************"
+ "----------------------------------------"
+ "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| "
+ "end of test");
+}
+
+TEST_CASE("stringuntils toString 2", "")
+{
+ for (int f = 0; f < 10000000; f += 123)
+ {
+ REQUIRE(strprintf("%d", f) == toString(f));
+ }
+}
+
+TEST_CASE("stringuntils removeColors 1", "")
+{
+ REQUIRE(removeColors("").empty());
+ REQUIRE("#" == removeColors("#"));
+ REQUIRE("##" == removeColors("##"));
+ REQUIRE(removeColors("##1").empty());
+ REQUIRE("2" == removeColors("##12"));
+ REQUIRE("1##" == removeColors("1##"));
+ REQUIRE("1" == removeColors("1##2"));
+ REQUIRE("13" == removeColors("1##23"));
+ REQUIRE("#1#2" == removeColors("#1#2"));
+ REQUIRE("#1" == removeColors("#1##2"));
+}
+
+TEST_CASE("stringuntils compareStrI 1", "")
+{
+ std::string str1;
+ std::string str2;
+ REQUIRE(0 == compareStrI(str1, str2));
+
+ str1 = "test";
+ str2 = "test";
+ REQUIRE(0 == compareStrI(str1, str2));
+
+ str1 = "test";
+ str2 = "test1";
+ REQUIRE(0 > compareStrI(str1, str2));
+
+ str1 = "test";
+ str2 = "aest1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ REQUIRE(0 < compareStrI(str1, str2));
+
+ str1 = "testaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ str2 = "testaa";
+ REQUIRE(0 < compareStrI(str1, str2));
+}
+
+TEST_CASE("stringuntils isWordSeparator 1", "")
+{
+ REQUIRE(isWordSeparator(' '));
+ REQUIRE(isWordSeparator(','));
+ REQUIRE(isWordSeparator('.'));
+ REQUIRE(isWordSeparator('\"'));
+ REQUIRE(!isWordSeparator(0));
+ REQUIRE(!isWordSeparator('a'));
+ REQUIRE(!isWordSeparator('-'));
+}
+
+TEST_CASE("stringuntils findSameSubstring", "")
+{
+ std::string str1;
+ std::string str2;
+
+ REQUIRE(findSameSubstring("", "").empty());
+
+ str1 = "test line";
+ str2 = "test line";
+ REQUIRE("test line" == findSameSubstring(str1, str2));
+
+ str1 = "test li";
+ str2 = "test line";
+ REQUIRE("test li" == findSameSubstring(str1, str2));
+
+ str1 = "test li";
+ str2 = "est li";
+ REQUIRE(findSameSubstring(str1, str2).empty());
+}
+
+TEST_CASE("stringuntils findSameSubstringI", "")
+{
+ std::string str1;
+ std::string str2;
+
+ REQUIRE(findSameSubstringI("", "").empty());
+
+ str1 = "tEst line";
+ str2 = "tesT line";
+ REQUIRE("tEst line" == findSameSubstringI(str1, str2));
+
+ str1 = "test Li";
+ str2 = "test lINe";
+ REQUIRE("test Li" == findSameSubstringI(str1, str2));
+
+ str1 = "test lINe";
+ str2 = "test Li";
+ REQUIRE("test lI" == findSameSubstringI(str1, str2));
+
+ str1 = "teSt li";
+ str2 = "est li";
+ REQUIRE(findSameSubstringI(str1, str2).empty());
+}
+
+TEST_CASE("stringuntils findI 1", "")
+{
+ REQUIRE(0 == findI("", ""));
+ REQUIRE(std::string::npos == findI("test", "line"));
+ REQUIRE(0 == findI("test line", "t"));
+ REQUIRE(0 == findI("test line", "te"));
+ REQUIRE(3 == findI("test line", "t l"));
+}
+
+TEST_CASE("stringuntils findI 2", "")
+{
+ std::vector <std::string> vect1;
+ vect1.push_back("test");
+ vect1.push_back("line");
+ vect1.push_back("qwe");
+
+ REQUIRE(std::string::npos == findI("", vect1));
+ REQUIRE(0 == findI("test", vect1));
+ REQUIRE(0 == findI("tesT lIne", vect1));
+ REQUIRE(5 == findI("teoT line", vect1));
+ REQUIRE(std::string::npos == findI("zzz", vect1));
+}
+
+TEST_CASE("stringuntils encodeStr 1", "")
+{
+ std::string str = encodeStr(10, 1);
+ REQUIRE(10 == decodeStr(str));
+
+ str.clear();
+ REQUIRE(0 == decodeStr(str));
+
+ str = encodeStr(10, 2);
+ REQUIRE(10 == decodeStr(str));
+
+ str = encodeStr(100, 3);
+ REQUIRE(100 == decodeStr(str));
+
+ str = encodeStr(1000, 4);
+ REQUIRE(1000 == decodeStr(str));
+}
+
+TEST_CASE("stringuntils extractNameFromSprite 1", "")
+{
+ REQUIRE(extractNameFromSprite("").empty());
+ REQUIRE("test" == extractNameFromSprite("test"));
+ REQUIRE("test" == extractNameFromSprite("test.qwe"));
+ REQUIRE("line" == extractNameFromSprite("test/line.zzz"));
+ REQUIRE("line" == extractNameFromSprite("test\\line.zzz"));
+ REQUIRE("line" == extractNameFromSprite("test/test2\\line.zzz"));
+ REQUIRE("line" == extractNameFromSprite("test\\test2/line.zzz"));
+}
+
+TEST_CASE("stringuntils removeSpriteIndex 1", "")
+{
+ REQUIRE(removeSpriteIndex("").empty());
+ REQUIRE("test" == removeSpriteIndex("test"));
+ REQUIRE("test" == removeSpriteIndex("test[1]"));
+ REQUIRE("line" == removeSpriteIndex("test/line[12]"));
+ REQUIRE("line" == removeSpriteIndex("test\\line[12]"));
+ REQUIRE("line" == removeSpriteIndex("test/test2\\line[12]"));
+ REQUIRE("line" == removeSpriteIndex("test\\test2/line[1]"));
+}
+
+TEST_CASE("stringutils getSafeUtf8String 1", "")
+{
+ const char *str;
+ str = getSafeUtf8String("");
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp("", str) == 0);
+ REQUIRE(str[0] == '\0');
+ REQUIRE(str[UTF8_MAX_SIZE - 1] == '\0');
+ delete [] str;
+
+ str = getSafeUtf8String("test line");
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp("test line", str) == 0);
+ REQUIRE(str[strlen("test line")] == '\0');
+ REQUIRE(str[UTF8_MAX_SIZE - 1] == '\0');
+ delete [] str;
+
+ str = getSafeUtf8String("1");
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp("1", str) == 0);
+ REQUIRE(str[1] == '\0');
+ REQUIRE(str[UTF8_MAX_SIZE - 1] == '\0');
+ delete [] str;
+}
+
+TEST_CASE("stringutils getSafeUtf8String 2", "")
+{
+ char *str;
+
+ getSafeUtf8String("test", nullptr);
+
+ str = new char[65535];
+ getSafeUtf8String("", str);
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp("", str) == 0);
+ REQUIRE(str[0] == '\0');
+ REQUIRE(str[UTF8_MAX_SIZE - 1] == '\0');
+ delete [] str;
+
+ str = new char[65535];
+ getSafeUtf8String("test line", str);
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp("test line", str) == 0);
+ REQUIRE(str[strlen("test line")] == '\0');
+ REQUIRE(str[UTF8_MAX_SIZE - 1] == '\0');
+ delete [] str;
+
+ str = new char[65535];
+ getSafeUtf8String("1", str);
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp("1", str) == 0);
+ REQUIRE(str[1] == '\0');
+ REQUIRE(str[UTF8_MAX_SIZE - 1] == '\0');
+ delete [] str;
+
+ str = new char[65535];
+ char *data1 = new char[65510];
+ memset(data1, 'a', 65510);
+ data1[65509] = '\0';
+ char *data2 = new char[65510];
+ memset(data2, 'a', 65500);
+ data2[65500] = '\0';
+ getSafeUtf8String(data1, str);
+ REQUIRE(str != nullptr);
+ REQUIRE(strcmp(data2, str) == 0);
+ REQUIRE(str[65500] == '\0');
+ delete [] data1;
+ delete [] data2;
+ delete [] str;
+}
+
+TEST_CASE("stringuntils getFileName 1", "")
+{
+ REQUIRE(getFileName("").empty());
+ REQUIRE("file" == getFileName("file"));
+ REQUIRE("file" == getFileName("test/file1\\file"));
+ REQUIRE("file" == getFileName("test\\file1/file"));
+ REQUIRE(getFileName("file/").empty());
+ REQUIRE("file" == getFileName("/file"));
+}
+
+TEST_CASE("stringuntils getFileDir 1", "")
+{
+ REQUIRE(getFileDir("").empty());
+ REQUIRE("file" == getFileDir("file"));
+ REQUIRE("test/file1" == getFileDir("test/file1\\file"));
+ REQUIRE("test\\file1" == getFileDir("test\\file1/file"));
+ REQUIRE("file" == getFileDir("file/"));
+ REQUIRE(getFileDir("/file").empty());
+}
+
+TEST_CASE("stringuntils replaceAll 1", "")
+{
+ std::string str1;
+ std::string str2;
+ std::string str3;
+
+ REQUIRE(replaceAll(str1, str2, str3).empty());
+
+ str1 = "this is test line";
+ str2 = "";
+ str3 = "";
+ REQUIRE("this is test line" == replaceAll(str1, str2, str3));
+
+ str1 = "this is test line";
+ str2 = "is ";
+ str3 = "";
+ REQUIRE("thtest line" == replaceAll(str1, str2, str3));
+
+ str1 = "this is test line";
+ str2 = "";
+ str3 = "1";
+ REQUIRE("this is test line" == replaceAll(str1, str2, str3));
+}
+
+TEST_CASE("stringuntils replaceRecursiveAll 1", "")
+{
+ std::string str;
+ str = "";
+ replaceRecursiveAll(str, "line", '.');
+ REQUIRE(str.empty());
+ str = "test line";
+ replaceRecursiveAll(str, "line", '.');
+ REQUIRE(str == "test .");
+ str = "11112222";
+ replaceRecursiveAll(str, "11", '1');
+ REQUIRE(str == "12222");
+ str = "122221";
+ replaceRecursiveAll(str, "11", '1');
+ REQUIRE(str == "122221");
+ str = "1222211";
+ replaceRecursiveAll(str, "11", '1');
+ REQUIRE(str == "122221");
+ str = "11112222";
+ replaceRecursiveAll(str, "112", '1');
+ REQUIRE(str == "111222");
+ str = "111122224";
+ replaceRecursiveAll(str, "112", '1');
+ REQUIRE(str == "1112224");
+ str = "3111122224";
+ replaceRecursiveAll(str, "112", '1');
+ REQUIRE(str == "31112224");
+ str = "121212";
+ replaceRecursiveAll(str, "12", '1');
+ REQUIRE(str == "111");
+ str = "1121212";
+ replaceRecursiveAll(str, "12", '1');
+ REQUIRE(str == "1111");
+ str = "11212122";
+ replaceRecursiveAll(str, "12", '1');
+ REQUIRE(str == "1111");
+ str = "112121222";
+ replaceRecursiveAll(str, "12", '1');
+ REQUIRE(str == "1111");
+ str = "112211221122";
+ replaceRecursiveAll(str, "12", '1');
+ REQUIRE(str == "111111");
+}
+
+TEST_CASE("stringuntils getBoolFromString 1", "")
+{
+ REQUIRE(getBoolFromString("true"));
+ REQUIRE(getBoolFromString("yes"));
+ REQUIRE(getBoolFromString("on"));
+ REQUIRE(!getBoolFromString("false"));
+ REQUIRE(!getBoolFromString("no"));
+ REQUIRE(!getBoolFromString("off"));
+ REQUIRE(getBoolFromString("1"));
+ REQUIRE(!getBoolFromString("0"));
+ REQUIRE(getBoolFromString("2"));
+
+ REQUIRE(getBoolFromString(" true"));
+ REQUIRE(getBoolFromString("yes "));
+ REQUIRE(getBoolFromString(" on"));
+ REQUIRE(!getBoolFromString("false "));
+ REQUIRE(!getBoolFromString(" no"));
+ REQUIRE(!getBoolFromString("off "));
+ REQUIRE(getBoolFromString(" 1"));
+ REQUIRE(!getBoolFromString("0 "));
+ REQUIRE(getBoolFromString(" 2"));
+
+ REQUIRE(getBoolFromString("tRue "));
+ REQUIRE(getBoolFromString(" Yes"));
+ REQUIRE(getBoolFromString("ON "));
+ REQUIRE(!getBoolFromString(" fALse"));
+ REQUIRE(!getBoolFromString("nO "));
+ REQUIRE(!getBoolFromString(" oFF"));
+}
+
+TEST_CASE("stringuntils parseBoolean 1", "")
+{
+ REQUIRE(parseBoolean("true") == 1);
+ REQUIRE(parseBoolean("yes") == 1);
+ REQUIRE(parseBoolean("on") == 1);
+ REQUIRE(parseBoolean("false") == 0);
+ REQUIRE(parseBoolean("no") == 0);
+ REQUIRE(parseBoolean("off") == 0);
+ REQUIRE(parseBoolean("1") == 1);
+ REQUIRE(parseBoolean("0") == 0);
+ REQUIRE(parseBoolean("2") == -1);
+ REQUIRE(parseBoolean("test") == -1);
+ REQUIRE(parseBoolean("") == -1);
+
+ REQUIRE(parseBoolean("true ") == 1);
+ REQUIRE(parseBoolean(" yes") == 1);
+ REQUIRE(parseBoolean("on ") == 1);
+ REQUIRE(parseBoolean(" false") == 0);
+ REQUIRE(parseBoolean("no ") == 0);
+ REQUIRE(parseBoolean(" off") == 0);
+ REQUIRE(parseBoolean("1 ") == 1);
+ REQUIRE(parseBoolean(" 0") == 0);
+ REQUIRE(parseBoolean("2 ") == -1);
+ REQUIRE(parseBoolean(" test") == -1);
+ REQUIRE(parseBoolean(" ") == -1);
+
+ REQUIRE(parseBoolean(" tRue") == 1);
+ REQUIRE(parseBoolean("Yes ") == 1);
+ REQUIRE(parseBoolean(" ON") == 1);
+ REQUIRE(parseBoolean("FaLse ") == 0);
+ REQUIRE(parseBoolean(" nO") == 0);
+ REQUIRE(parseBoolean("oFf ") == 0);
+ REQUIRE(parseBoolean(" tEst") == -1);
+}
+
+TEST_CASE("stringuntils splitToIntSet 1", "")
+{
+ std::set<int> tokens;
+ splitToIntSet(tokens, "", ',');
+ REQUIRE(tokens.empty() == true);
+
+ tokens.clear();
+ splitToIntSet(tokens, "10z,aa,-1", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find(10) != tokens.end());
+ REQUIRE(tokens.find(0) != tokens.end());
+ REQUIRE(tokens.find(-1) != tokens.end());
+
+ tokens.clear();
+ splitToIntSet(tokens, "10,2,30", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find(10) != tokens.end());
+ REQUIRE(tokens.find(2) != tokens.end());
+ REQUIRE(tokens.find(30) != tokens.end());
+
+ tokens.clear();
+ splitToIntSet(tokens, "10,2,30,", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find(10) != tokens.end());
+ REQUIRE(tokens.find(2) != tokens.end());
+ REQUIRE(tokens.find(30) != tokens.end());
+
+ tokens.clear();
+ splitToIntSet(tokens, "10,2;30", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens.find(10) != tokens.end());
+ REQUIRE(tokens.find(2) != tokens.end());
+
+ tokens.clear();
+ splitToIntSet(tokens, "10;20;30", ';');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find(10) != tokens.end());
+ REQUIRE(tokens.find(20) != tokens.end());
+ REQUIRE(tokens.find(30) != tokens.end());
+}
+
+TEST_CASE("stringuntils splitToIntList 1", "")
+{
+ std::list<int> tokens;
+ tokens = splitToIntList("", ',');
+ REQUIRE(tokens.empty() == true);
+
+ tokens.clear();
+ tokens = splitToIntList("10z,a,-1", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.front() == 10);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 0);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == -1);
+ tokens.pop_front();
+
+ tokens.clear();
+ tokens = splitToIntList("10,2,30", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.front() == 10);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 2);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 30);
+ tokens.pop_front();
+
+ tokens.clear();
+ tokens = splitToIntList("10,2,30,", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.front() == 10);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 2);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 30);
+ tokens.pop_front();
+
+ tokens.clear();
+ tokens = splitToIntList("10,2;30", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens.front() == 10);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 2);
+ tokens.pop_front();
+
+ tokens.clear();
+ tokens = splitToIntList("10;20;30", ';');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.front() == 10);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 20);
+ tokens.pop_front();
+ REQUIRE(tokens.front() == 30);
+ tokens.pop_front();
+}
+
+TEST_CASE("stringuntils splitToStringSet 1", "")
+{
+ std::set<std::string> tokens;
+ splitToStringSet(tokens, "", ',');
+ REQUIRE(tokens.empty() == true);
+
+ tokens.clear();
+ splitToStringSet(tokens, "10q,2w,30e", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find("10q") != tokens.end());
+ REQUIRE(tokens.find("2w") != tokens.end());
+ REQUIRE(tokens.find("30e") != tokens.end());
+
+ tokens.clear();
+ splitToStringSet(tokens, "10q,2w,30e,", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find("10q") != tokens.end());
+ REQUIRE(tokens.find("2w") != tokens.end());
+ REQUIRE(tokens.find("30e") != tokens.end());
+
+ tokens.clear();
+ splitToStringSet(tokens, "10q,,30e", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens.find("10q") != tokens.end());
+ REQUIRE(tokens.find("30e") != tokens.end());
+
+ tokens.clear();
+ splitToStringSet(tokens, "10q,2w,30e,", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find("10q") != tokens.end());
+ REQUIRE(tokens.find("2w") != tokens.end());
+ REQUIRE(tokens.find("30e") != tokens.end());
+
+ tokens.clear();
+ splitToStringSet(tokens, "10w,2w;30e", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens.find("10w") != tokens.end());
+ REQUIRE(tokens.find("2w;30e") != tokens.end());
+
+ tokens.clear();
+ splitToStringSet(tokens, "10q;20w;30e", ';');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens.find("10q") != tokens.end());
+ REQUIRE(tokens.find("20w") != tokens.end());
+ REQUIRE(tokens.find("30e") != tokens.end());
+}
+
+TEST_CASE("stringuntils splitToIntVector 1", "")
+{
+ std::vector<int> tokens;
+ splitToIntVector(tokens, "", ',');
+ REQUIRE(tokens.empty() == true);
+
+ tokens.clear();
+ splitToIntVector(tokens, "10,2,30", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == 10);
+ REQUIRE(tokens[1] == 2);
+ REQUIRE(tokens[2] == 30);
+
+ tokens.clear();
+ splitToIntVector(tokens, "10,2a,z30", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == 10);
+ REQUIRE(tokens[1] == 2);
+ REQUIRE(tokens[2] == 0);
+
+ tokens.clear();
+ splitToIntVector(tokens, "10,2,30,", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == 10);
+ REQUIRE(tokens[1] == 2);
+ REQUIRE(tokens[2] == 30);
+
+ tokens.clear();
+ splitToIntVector(tokens, "10,,30", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens[0] == 10);
+ REQUIRE(tokens[1] == 30);
+
+ tokens.clear();
+ splitToIntVector(tokens, "10,2;30", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens[0] == 10);
+ REQUIRE(tokens[1] == 2);
+
+ tokens.clear();
+ splitToIntVector(tokens, "10;20;30", ';');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == 10);
+ REQUIRE(tokens[1] == 20);
+ REQUIRE(tokens[2] == 30);
+}
+
+TEST_CASE("stringuntils splitToStringVector 1", "")
+{
+ std::vector<std::string> tokens;
+ splitToStringVector(tokens, "", ',');
+ REQUIRE(tokens.empty() == true);
+
+ tokens.clear();
+ splitToStringVector(tokens, "t,line,zz", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == "t");
+ REQUIRE(tokens[1] == "line");
+ REQUIRE(tokens[2] == "zz");
+
+ tokens.clear();
+ splitToStringVector(tokens, "t,line,zz,", ',');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == "t");
+ REQUIRE(tokens[1] == "line");
+ REQUIRE(tokens[2] == "zz");
+
+ tokens.clear();
+ splitToStringVector(tokens, "t,,zz", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens[0] == "t");
+ REQUIRE(tokens[1] == "zz");
+
+ tokens.clear();
+ splitToStringVector(tokens, "10,a2;30", ',');
+ REQUIRE(tokens.size() == 2);
+ REQUIRE(tokens[0] == "10");
+ REQUIRE(tokens[1] == "a2;30");
+
+ tokens.clear();
+ splitToStringVector(tokens, "a10;b;3line", ';');
+ REQUIRE(tokens.size() == 3);
+ REQUIRE(tokens[0] == "a10");
+ REQUIRE(tokens[1] == "b");
+ REQUIRE(tokens[2] == "3line");
+}
+
+TEST_CASE("stringuntils replaceSpecialChars 1", "")
+{
+ std::string str;
+
+ str = "";
+ replaceSpecialChars(str);
+ REQUIRE(str.empty());
+
+ str = "test";
+ replaceSpecialChars(str);
+ REQUIRE("test" == str);
+
+ str = "&";
+ replaceSpecialChars(str);
+ REQUIRE("&" == str);
+
+ str = "&1";
+ replaceSpecialChars(str);
+ REQUIRE("&1" == str);
+
+ str = "&33";
+ replaceSpecialChars(str);
+ REQUIRE("&33" == str);
+
+ str = "&33;";
+ replaceSpecialChars(str);
+ REQUIRE("!" == str);
+
+ str = "&33z;";
+ replaceSpecialChars(str);
+ REQUIRE("&33z;" == str);
+
+ str = "1&33;";
+ replaceSpecialChars(str);
+ REQUIRE("1!" == str);
+
+ str = "&33;2";
+ replaceSpecialChars(str);
+ REQUIRE("!2" == str);
+
+ str = "&33;&";
+ replaceSpecialChars(str);
+ REQUIRE("!&" == str);
+
+ str = "test line&33;";
+ replaceSpecialChars(str);
+ REQUIRE("test line!" == str);
+}
+
+TEST_CASE("stringuntils normalize 1", "")
+{
+ REQUIRE(normalize("").empty());
+ REQUIRE(normalize("test") == "test");
+ REQUIRE(normalize("Test") == "test");
+ REQUIRE(normalize(" test line") == "test line");
+ REQUIRE(normalize("test line ") == "test line");
+ REQUIRE(normalize(" tEst line") == "test line");
+ REQUIRE(normalize("test lIne ") == "test line");
+}
+
+TEST_CASE("stringuntils combineDye 1", "")
+{
+ REQUIRE(combineDye("", "").empty());
+ REQUIRE("test" == combineDye("test", ""));
+ REQUIRE("|line" == combineDye("", "line"));
+ REQUIRE("test|line" == combineDye("test", "line"));
+ REQUIRE("|line" == combineDye("|w", "line"));
+ REQUIRE("aaa|line" == combineDye("aaa|w", "line"));
+ REQUIRE("test|line" == combineDye("test|w", "line"));
+}
+
+TEST_CASE("stringuntils combineDye 2", "")
+{
+ REQUIRE(combineDye2("", "").empty());
+ REQUIRE("test" == combineDye2("test", ""));
+ REQUIRE("test" == combineDye2("test", "W"));
+ REQUIRE(combineDye2("", "line").empty());
+ REQUIRE("test.xml" == combineDye2("test.xml", "123"));
+ REQUIRE("test.xml|#43413d,59544f,7a706c" ==
+ combineDye2("test.xml|#43413d,59544f,7a706c", ""));
+ REQUIRE("test.xml|#43413d,59544f,7a706c:W;" ==
+ combineDye2("test.xml|#43413d,59544f,7a706c", "W"));
+ REQUIRE("test.xml|#43413d,59544f,7a706c:W;#123456:B;" ==
+ combineDye2("test.xml|#43413d,59544f,7a706c;#123456", "W;B"));
+}
+
+TEST_CASE("stringuntils combineDye 3", "")
+{
+ REQUIRE(combineDye3("", "").empty());
+ REQUIRE("test" == combineDye3("test", ""));
+ REQUIRE(combineDye3("", "line").empty());
+ REQUIRE("test.xml|123" == combineDye3("test.xml", "123"));
+ REQUIRE("test.xml|#43413d,59544f,7a706c" ==
+ combineDye3("test.xml|#43413d,59544f,7a706c", ""));
+ REQUIRE("test.xml|#43413d,59544f,7a706c:W;" ==
+ combineDye3("test.xml|#43413d,59544f,7a706c", "W"));
+ REQUIRE("test.xml|#43413d,59544f,7a706c:W;#123456:B;" ==
+ combineDye3("test.xml|#43413d,59544f,7a706c;#123456", "W;B"));
+}
+
+TEST_CASE("stringuntils packList 1", "")
+{
+ std::list <std::string> list;
+ REQUIRE(packList(list).empty());
+
+ list.push_back(std::string());
+ REQUIRE("|" == packList(list));
+
+ list.clear();
+ list.push_back("test");
+ REQUIRE("test" == packList(list));
+
+ list.push_back("line");
+ REQUIRE("test|line" == packList(list));
+
+ list.push_back("2");
+ REQUIRE("test|line|2" == packList(list));
+
+ list.clear();
+ list.push_back("|test");
+ list.push_back("line");
+ REQUIRE("|test|line" == packList(list));
+}
+
+TEST_CASE("stringuntils stringToHexPath 1", "")
+{
+ std::string str;
+
+ str = "";
+ REQUIRE(stringToHexPath(str).empty());
+
+ str = "a";
+ REQUIRE("%61/" == stringToHexPath(str));
+
+ str = "ab";
+ REQUIRE("%61/%62" == stringToHexPath(str));
+
+ str = "abc";
+ REQUIRE("%61/%62%63" == stringToHexPath(str));
+
+ str = "abcd";
+ REQUIRE("%61/%62%63%64" == stringToHexPath(str));
+}
+
+TEST_CASE("stringuntils deleteCharLeft 1", "")
+{
+ std::string str;
+ unsigned int pos = 0;
+
+ str = "";
+ deleteCharLeft(str, nullptr);
+ REQUIRE(str.empty());
+
+ str = "test line";
+ pos = 4;
+ deleteCharLeft(str, &pos);
+ REQUIRE("tes line" == str);
+
+ str = "тест line";
+ pos = 8;
+ deleteCharLeft(str, &pos);
+ REQUIRE("тес line" == str);
+
+ str = "test line\x0";
+ pos = 4;
+ deleteCharLeft(str, &pos);
+ REQUIRE("tes line\x0" == str);
+}
+
+TEST_CASE("stringuntils findLast 1", "")
+{
+ std::string str;
+
+ str = "";
+ REQUIRE(findLast(str, ""));
+
+ str = "test line";
+ REQUIRE(findLast(str, "line"));
+
+ str = "test line";
+ REQUIRE(!findLast(str, "lin"));
+}
+
+TEST_CASE("stringuntils findFirst 1", "")
+{
+ std::string str;
+
+ str = "";
+ REQUIRE(findFirst(str, ""));
+
+ str = "test line";
+ REQUIRE(findFirst(str, "test"));
+
+ str = "test";
+ REQUIRE(findFirst(str, "test line") == false);
+
+ str = "test line";
+ REQUIRE(findFirst(str, "est") == false);
+}
+
+TEST_CASE("stringuntils findCutLast 1", "")
+{
+ std::string str;
+
+ str = "";
+ REQUIRE(findCutLast(str, ""));
+ REQUIRE(str.empty());
+
+ str = "test line";
+ REQUIRE(findCutLast(str, "line"));
+ REQUIRE("test " == str);
+
+ str = "test line";
+ REQUIRE(findCutLast(str, "lin") == false);
+ REQUIRE("test line" == str);
+
+ str = "test";
+ REQUIRE(findCutLast(str, "test line") == false);
+ REQUIRE("test" == str);
+}
+
+TEST_CASE("stringuntils CutLast 1", "")
+{
+ std::string str;
+
+ str = "";
+ cutLast(str, "");
+ REQUIRE(str.empty());
+
+ str = "test line";
+ cutLast(str, "line");
+ REQUIRE("test " == str);
+
+ str = "test line";
+ cutLast(str, "lin");
+ REQUIRE("test line" == str);
+
+ str = "test";
+ cutLast(str, "test line");
+ REQUIRE("test" == str);
+}
+
+TEST_CASE("stringuntils findCutFirst 1", "")
+{
+ std::string str;
+
+ str = "";
+ REQUIRE(findCutFirst(str, ""));
+ REQUIRE(str.empty());
+
+ str = "test line";
+ REQUIRE(findCutFirst(str, "test"));
+ REQUIRE(" line" == str);
+
+ str = "test line";
+ REQUIRE(findCutFirst(str, "est") == false);
+ REQUIRE("test line" == str);
+
+ str = "test";
+ REQUIRE(findCutFirst(str, "test line") == false);
+ REQUIRE("test" == str);
+}
+
+TEST_CASE("stringuntils cutFirst 1", "")
+{
+ std::string str;
+
+ str = "";
+ cutFirst(str, "");
+ REQUIRE(str.empty());
+
+ str = "test line";
+ cutFirst(str, "test");
+ REQUIRE(" line" == str);
+
+ str = "test line";
+ cutFirst(str, "est");
+ REQUIRE("test line" == str);
+
+ str = "test";
+ cutFirst(str, "test line");
+ REQUIRE("test" == str);
+}
+
+TEST_CASE("stringuntils removeProtocol 1", "")
+{
+ std::string str;
+
+ str = "";
+ REQUIRE(removeProtocol(str).empty());
+
+ str = "http://";
+ REQUIRE(removeProtocol(str).empty());
+
+ str = "http://test";
+ REQUIRE("test" == removeProtocol(str));
+}
+
+TEST_CASE("stringuntils strStartWith 1", "")
+{
+ REQUIRE(strStartWith("", ""));
+ REQUIRE(!strStartWith("", "1"));
+ REQUIRE(strStartWith("test line", "test"));
+ REQUIRE(strStartWith("test line", "test line"));
+ REQUIRE(!strStartWith("test line", "est"));
+}
+
+TEST_CASE("stringuntils encodeLinkText", "")
+{
+ std::string str;
+
+ str = encodeLinkText("test line");
+ REQUIRE(str == "test line");
+ str = encodeLinkText("test|line");
+ REQUIRE(str == "test\342\235\230line");
+ str = encodeLinkText("test||line");
+ REQUIRE(str == "test\342\235\230\342\235\230line");
+}
+
+TEST_CASE("stringuntils decodeLinkText", "")
+{
+ std::string str;
+
+ str = encodeLinkText("test|line");
+ REQUIRE(str == "test\342\235\230line");
+ str = decodeLinkText(str);
+ REQUIRE(str == "test|line");
+}
+
+TEST_CASE("stringuntils isDigit", "")
+{
+ std::string str;
+
+ REQUIRE_FALSE(isDigit(""));
+ REQUIRE(isDigit("1"));
+ REQUIRE(isDigit("123"));
+ REQUIRE_FALSE(isDigit("+123"));
+ REQUIRE_FALSE(isDigit("-123"));
+ REQUIRE_FALSE(isDigit("1.23"));
+ REQUIRE_FALSE(isDigit("12-34"));
+}
+
+TEST_CASE("stringuntils findAny", "")
+{
+ std::string str;
+
+ REQUIRE(findAny("test line", ",", 0) == std::string::npos);
+ REQUIRE(findAny("test line", " ", 0) == 4U);
+ REQUIRE(findAny("test, line", ", ", 0) == 4U);
+ REQUIRE(findAny("test ,line", ", ", 0) == 4U);
+ REQUIRE(findAny("test, line", " ,", 2) == 4U);
+ REQUIRE(findAny("test ,line", " ,", 3) == 4U);
+ REQUIRE(findAny("\"one\",,two, tree", ",", 5) == 5U);
+}
+
+TEST_CASE("stringuntils escapeString", "")
+{
+ REQUIRE(escapeString("") == "\"\"");
+ REQUIRE(escapeString("1") == "\"1\"");
+ REQUIRE(escapeString(" ") == "\" \"");
+ REQUIRE(escapeString("\"") == "\"\\\"\"");
+ REQUIRE(escapeString("123") == "\"123\"");
+ REQUIRE(escapeString("12\"3") == "\"12\\\"3\"");
+ REQUIRE(escapeString("12\"\"3") == "\"12\\\"\\\"3\"");
+ REQUIRE(escapeString("\"123\"") == "\"\\\"123\\\"\"");
+ REQUIRE(escapeString("\\") == "\"\\\"");
+ REQUIRE(escapeString("12\\3") == "\"12\\3\"");
+}
+
+TEST_CASE("stringuntils sanitizePath", "")
+{
+ std::string path;
+ const std::string sep = dirSeparator;
+ path = "";
+ sanitizePath(path);
+ REQUIRE(path.empty());
+ path = "/";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "/\\";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "\\/";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "//";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "///";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "//\\/";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "///\\";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "\\";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "\\\\";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "\\/\\";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "\\\\/";
+ sanitizePath(path);
+ REQUIRE(path == dirSeparator);
+ path = "test";
+ sanitizePath(path);
+ REQUIRE(path == "test");
+ path = "./test";
+ sanitizePath(path);
+ REQUIRE(path == "." + sep + "test");
+ path = "test line";
+ sanitizePath(path);
+ REQUIRE(path == "test line");
+ path = "dir/test";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test");
+ path = "/dir/test";
+ sanitizePath(path);
+ REQUIRE(path == sep + "dir" + sep + "test");
+ path = "dir//test";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test");
+ path = "dir///test";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test");
+ path = "dir///\\test";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test");
+ path = "dir/\\//test";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test");
+ path = "dir\\test";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test");
+ path = "dir/test/";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test" + sep);
+ path = "dir/test\\";
+ sanitizePath(path);
+ REQUIRE(path == "dir" + sep + "test" + sep);
+ path = "/very\\long/dir\\with\\sepa/ra/tors";
+ sanitizePath(path);
+ REQUIRE(path == sep + "very" + sep + "long" + sep + \
+ "dir" + sep + "with" + sep + "sepa" + sep + "ra" + sep + "tors");
+ path = "/very\\long/dir\\\\with\\sepa//ra/tors";
+ sanitizePath(path);
+ REQUIRE(path == sep + "very" + sep + "long" + sep + \
+ "dir" + sep + "with" + sep + "sepa" + sep + "ra" + sep + "tors");
+}
+
+TEST_CASE("stringuntils pathJoin1", "")
+{
+ const std::string sep = dirSeparator;
+
+ REQUIRE(pathJoin("", "") == sep);
+ REQUIRE(pathJoin(sep, "") == sep);
+ REQUIRE(pathJoin("", sep) == sep);
+ REQUIRE(pathJoin(sep, sep) == sep);
+ REQUIRE(pathJoin("dir1", "dir2") == "dir1" + sep + "dir2");
+ REQUIRE(pathJoin("dir1" + sep, "dir2") == "dir1" + sep + "dir2");
+ REQUIRE(pathJoin("dir1", sep + "dir2") == "dir1" + sep + "dir2");
+ REQUIRE(pathJoin("dir1" + sep, sep + "dir2") == "dir1" + sep + "dir2");
+ REQUIRE(pathJoin("dir1" + sep + "dir2" + sep + "dir3", "dir4") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4");
+ REQUIRE(pathJoin("dir1" + sep + "dir2" + sep, "dir3" + sep + "dir4") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4");
+ REQUIRE(pathJoin("dir1" + sep + "dir2", "dir3" + sep + "dir4") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4");
+ REQUIRE(pathJoin("dir1" + sep + "dir2", sep + "dir3" + sep + "dir4") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4");
+}
+
+TEST_CASE("stringuntils pathJoin2", "")
+{
+ const std::string sep = dirSeparator;
+
+ REQUIRE(pathJoin("", "", "") == sep);
+ REQUIRE(pathJoin(sep, "", "") == sep);
+ REQUIRE(pathJoin("", sep, "") == sep);
+ REQUIRE(pathJoin("", "", sep) == sep);
+ REQUIRE(pathJoin(sep, sep, "") == sep);
+ REQUIRE(pathJoin(sep, "", sep) == sep);
+ REQUIRE(pathJoin("", sep, sep) == sep);
+ REQUIRE(pathJoin(sep, sep, sep) == sep);
+
+ REQUIRE(pathJoin("dir1", "dir2", "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, "dir2", "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1", sep + "dir2", "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1", "dir2" + sep, "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1", "dir2", sep + "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1", "dir2", "dir3" + sep) ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep);
+ REQUIRE(pathJoin("dir1" + sep, sep + "dir2", "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, "dir2" + sep, "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, "dir2", sep + "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, sep + "dir2" + sep, "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, sep + "dir2", sep + "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, sep + "dir2" + sep, "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep, sep + "dir2" + sep, sep + "dir3") ==
+ "dir1" + sep + "dir2" + sep + "dir3");
+ REQUIRE(pathJoin("dir1" + sep + "dir2" + sep + "dir3", "dir4", "dir5") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4" + sep + "dir5");
+ REQUIRE(pathJoin("dir1" + sep + "dir2" + sep,
+ "dir3" + sep + "dir4",
+ "dir5") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4" + sep + "dir5");
+ REQUIRE(pathJoin("dir1" + sep + "dir2",
+ "dir3",
+ sep + "dir4" + sep + "dir5") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4" + sep + "dir5");
+ REQUIRE(pathJoin("dir1" + sep + "dir2",
+ sep + "dir3" + sep + "dir4",
+ sep + "dir5") ==
+ "dir1" + sep + "dir2" + sep + "dir3" + sep + "dir4" + sep + "dir5");
+}
+
+TEST_CASE("stringuntils urlJoin", "")
+{
+ REQUIRE(urlJoin("", "") == "/");
+ REQUIRE(urlJoin("/", "") == "/");
+ REQUIRE(urlJoin("", "/") == "/");
+ REQUIRE(urlJoin("/", "/") == "/");
+ REQUIRE(urlJoin("dir1", "dir2") == "dir1/dir2");
+ REQUIRE(urlJoin("dir1/", "dir2") == "dir1/dir2");
+ REQUIRE(urlJoin("dir1", "/dir2") == "dir1/dir2");
+ REQUIRE(urlJoin("dir1/", "/dir2") == "dir1/dir2");
+ REQUIRE(urlJoin("dir1/dir2/dir3", "dir4") == "dir1/dir2/dir3/dir4");
+ REQUIRE(urlJoin("dir1/dir2/", "dir3/dir4") == "dir1/dir2/dir3/dir4");
+ REQUIRE(urlJoin("dir1/dir2", "dir3/dir4") == "dir1/dir2/dir3/dir4");
+ REQUIRE(urlJoin("dir1/dir2", "/dir3/dir4") == "dir1/dir2/dir3/dir4");
+}
+
+TEST_CASE("stringuntils secureChatCommand", "")
+{
+ std::string str;
+ secureChatCommand(str);
+ REQUIRE(str.empty());
+ str = "test";
+ secureChatCommand(str);
+ REQUIRE(str == "test");
+ str = "test line";
+ secureChatCommand(str);
+ REQUIRE(str == "test line");
+ str = "/test";
+ secureChatCommand(str);
+ REQUIRE(str == "_/test");
+ str = "@test";
+ secureChatCommand(str);
+ REQUIRE(str == "_@test");
+ str = "#test";
+ secureChatCommand(str);
+ REQUIRE(str == "_#test");
+}
+
+#ifdef ENABLE_NLS
+TEST_CASE("stringuntils timeDiffToString", "")
+{
+ REQUIRE(timeDiffToString(60 * 60 * 24 * 7) == "1 week");
+ REQUIRE(timeDiffToString(60 * 60 * 24 * 7 * 2 +
+ 60 * 60 * 24 * 3
+ ) == "2 weeks, 3 days");
+ REQUIRE(timeDiffToString(60 * 60 * 24 * 7 * 2 +
+ 60 * 60 * 24 * 3 +
+ 60 * 60 * 4
+ ) == "2 weeks, 3 days, 4 hours");
+ REQUIRE(timeDiffToString(60 * 60 * 24 * 7 * 2 +
+ 60 * 60 * 24 * 3 +
+ 60 * 60 * 4 +
+ 60 * 7
+ ) == "2 weeks, 3 days, 4 hours, 7 minutes");
+ REQUIRE(timeDiffToString(60 * 60 * 24 * 7 * 2 +
+ 60 * 60 * 24 * 3 +
+ 60 * 60 * 4 +
+ 60 * 7 +
+ 10
+ ) == "2 weeks, 3 days, 4 hours, 7 minutes, 10 seconds");
+ REQUIRE(timeDiffToString(5) == "5 seconds");
+ REQUIRE(timeDiffToString(0) == "0 seconds");
+ REQUIRE(timeDiffToString(60 * 60 * 24 * 3
+ ) == "3 days");
+ REQUIRE(timeDiffToString(60 * 60 * 4
+ ) == "4 hours");
+ REQUIRE(timeDiffToString(60 * 7
+ ) == "7 minutes");
+}
+#endif // ENABLE_NLS
+
+TEST_CASE("stringuntils replaceItemLinks", "")
+{
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+ ItemDB::NamedItemInfos &namedInfos = ItemDB::getNamedItemInfosTest();
+ ItemDB::ItemInfos &infos = ItemDB::getItemInfosTest();
+ paths.setDefaultValues(getPathsDefaults());
+ ItemInfo *info = new ItemInfo;
+ info->setId(123456);
+ info->setName("test name 1");
+ namedInfos["test name 1"] = info;
+ infos[123456] = info;
+
+ info = new ItemInfo;
+ info->setId(123);
+ info->setName("test name 2");
+ namedInfos["test name 2"] = info;
+ namedInfos["qqq"] = info;
+ infos[123] = info;
+
+ std::string str;
+
+ SECTION("empty")
+ {
+ str = "test line";
+ replaceItemLinks(str);
+ REQUIRE(str == "test line");
+
+ str = "";
+ replaceItemLinks(str);
+ REQUIRE(str.empty());
+
+ str = "[]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[]");
+
+ str = "[qqq]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[@@123|qqq@@]");
+
+ str = "[,]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[,]");
+
+ str = "[, ]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[, ]");
+ }
+
+ SECTION("simple")
+ {
+ str = "[test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[@@123456|test name 1@@]");
+
+ str = "text1 [test name 1] text2";
+ replaceItemLinks(str);
+ REQUIRE(str == "text1 [@@123456|test name 1@@] text2");
+
+ str = "[test name 1][test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[@@123456|test name 1@@][@@123456|test name 1@@]");
+
+ str = "[test name 1] [test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[@@123456|test name 1@@] [@@123456|test name 1@@]");
+
+ str = "test1 [test name 1]test2[test name 1] test3";
+ replaceItemLinks(str);
+ REQUIRE(str == "test1 [@@123456|test name 1@@]test2"
+ "[@@123456|test name 1@@] test3");
+
+// failing because assert
+// str = "[test name 1] [no link]";
+// replaceItemLinks(str);
+// REQUIRE(str == "[@@123456|test name 1@@] [no link]");
+
+ str = "[test name 1,test name 2]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[@@123456,123|@@]");
+
+ str = "[test name 1, test name 2 ]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[@@123456,123|@@]");
+ }
+
+ SECTION("broken")
+ {
+ str = "[";
+ replaceItemLinks(str);
+ REQUIRE(str == "[");
+
+ str = "]";
+ replaceItemLinks(str);
+ REQUIRE(str == "]");
+
+ str = "][";
+ replaceItemLinks(str);
+ REQUIRE(str == "][");
+
+ str = "]]";
+ replaceItemLinks(str);
+ REQUIRE(str == "]]");
+
+ str = "]t";
+ replaceItemLinks(str);
+ REQUIRE(str == "]t");
+
+ str = "t[";
+ replaceItemLinks(str);
+ REQUIRE(str == "t[");
+
+ str = "t]";
+ replaceItemLinks(str);
+ REQUIRE(str == "t]");
+
+ str = "[[[";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[[");
+
+ str = "[[]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[]");
+
+ str = "[[t";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[t");
+
+ str = "[][";
+ replaceItemLinks(str);
+ REQUIRE(str == "[][");
+
+ str = "[]]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[]]");
+
+ str = "[]t";
+ replaceItemLinks(str);
+ REQUIRE(str == "[]t");
+
+ str = "[t[";
+ replaceItemLinks(str);
+ REQUIRE(str == "[t[");
+
+// failing because assert
+// str = "[t]";
+// replaceItemLinks(str);
+// REQUIRE(str == "[t]");
+
+ str = "t[[";
+ replaceItemLinks(str);
+ REQUIRE(str == "t[[");
+
+ str = "t[]";
+ replaceItemLinks(str);
+ REQUIRE(str == "t[]");
+
+ str = "t[[";
+ replaceItemLinks(str);
+ REQUIRE(str == "t[[");
+
+ str = "]]]";
+ replaceItemLinks(str);
+ REQUIRE(str == "]]]");
+ }
+
+ SECTION("broken2")
+ {
+ str = "[][]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[][]");
+
+ str = "[[]]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[]]");
+
+ str = "][[]";
+ replaceItemLinks(str);
+ REQUIRE(str == "][[]");
+ }
+
+ SECTION("broken3")
+ {
+ str = "[[test name 1]]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[@@123456|test name 1@@]]");
+
+ str = "[[test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[@@123456|test name 1@@]");
+
+ str = "[[qqq] name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[@@123|qqq@@] name 1]");
+
+ str = "[[test name 1]test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[@@123456|test name 1@@]test name 1]");
+
+ str = "[[test name 1[]test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[test name 1[]test name 1]");
+
+ str = "[[test name 1],test name2,test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[@@123456|test name 1@@],test name2,test name 1]");
+
+ str = "[[ test name 1], test name2,test name 1 ]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[@@123456|test name 1@@], test name2,test name 1 ]");
+
+ str = "[[test name 1,test name2[]test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[test name 1,test name2[]test name 1]");
+
+ str = "[[test name 1 ,test name2[] test name 1]";
+ replaceItemLinks(str);
+ REQUIRE(str == "[[test name 1 ,test name2[] test name 1]");
+ }
+ ResourceManager::deleteInstance();
+ delete_all(infos);
+ infos.clear();
+ namedInfos.clear();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ delete2(logger);
+// VirtFs::deinit();
+}
diff --git a/src/unittests/utils/timer_unittest.cc b/src/unittests/utils/timer_unittest.cc
new file mode 100644
index 000000000..b5cfc692e
--- /dev/null
+++ b/src/unittests/utils/timer_unittest.cc
@@ -0,0 +1,88 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "const/utils/timer.h"
+
+#include "utils/timer.h"
+
+#include <climits>
+
+#include "debug.h"
+
+static const int MAX_TICK_VALUE = INT_MAX / 2;
+
+TEST_CASE("timer const", "")
+{
+ REQUIRE(MILLISECONDS_IN_A_TICK != 0);
+}
+
+TEST_CASE("timer get_elapsed_time", "")
+{
+ tick_time = 0;
+ REQUIRE(get_elapsed_time(0) == 0);
+ REQUIRE(get_elapsed_time(MAX_TICK_VALUE - 1) == 1 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(MAX_TICK_VALUE - 2) == 2 * MILLISECONDS_IN_A_TICK);
+
+ tick_time = 1;
+ REQUIRE(get_elapsed_time(0) == 1 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(1) == 0 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(MAX_TICK_VALUE - 1) == 2 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(MAX_TICK_VALUE - 2) == 3 * MILLISECONDS_IN_A_TICK);
+
+ tick_time = 10;
+ REQUIRE(get_elapsed_time(0) == 10 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(10) == 0 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(MAX_TICK_VALUE - 1) ==
+ 11 * MILLISECONDS_IN_A_TICK);
+
+ tick_time = 10000;
+ REQUIRE(get_elapsed_time(0) == 10000 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(10) == 9990 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(10000) == 0 * MILLISECONDS_IN_A_TICK);
+ REQUIRE(get_elapsed_time(MAX_TICK_VALUE - 1) ==
+ 10001 * MILLISECONDS_IN_A_TICK);
+}
+
+TEST_CASE("timer get_elapsed_time1", "")
+{
+ tick_time = 0;
+ REQUIRE(get_elapsed_time1(0) == 0);
+ REQUIRE(get_elapsed_time1(MAX_TICK_VALUE - 1) == 1);
+ REQUIRE(get_elapsed_time1(MAX_TICK_VALUE - 2) == 2);
+
+ tick_time = 1;
+ REQUIRE(get_elapsed_time1(0) == 1);
+ REQUIRE(get_elapsed_time1(1) == 0);
+ REQUIRE(get_elapsed_time1(MAX_TICK_VALUE - 1) == 2);
+ REQUIRE(get_elapsed_time1(MAX_TICK_VALUE - 2) == 3);
+
+ tick_time = 10;
+ REQUIRE(get_elapsed_time1(0) == 10);
+ REQUIRE(get_elapsed_time1(10) == 0);
+ REQUIRE(get_elapsed_time1(MAX_TICK_VALUE - 1) == 11);
+
+ tick_time = 10000;
+ REQUIRE(get_elapsed_time1(0) == 10000);
+ REQUIRE(get_elapsed_time1(10) == 9990);
+ REQUIRE(get_elapsed_time1(10000) == 0);
+ REQUIRE(get_elapsed_time1(MAX_TICK_VALUE - 1) == 10001);
+}
diff --git a/src/unittests/utils/translation/poparser_unittest.cc b/src/unittests/utils/translation/poparser_unittest.cc
new file mode 100644
index 000000000..f724e66fb
--- /dev/null
+++ b/src/unittests/utils/translation/poparser_unittest.cc
@@ -0,0 +1,158 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2016-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "configmanager.h"
+#include "dirs.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+
+#include "utils/translation/podict.h"
+#include "utils/translation/poparser.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "debug.h"
+
+TEST_CASE("PoParser leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("PoParser tests", "PoParser")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ theme = new Theme;
+ Theme::selectSkin();
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+
+ SECTION("PoParser empty")
+ {
+ PoParser *parser = new PoParser;
+ PoDict *dict = parser->load("ru",
+ "unknownfilename.po",
+ nullptr);
+
+ REQUIRE(dict != nullptr);
+ REQUIRE(dict->getMap() != nullptr);
+ REQUIRE(dict->getMap()->empty());
+
+ delete parser;
+ delete dict;
+ }
+
+ SECTION("PoParser normal")
+ {
+ PoParser *parser = new PoParser;
+ PoDict *dict = parser->load("ru",
+ "test/test1",
+ nullptr);
+
+ REQUIRE(dict != nullptr);
+ REQUIRE(dict->getMap() != nullptr);
+ REQUIRE(dict->getMap()->size() == 1786);
+ REQUIRE(dict->getStr("Unknown skill message.") ==
+ "Неизвестная ошибка скилов.");
+ REQUIRE(dict->getStr("Full strip failed because of coating.") ==
+ "Full strip failed because of coating.");
+ REQUIRE(dict->getStr("You picked up %d [@@%d|%s@@].") ==
+ "Вы подняли %d [@@%d|%s@@].");
+
+ delete parser;
+ delete dict;
+ }
+
+ SECTION("PoParser fuzzy")
+ {
+ PoParser *parser = new PoParser;
+ PoDict *dict = parser->load("ru",
+ "test/test1",
+ nullptr);
+
+ REQUIRE(dict != nullptr);
+ REQUIRE(dict->getMap() != nullptr);
+ REQUIRE(dict->getMap()->size() == 1786);
+ REQUIRE(dict->getStr("Atk +100%.") == "Atk +100%.");
+
+ delete parser;
+ delete dict;
+ }
+ delete2(client);
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("PoParser leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/utils/xml_unittest.cc b/src/unittests/utils/xml_unittest.cc
new file mode 100644
index 000000000..f9f7990f8
--- /dev/null
+++ b/src/unittests/utils/xml_unittest.cc
@@ -0,0 +1,400 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2014-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "configmanager.h"
+#include "dirs.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+#include "gui/theme.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+#ifdef ENABLE_PUGIXML
+#include "utils/xmlwriter.h"
+#endif // ENABLE_PUGIXML
+
+#include "render/sdlgraphics.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "debug.h"
+
+TEST_CASE("xml test1", "")
+{
+ logger = new Logger();
+ REQUIRE(client == nullptr);
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("xml doc", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ logger = new Logger();
+ client = new Client;
+ XML::initXML();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ Dirs::initRootDir();
+ Dirs::initHomeDir();
+
+ ConfigManager::initConfiguration();
+ getConfigDefaults2(config.getDefaultValues());
+ branding.setDefaultValues(getBrandingDefaults());
+
+ theme = new Theme;
+ Theme::selectSkin();
+
+ const char *const tempXmlName = "tempxml.xml";
+ ActorSprite::load();
+ gui = new Gui();
+ gui->postInit(mainGraphics);
+
+ SECTION("load1")
+ {
+ XML::Document doc("graphics/gui/browserbox.xml",
+ UseVirtFs_true,
+ SkipError_false);
+ REQUIRE(doc.isLoaded() == true);
+ REQUIRE(doc.isValid() == true);
+ REQUIRE(doc.rootNode() != nullptr);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "skinset") == true);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "skinset123") == false);
+ REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
+// REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
+ }
+
+ SECTION("load2")
+ {
+ const char *const xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<root><data option1=\"false\" option2=\"true\"/>"
+ "<cont>this is test</cont></root>";
+ XML::Document doc(xml, strlen(xml));
+ REQUIRE(doc.isLoaded() == true);
+ REQUIRE(doc.isValid() == true);
+ REQUIRE(doc.rootNode() != nullptr);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root123") == false);
+ REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
+ REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
+ REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
+ REQUIRE(XmlHaveChildContent(doc.rootNode()) == false);
+ }
+
+ SECTION("load3")
+ {
+ const std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<!-- comment here\nand here -->"
+ "<root><data option1=\"false\" option2=\"true\"/></root>";
+ XML::Document doc(xml.c_str(), xml.size());
+ REQUIRE(doc.isLoaded() == true);
+ REQUIRE(doc.isValid() == true);
+ REQUIRE(doc.rootNode() != nullptr);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root123") == false);
+ REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
+ REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
+ REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
+ REQUIRE(XmlHaveChildContent(doc.rootNode()) == false);
+ }
+
+ SECTION("load4")
+ {
+ const char *const xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<root>this is test</root>";
+ XML::Document doc(xml, strlen(xml));
+ REQUIRE(doc.isLoaded() == true);
+ REQUIRE(doc.isValid() == true);
+ REQUIRE(doc.rootNode() != nullptr);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root123") == false);
+ REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
+ REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
+ REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
+ REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
+ REQUIRE(!strcmp(XmlChildContent(doc.rootNode()), "this is test"));
+ }
+
+ SECTION("properties")
+ {
+ XML::Document doc("graphics/gui/browserbox.xml",
+ UseVirtFs_true,
+ SkipError_false);
+
+ XmlNodeConstPtr rootNode = doc.rootNode();
+ REQUIRE(XML::getProperty(rootNode, "image", "") == "window.png");
+ }
+
+ SECTION("for each")
+ {
+ XML::Document doc("graphics/gui/browserbox.xml",
+ UseVirtFs_true,
+ SkipError_false);
+
+ XmlNodeConstPtr rootNode = doc.rootNode();
+// REQUIRE(XmlHaveChildContent(rootNode) == true);
+ XmlNodePtr node = XmlNodeDefault;
+ for_each_xml_child_node(widgetNode, rootNode)
+ {
+ node = widgetNode;
+ if (xmlNameEqual(node, "widget"))
+ break;
+ }
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "widget") == true);
+// REQUIRE(XmlHaveChildContent(node) == true);
+ for_each_xml_child_node(optionNode, node)
+ {
+ node = optionNode;
+ if (xmlNameEqual(node, "option"))
+ break;
+ }
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "option") == true);
+ REQUIRE(XmlHaveChildContent(node) == false);
+ REQUIRE(XmlHasProp(node, "name") == true);
+ REQUIRE(XmlHasProp(node, "value") == true);
+ REQUIRE(XmlHasProp(node, "option123") == false);
+ REQUIRE(XML::getProperty(node, "name", "") == "padding");
+ REQUIRE(XML::langProperty(node, "name", "") == "padding");
+ REQUIRE(XML::getProperty(node, "value", 0) == 1);
+ REQUIRE(XML::getBoolProperty(node, "value", true) == true);
+ REQUIRE(XML::getBoolProperty(node, "value", false) == false);
+ REQUIRE(XML::getIntProperty(node, "value", -1, -10, 100) == 1);
+ }
+
+ SECTION("child1")
+ {
+ XML::Document doc("graphics/gui/browserbox.xml",
+ UseVirtFs_true,
+ SkipError_false);
+
+ XmlNodeConstPtr rootNode = doc.rootNode();
+ XmlNodePtr node = XML::findFirstChildByName(rootNode, "widget");
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "widget") == true);
+// REQUIRE(XmlHaveChildContent(node) == true);
+ node = XML::findFirstChildByName(node, "option");
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "option") == true);
+ REQUIRE(XmlHaveChildContent(node) == false);
+ REQUIRE(XmlHasProp(node, "name") == true);
+ REQUIRE(XmlHasProp(node, "value") == true);
+ REQUIRE(XmlHasProp(node, "option123") == false);
+ REQUIRE(XML::getProperty(node, "name", "") == "padding");
+ REQUIRE(XML::langProperty(node, "name", "") == "padding");
+ REQUIRE(XML::langProperty(node, "name123", "").empty());
+ REQUIRE(XML::getProperty(node, "value", 0) == 1);
+ REQUIRE(XML::getProperty(node, "value123", -1) == -1);
+ REQUIRE(XML::getBoolProperty(node, "value", true) == true);
+ REQUIRE(XML::getBoolProperty(node, "value", false) == false);
+ REQUIRE(XML::getBoolProperty(node, "value123", true) == true);
+ REQUIRE(XML::getIntProperty(node, "value", -1, -10, 100) == 1);
+ REQUIRE(XML::getIntProperty(node, "value123", -1, -10, 100) == -1);
+ }
+
+ SECTION("child2")
+ {
+ const char *const xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<root><data option1=\"false\" option2=\"true\" "
+ "option3=\"10.5\"/></root>";
+ XML::Document doc(xml, strlen(xml));
+ XmlNodeConstPtr rootNode = doc.rootNode();
+ REQUIRE(XmlHaveChildContent(rootNode) == false);
+ XmlNodePtr node = XML::findFirstChildByName(rootNode, "data");
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "data") == true);
+ REQUIRE(XmlHaveChildContent(node) == false);
+ REQUIRE(XmlHasProp(node, "option1") == true);
+ REQUIRE(XmlHasProp(node, "option123") == false);
+ REQUIRE(XML::getBoolProperty(node, "option1", true) == false);
+ REQUIRE(XML::getBoolProperty(node, "option2", false) == true);
+ const float opt3 = XML::getFloatProperty(node, "option3", 0.0);
+ REQUIRE(opt3 > 10);
+ REQUIRE(opt3 < 11);
+ }
+
+ SECTION("child3")
+ {
+ const std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<!-- comment --><root><!-- comment -->"
+ "<data option1=\"false\" option2=\"true\" "
+ "option3=\"10.5\"/><!-- comment --></root>";
+ XML::Document doc(xml.c_str(), xml.size());
+ XmlNodeConstPtr rootNode = doc.rootNode();
+// REQUIRE(XmlHaveChildContent(rootNode) == true);
+ XmlNodePtr node = XML::findFirstChildByName(rootNode, "data");
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "data") == true);
+ REQUIRE(XmlHaveChildContent(node) == false);
+ REQUIRE(XmlHasProp(node, "option1") == true);
+ REQUIRE(XmlHasProp(node, "option123") == false);
+ REQUIRE(XML::getBoolProperty(node, "option1", true) == false);
+ REQUIRE(XML::getBoolProperty(node, "option2", false) == true);
+ const float opt3 = XML::getFloatProperty(node, "option3", 0.0);
+ REQUIRE(opt3 > 10);
+ REQUIRE(opt3 < 11);
+ }
+
+ SECTION("validate")
+ {
+// REQUIRE(XML::Document::validateXml(
+// "graphics/gui/browserbox.xml") == true);
+ REQUIRE(XML::Document::validateXml(
+ "graphics/gui/bubble.png") == false);
+ REQUIRE(XML::Document::validateXml(
+ "graphics/gui/testfile123.xml") == false);
+ }
+
+ SECTION("save1")
+ {
+ // clean
+ ::remove(tempXmlName);
+
+ // save
+ FILE *const testFile = fopen(tempXmlName, "w");
+ REQUIRE(testFile);
+ fclose(testFile);
+ XmlTextWriterPtr writer = XmlNewTextWriterFilename(
+ tempXmlName,
+ 0);
+ XmlTextWriterSetIndent(writer, 1);
+ XmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr);
+ XmlTextWriterStartRootElement(writer, "root");
+ XmlTextWriterEndDocument(writer);
+ XmlSaveTextWriterFilename(writer, tempXmlName);
+ XmlFreeTextWriter(writer);
+
+ // load
+ XML::Document doc(tempXmlName,
+ UseVirtFs_false,
+ SkipError_false);
+ REQUIRE(doc.isLoaded() == true);
+ REQUIRE(doc.isValid() == true);
+ REQUIRE(doc.rootNode() != nullptr);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "skinset123") == false);
+ REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
+// REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
+
+ // clean again
+ ::remove(tempXmlName);
+ }
+
+ SECTION("save2")
+ {
+ // clean
+ ::remove(tempXmlName);
+
+ // save
+ FILE *const testFile = fopen(tempXmlName, "w");
+ REQUIRE(testFile);
+ fclose(testFile);
+ XmlTextWriterPtr writer = XmlNewTextWriterFilename(
+ tempXmlName,
+ 0);
+ XmlTextWriterSetIndent(writer, 1);
+ XmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr);
+ XmlTextWriterStartRootElement(writer, "root");
+
+ XmlTextWriterStartElement(writer, "option");
+ XmlTextWriterWriteAttribute(writer, "name", "the name");
+ XmlTextWriterWriteAttribute(writer, "value", "the value");
+ XmlTextWriterEndElement(writer);
+
+ XmlTextWriterEndDocument(writer);
+ XmlSaveTextWriterFilename(writer, tempXmlName);
+ XmlFreeTextWriter(writer);
+
+ // load
+ XML::Document doc(tempXmlName,
+ UseVirtFs_false,
+ SkipError_false);
+ REQUIRE(doc.isLoaded() == true);
+ REQUIRE(doc.isValid() == true);
+ REQUIRE(doc.rootNode() != nullptr);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
+ REQUIRE(xmlNameEqual(doc.rootNode(), "skinset123") == false);
+ REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
+// REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
+ XmlNodePtr node = XML::findFirstChildByName(doc.rootNode(), "option");
+ REQUIRE(node != nullptr);
+ REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
+ REQUIRE(xmlNameEqual(node, "option") == true);
+ REQUIRE(XmlHaveChildContent(node) == false);
+ REQUIRE(XmlHasProp(node, "name") == true);
+ REQUIRE(XmlHasProp(node, "value") == true);
+ REQUIRE(XmlHasProp(node, "option123") == false);
+ REQUIRE(XML::getProperty(node, "name", "") == "the name");
+ REQUIRE(XML::getProperty(node, "value", "") == "the value");
+
+ // clean again
+ ::remove(tempXmlName);
+ }
+
+ delete2(theme);
+ delete2(client);
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("xml test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
diff --git a/src/unittests/utils/xmlutils_unittest.cc b/src/unittests/utils/xmlutils_unittest.cc
new file mode 100644
index 000000000..014730e95
--- /dev/null
+++ b/src/unittests/utils/xmlutils_unittest.cc
@@ -0,0 +1,203 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2014-2017 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "unittests/unittests.h"
+
+#include "client.h"
+#include "graphicsmanager.h"
+
+#include "being/actorsprite.h"
+
+#include "fs/virtfs/fs.h"
+
+#include "gui/gui.h"
+
+#include "utils/delete2.h"
+#include "utils/env.h"
+#include "utils/xmlutils.h"
+
+#include "render/sdlgraphics.h"
+
+#include "resources/resourcemanager/resourcemanager.h"
+
+#include "resources/sdlimagehelper.h"
+
+#include "debug.h"
+
+TEST_CASE("xmlutils leak test1", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}
+
+TEST_CASE("xmlutils readXmlIntVector 1", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ std::vector<int> arr;
+
+ readXmlIntVector("graphics/gui/browserbox.xml",
+ "skinset",
+ "widget",
+ "option",
+ "value",
+ arr,
+ SkipError_false);
+
+ REQUIRE(5 == arr.size());
+ REQUIRE(1 == arr[0]);
+ REQUIRE(15 == arr[1]);
+ REQUIRE(0 == arr[2]);
+ REQUIRE(1 == arr[3]);
+ REQUIRE(1 == arr[4]);
+ delete2(client);
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("xmlutils readXmlStringMap 1", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ std::map<std::string, std::string> arr;
+
+ readXmlStringMap("graphics/sprites/manaplus_emotes.xml",
+ "emotes",
+ "emote",
+ "sprite",
+ "name",
+ "variant",
+ arr,
+ SkipError_false);
+
+ REQUIRE(arr.size() == 27);
+ REQUIRE(arr["Kitty"] == "0");
+ REQUIRE(arr["xD"] == "1");
+ REQUIRE(arr["Metal"] == "26");
+ delete2(client);
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("xmlutils readXmlIntMap 1", "")
+{
+ setEnv("SDL_VIDEODRIVER", "dummy");
+
+ client = new Client;
+ XML::initXML();
+ logger = new Logger();
+ VirtFs::mountDirSilent("data", Append_false);
+ VirtFs::mountDirSilent("../data", Append_false);
+ VirtFs::mountDirSilent("data/test", Append_false);
+ VirtFs::mountDirSilent("../data/test", Append_false);
+
+ mainGraphics = new SDLGraphics;
+ imageHelper = new SDLImageHelper();
+#ifdef USE_SDL2
+ SDLImageHelper::setRenderer(graphicsManager.createRenderer(
+ graphicsManager.createWindow(640, 480, 0,
+ SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
+#else // USE_SDL2
+
+ graphicsManager.createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
+#endif // USE_SDL2
+
+ ActorSprite::load();
+
+ std::map<int32_t, int32_t> arr;
+
+ readXmlIntMap("testintmap.xml",
+ "tests",
+ "sub",
+ "item",
+ "id",
+ "val",
+ arr,
+ SkipError_false);
+
+ REQUIRE(arr.size() == 3);
+ REQUIRE(arr[1] == 2);
+ REQUIRE(arr[10] == 20);
+ REQUIRE(arr[3] == 0);
+ delete2(client);
+ ResourceManager::deleteInstance();
+ VirtFs::unmountDirSilent("data/test");
+ VirtFs::unmountDirSilent("../data/test");
+ VirtFs::unmountDirSilent("data");
+ VirtFs::unmountDirSilent("../data");
+ delete2(logger);
+// VirtFs::deinit();
+}
+
+TEST_CASE("xmlutils leak test2", "")
+{
+ logger = new Logger();
+ REQUIRE(gui == nullptr);
+ ResourceManager::cleanOrphans(true);
+ ResourceManager::deleteInstance();
+ delete2(logger);
+}