mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch: accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes they need. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
297 lines
10 KiB
C++
297 lines
10 KiB
C++
#include "LDFFormat.h"
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "Game.h"
|
|
#include "dCommonDependencies.h"
|
|
#include "Logger.h"
|
|
|
|
class LDFTests : public dCommonDependenciesTest {
|
|
protected:
|
|
void SetUp() override {
|
|
SetUpDependencies();
|
|
}
|
|
|
|
void TearDown() override {
|
|
TearDownDependencies();
|
|
}
|
|
};
|
|
|
|
typedef std::unique_ptr<LDFBaseData> LdfUniquePtr;
|
|
|
|
// Suite of tests for parsing LDF values
|
|
|
|
TEST_F(LDFTests, LDFUTF16Test) {
|
|
std::string testWord = "KEY=0:IAmA weird string with :::: and spac,./;'][\\es that I expect to be parsed correctly...; ";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_16);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ((static_cast<LDFData<std::u16string>*>(data.get()))->GetValue(), u"IAmA weird string with :::: and spac,./;'][\\es that I expect to be parsed correctly...; ");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFUTF16EmptyTest) {
|
|
std::string testWord = "KEY=0:";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_16);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::u16string>*>(data.get())->GetValue(), u"");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFUTF16ColonTest) {
|
|
std::string testWord = "KEY=0:::";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_16);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::u16string>*>(data.get())->GetValue(), u"::");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFUTF16EqualsTest) {
|
|
std::string testWord = "KEY=0:==";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_16);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::u16string>*>(data.get())->GetValue(), u"==");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFS32Test) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=1:-15"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_S32);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<int32_t>*>(data.get())->GetValue(), -15);
|
|
ASSERT_EQ(data->GetString(), "KEY=1:-15");
|
|
}
|
|
TEST_F(LDFTests, LDFU32Test) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=5:15"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_U32);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<uint32_t>*>(data.get())->GetValue(), 15);
|
|
ASSERT_EQ(data->GetString(), "KEY=5:15");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFU32TrueTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=5:true"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_U32);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<uint32_t>*>(data.get())->GetValue(), 1);
|
|
ASSERT_EQ(data->GetString(), "KEY=5:1");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFU32FalseTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=5:false"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_U32);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<uint32_t>*>(data.get())->GetValue(), 0);
|
|
ASSERT_EQ(data->GetString(), "KEY=5:0");
|
|
}
|
|
|
|
|
|
// Use find since floats and doubles generally have appended 0s
|
|
TEST_F(LDFTests, LDFFloatTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=3:15.5"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_FLOAT);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<float>*>(data.get())->GetValue(), 15.5f);
|
|
ASSERT_EQ(data->GetString().find("KEY=3:15.5"), 0);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFDoubleTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=4:15.5"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_DOUBLE);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<double>*>(data.get())->GetValue(), 15.5);
|
|
ASSERT_EQ(data->GetString().find("KEY=4:15.5"), 0);
|
|
}
|
|
|
|
|
|
TEST_F(LDFTests, LDFBoolTrueTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=7:true"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_BOOLEAN);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<bool>*>(data.get())->GetValue(), true);
|
|
ASSERT_EQ(data->GetString(), "KEY=7:1");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFBoolFalseTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=7:false"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_BOOLEAN);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<bool>*>(data.get())->GetValue(), false);
|
|
ASSERT_EQ(data->GetString(), "KEY=7:0");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFBoolIntTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=7:3"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_BOOLEAN);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<bool>*>(data.get())->GetValue(), true);
|
|
ASSERT_EQ(data->GetString(), "KEY=7:1");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFU64Test) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=8:15"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_U64);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<uint64_t>*>(data.get())->GetValue(), 15);
|
|
ASSERT_EQ(data->GetString(), "KEY=8:15");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFLWOOBJIDTest) {
|
|
LdfUniquePtr data(LDFBaseData::DataFromString("KEY=9:15"));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_OBJID);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<uint64_t>*>(data.get())->GetValue(), 15);
|
|
ASSERT_EQ(data->GetString(), "KEY=9:15");
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFUTF8Test) {
|
|
std::string testWord = "KEY=13:IAmA weird string with :::: and spac,./;'][\\es that I expect to be parsed correctly...; ";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_8);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::string>*>(data.get())->GetValue(), "IAmA weird string with :::: and spac,./;'][\\es that I expect to be parsed correctly...; ");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFUTF8EmptyTest) {
|
|
std::string testWord = "KEY=13:";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_8);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::string>*>(data.get())->GetValue(), "");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
TEST_F(LDFTests, LDFUTF8ColonsTest) {
|
|
std::string testWord = "KEY=13:::";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_8);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::string>*>(data.get())->GetValue(), "::");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
TEST_F(LDFTests, LDFUTF8EqualsTest) {
|
|
std::string testWord = "KEY=13:==";
|
|
LdfUniquePtr data(LDFBaseData::DataFromString(testWord));
|
|
ASSERT_NE(data, nullptr);
|
|
ASSERT_EQ(data->GetValueType(), eLDFType::LDF_TYPE_UTF_8);
|
|
ASSERT_EQ(data->GetKey(), u"KEY");
|
|
ASSERT_EQ(static_cast<LDFData<std::string>*>(data.get())->GetValue(), "==");
|
|
ASSERT_EQ(data->GetString(), testWord);
|
|
}
|
|
|
|
|
|
TEST_F(LDFTests, LDFParseEdgeCaseTest) {
|
|
std::vector<std::string> tests = {
|
|
// Test undefined data
|
|
"", // Empty
|
|
"=", // Only equals sign
|
|
":", // Only colon
|
|
"=:", // Only colon and equals sign
|
|
|
|
// Test no LDFType
|
|
"KEY=:", // No LDF Type
|
|
"KEY=:44", // No LDF Type, but has value
|
|
|
|
// Test invalid values, but valid types
|
|
"key=1:", // no value for int32
|
|
"key=1:banana", // invalid value for int32
|
|
"key=3:", // No value for float
|
|
"key=3:banana", // invalid for float
|
|
"key=4:", // No value for double
|
|
"key=4:banana", // invalid for double
|
|
"key=5:", // No value for U32
|
|
"key=5:banana", // invalid for U32
|
|
"key=7:", // No value for bool
|
|
"key=7:banana", // invalid for bool
|
|
"key=8:", // No value for U64
|
|
"key=8:banana", // invalid for U64
|
|
"key=9:", // No value for LWOOBJID
|
|
"key=9:banana", // invalid for LWOOBJID
|
|
|
|
// Test invalid LDF types
|
|
"key=14:value", // invalid LDF type
|
|
"key=-1:value", // invalid LDF type
|
|
"key=-2:value", // invalid LDF type (no enum definition)
|
|
"key=Garbage:value", // invalid LDF type
|
|
};
|
|
for (auto testString : tests) {
|
|
LOG("Testing LDF Parsing of invalid string (%s)", testString.c_str());
|
|
EXPECT_NO_THROW(LDFBaseData::DataFromString(testString));
|
|
}
|
|
}
|
|
|
|
#ifdef PERF_TEST
|
|
|
|
TEST_F(LDFTests, LDFSpeedTest) {
|
|
std::string keyToTest = "KEY=0:IAmA weird string with :::: and s";
|
|
for (int i = 0; i < 10000; i++) LDFBaseData::DataFromString(keyToTest);
|
|
}
|
|
|
|
#endif //PERF
|
|
|
|
TEST_F(LDFTests, LwoNameValueLinesRoundTrip) {
|
|
LwoNameValue config;
|
|
config.Insert<int32_t>("modelType", 2);
|
|
config.Insert<LWOOBJID>("userModelID", 1152921510436607007);
|
|
config.Insert<std::u16string>("userModelName", u"My House: v2");
|
|
config.Insert<bool>("userModelHasBhvr", true);
|
|
|
|
LwoNameValue parsed;
|
|
parsed.InsertLines(config.ToLines());
|
|
ASSERT_EQ(parsed.values.size(), 4);
|
|
for (const auto& [key, value] : config.values) {
|
|
const auto it = parsed.find(key);
|
|
ASSERT_NE(it, parsed.end());
|
|
EXPECT_EQ(it->second->GetString(), value->GetString());
|
|
}
|
|
}
|
|
|
|
TEST_F(LDFTests, LwoNameValueLinesSkipsBadLines) {
|
|
LwoNameValue parsed;
|
|
parsed.InsertLines("\nnot an ldf line\ncount=1:5\n");
|
|
ASSERT_EQ(parsed.values.size(), 1);
|
|
EXPECT_NE(parsed.find(u"count"), parsed.end());
|
|
EXPECT_TRUE(LwoNameValue{}.ToLines().empty());
|
|
}
|
|
|
|
TEST_F(LDFTests, LwoNameValueLinesKeepNewlinesAndBackslashes) {
|
|
LwoNameValue config;
|
|
config.Insert<std::u16string>("userModelDesc", u"Line one\nLine two");
|
|
config.Insert<std::string>("path", "scripts\\02_server\\thing.lua");
|
|
config.Insert<std::u16string>("tricky", u"ends with a backslash\\");
|
|
|
|
const auto lines = config.ToLines();
|
|
EXPECT_EQ(std::count(lines.begin(), lines.end(), '\n'), 2); // one line per value
|
|
|
|
LwoNameValue parsed;
|
|
parsed.InsertLines(lines);
|
|
ASSERT_EQ(parsed.values.size(), 3);
|
|
for (const auto& [key, value] : config.values) {
|
|
const auto it = parsed.find(key);
|
|
ASSERT_NE(it, parsed.end());
|
|
EXPECT_EQ(it->second->GetString(), value->GetString());
|
|
}
|
|
}
|