diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index f92f61bae8..6dcf7cb79a 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -86,3 +86,26 @@ set(LANGUAGEPACK_TEST_SOURCES add_executable(test_languagepack ${LANGUAGEPACK_TEST_SOURCES}) target_link_libraries(test_languagepack ${GTEST_LIBRARIES} dl z SDL2 SDL2_ttf ssl crypto) add_test(NAME languagepack COMMAND test_languagepack) + + +# LanguagePack test +set(INI_TEST_SOURCES + "IniWriterTest.cpp" + "IniReaderTest.cpp" + "../../src/openrct2/config/IniReader.cpp" + "../../src/openrct2/config/IniWriter.cpp" + "../../src/openrct2/core/Console.cpp" + "../../src/openrct2/core/Diagnostics.cpp" + "../../src/openrct2/core/Guard.cpp" + "../../src/openrct2/core/IStream.cpp" + "../../src/openrct2/core/MemoryStream.cpp" + "../../src/openrct2/core/String.cpp" + "../../src/openrct2/diagnostic.c" + "../../src/openrct2/localisation/format_codes.c" + "../../src/openrct2/localisation/utf8.c" + "../../src/openrct2/util/util.c" + "../../src/openrct2/Version.cpp" + ) +add_executable(test_ini ${INI_TEST_SOURCES}) +target_link_libraries(test_ini ${GTEST_LIBRARIES} dl z) +add_test(NAME ini COMMAND test_ini) diff --git a/test/tests/IniReaderTest.cpp b/test/tests/IniReaderTest.cpp new file mode 100644 index 0000000000..9a8d0740ca --- /dev/null +++ b/test/tests/IniReaderTest.cpp @@ -0,0 +1,66 @@ +#include +#include +#include "openrct2/config/ConfigEnum.hpp" +#include "openrct2/config/IniReader.hpp" +#include "openrct2/core/MemoryStream.h" +#include "openrct2/core/Util.hpp" + +class IniReaderTest : public testing::Test +{ +protected: + static const utf8 predefined[]; +}; + +static auto Enum_Currency = ConfigEnum({}); + +TEST_F(IniReaderTest, create_empty) +{ + MemoryStream * ms = new MemoryStream(0); + ASSERT_NE(ms, nullptr); + ASSERT_EQ(ms->CanRead(), true); + ASSERT_EQ(ms->CanWrite(), true); + IIniReader * ir = CreateIniReader(ms); + ASSERT_NE(ir, nullptr); + ASSERT_EQ(ir->GetBoolean("nobody", true), true); + ASSERT_EQ(ir->GetCString("expects", nullptr), nullptr); + ASSERT_EQ(ir->GetEnum("spanish", 12345, Enum_Currency), 12345); + ASSERT_EQ(ir->GetFloat("inquisition", 1.234f), 1.234f); + ASSERT_EQ(ir->GetSint32("universal_answer", 42), 42); + delete ir; + delete ms; +} + +TEST_F(IniReaderTest, read_prepared) +{ + MemoryStream * ms = new MemoryStream(predefined, 99); + ASSERT_NE(ms, nullptr); + ASSERT_EQ(ms->CanRead(), true); + ASSERT_EQ(ms->CanWrite(), false); + IIniReader * ir = CreateIniReader(ms); + ASSERT_NE(ir, nullptr); + ASSERT_EQ(ir->ReadSection("doesnt_exist"), false); + ASSERT_EQ(ir->ReadSection("bool"), true); + // name of section + ASSERT_EQ(ir->GetSint32("bool", 42), 42); + // value from different section + ASSERT_EQ(ir->GetSint32("one", 42), 42); + // existing value as different type + EXPECT_THROW(ir->GetSint32("boolval", 42), std::invalid_argument); + ASSERT_EQ(ir->GetBoolean("boolval", false), true); + // skip one section + ASSERT_EQ(ir->ReadSection("string"), true); + // values from different sections + ASSERT_EQ(ir->GetSint32("one", 42), 42); + ASSERT_EQ(ir->GetBoolean("boolval", false), true); + const utf8 * str = ir->GetCString("path", nullptr); + ASSERT_STREQ(str, u8"C:'\\some/dir\\here/神鷹暢遊"); + Memory::Free(str); + // go backa section + ASSERT_EQ(ir->ReadSection("int"), true); + ASSERT_EQ(ir->GetSint32("one", 42), 1); + delete ir; + delete ms; +} + +const utf8 IniReaderTest::predefined[] = "[bool]\nboolval = true\n\n[int]\none = 1\nzero = 0\n\n[string]\npath = " + "\"C:'\\\\some/dir\\\\here/\xE7\xA5\x9E\xE9\xB7\xB9\xE6\x9A\xA2\xE9\x81\x8A\"\n"; diff --git a/test/tests/IniWriterTest.cpp b/test/tests/IniWriterTest.cpp new file mode 100644 index 0000000000..b83a41a1f4 --- /dev/null +++ b/test/tests/IniWriterTest.cpp @@ -0,0 +1,193 @@ +#include +#include +#include "openrct2/config/ConfigEnum.hpp" +#include "openrct2/config/IniWriter.hpp" +#include "openrct2/core/MemoryStream.h" + +class IniWriterTest : public testing::Test +{ +}; + +static auto Enum_Currency = ConfigEnum({ + ConfigEnumEntry("GBP", 1), +}); + +TEST_F(IniWriterTest, create_empty) +{ + MemoryStream * ms = new MemoryStream(0); + ASSERT_NE(ms, nullptr); + ASSERT_EQ(ms->CanRead(), true); + ASSERT_EQ(ms->CanWrite(), true); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_one_section) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteSection("OpenRCT2"); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 12); + ASSERT_EQ(ms->GetLength(), 12); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "[OpenRCT2]\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_multiple_sections) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteSection("OpenRCT1"); + iw->WriteSection("OpenRCT2"); + iw->WriteSection("OpenRCT3"); + iw->WriteSection("OpenRCT4"); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 48); + ASSERT_EQ(ms->GetLength(), 48); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "[OpenRCT1]\n\n[OpenRCT2]\n\n[OpenRCT3]\n\n[OpenRCT4]\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_loose_bool_entry) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteBoolean("boolval", true); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 16); + ASSERT_EQ(ms->GetLength(), 16); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "boolval = true\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_loose_enum_entry) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteEnum("by_string", "stringval"); + iw->WriteEnum("sint32", 0, Enum_Currency); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 34); + ASSERT_EQ(ms->GetLength(), 34); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "by_string = stringval\nsint32 = 0\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_loose_float_entry) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteFloat("one", 1.); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 16); + ASSERT_EQ(ms->GetLength(), 16); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + // This will be non-fatal due to float. + EXPECT_STREQ(ini, "one = 1.000000\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_loose_sint32_entry) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteSint32("one", 1); + iw->WriteSint32("zero", 0); + iw->WriteSint32("minusone", -1); + iw->WriteSint32("intmin", std::numeric_limits::min()); + iw->WriteSint32("intmax", std::numeric_limits::max()); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 73); + ASSERT_EQ(ms->GetLength(), 73); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "one = 1\nzero = 0\nminusone = -1\nintmin = -2147483648\nintmax = 2147483647\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_loose_string_entry) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteString("path", u8"C:'\\some/dir\\here/神鷹暢遊"); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 43); + ASSERT_EQ(ms->GetLength(), 43); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "path = \"C:'\\\\some/dir\\\\here/\xE7\xA5\x9E\xE9\xB7\xB9\xE6\x9A\xA2\xE9\x81\x8A\"\n"); + Memory::Free(ini); + delete iw; + delete ms; +} + +TEST_F(IniWriterTest, create_multiple_section_with_values) +{ + MemoryStream * ms = new MemoryStream(1000); + ASSERT_NE(ms, nullptr); + IIniWriter * iw = CreateIniWriter(ms); + ASSERT_NE(iw, nullptr); + iw->WriteSection("bool"); + iw->WriteBoolean("boolval", true); + iw->WriteSection("int"); + iw->WriteSint32("one", 1); + iw->WriteSint32("zero", 0); + iw->WriteSection("string"); + iw->WriteString("path", u8"C:'\\some/dir\\here/神鷹暢遊"); + int8_t null_terminator = 0; + ms->Write(&null_terminator, 1); + ASSERT_EQ(ms->GetPosition(), 99); + ASSERT_EQ(ms->GetLength(), 99); + ms->SetPosition(0); + const char * ini = (const char *)ms->ReadString(); + ASSERT_STREQ(ini, "[bool]\nboolval = true\n\n[int]\none = 1\nzero = 0\n\n[string]\npath = " + "\"C:'\\\\some/dir\\\\here/\xE7\xA5\x9E\xE9\xB7\xB9\xE6\x9A\xA2\xE9\x81\x8A\"\n"); + Memory::Free(ini); + delete iw; + delete ms; +}