mirror of
https://github.com/EasyRPG/Player.git
synced 2026-10-25 15:57:14 +00:00
225 lines
5.0 KiB
C++
225 lines
5.0 KiB
C++
#include "doctest.h"
|
|
#include "json_helper.h"
|
|
#include <fstream>
|
|
|
|
#ifdef HAVE_NLOHMANN_JSON
|
|
|
|
#include <nlohmann/json_fwd.hpp>
|
|
|
|
TEST_SUITE_BEGIN("JSON");
|
|
|
|
json load(std::string_view file) {
|
|
std::ifstream is(EP_TEST_PATH "/json/" + std::string(file));
|
|
return json::parse(is, nullptr, false);
|
|
}
|
|
|
|
TEST_CASE("Get Value") {
|
|
auto obj = load("obj.json");
|
|
auto get = [&](std::string_view path) {
|
|
return Json_Helper::GetValue(obj, path);
|
|
};
|
|
|
|
CHECK_EQ(get("/name"), "Aina");
|
|
CHECK_EQ(get("/level"), "5");
|
|
CHECK_EQ(get("/active"), "true");
|
|
CHECK_EQ(get("/atk"), "[1,5,10,30,20]");
|
|
CHECK_EQ(get("/skills/0"), R"({"name":"Sword","atk":10})");
|
|
|
|
CHECK_EQ(get("/missing"), "");
|
|
CHECK_EQ(get("/atk/missing"), "");
|
|
CHECK_EQ(get("/atk/42"), "");
|
|
|
|
obj = load("list.json");
|
|
CHECK_EQ(get("/0"), "1");
|
|
CHECK_EQ(get("/2/name"), "Aina");
|
|
}
|
|
|
|
TEST_CASE("Set Value") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto get = [&](std::string_view path) {
|
|
return Json_Helper::GetValue(obj, path);
|
|
};
|
|
|
|
auto set = [&](std::string_view path, std::string_view value) {
|
|
Json_Helper::SetValue(obj, path, value);
|
|
CHECK_EQ(get(path), value);
|
|
};
|
|
|
|
set("/name", "Easy");
|
|
set("/level", "A");
|
|
set("/active", "false");
|
|
|
|
set("/atk/0", "3");
|
|
CHECK_EQ(get("/atk"), "[3,5,10,30,20]");
|
|
|
|
set("/missing", "1");
|
|
set("/atk/6", "50");
|
|
CHECK_EQ(get("/atk"), "[3,5,10,30,20,null,50]");
|
|
|
|
set("/obj", R"({"key":"value"})");
|
|
CHECK_EQ(get("/obj/key"), "value");
|
|
}
|
|
|
|
TEST_CASE("Get Length") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto len = [&](std::string_view path) {
|
|
return Json_Helper::GetLength(obj, path);
|
|
};
|
|
|
|
CHECK_EQ(len("/name"), 0);
|
|
CHECK_EQ(len("/atk"), 5);
|
|
CHECK_EQ(len("/skills"), 2);
|
|
CHECK_EQ(len("/missing"), 0);
|
|
}
|
|
|
|
TEST_CASE("Get Keys") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto keys = [&](std::string_view path) {
|
|
return Json_Helper::GetKeys(obj, path);
|
|
};
|
|
|
|
CHECK_EQ(keys("/name"), std::vector<std::string>());
|
|
CHECK_EQ(keys("/atk"), std::vector<std::string>{"0", "1", "2", "3", "4"});
|
|
CHECK_EQ(keys("/skills/0"), std::vector<std::string>{"name", "atk"});
|
|
CHECK_EQ(keys("/missing"), std::vector<std::string>());
|
|
}
|
|
|
|
TEST_CASE("Get Type") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto check = [&](std::string_view path) {
|
|
return Json_Helper::GetType(obj, path);
|
|
};
|
|
|
|
CHECK_EQ(check("/name"), "string");
|
|
CHECK_EQ(check("/atk"), "array");
|
|
CHECK_EQ(check("/active"), "boolean");
|
|
CHECK_EQ(check("/level"), "number");
|
|
CHECK_EQ(check("/skills/0"), "object");
|
|
CHECK_EQ(check("/class"), "null");
|
|
CHECK_EQ(check("/missing"), "");
|
|
}
|
|
|
|
TEST_CASE("Get Path") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto path = [&](std::string_view path) {
|
|
return Json_Helper::GetPath(obj, path);
|
|
};
|
|
|
|
// Function isn't fully implemented yet and not used by the Player
|
|
CHECK_EQ(path("Aina"), "/name");
|
|
//CHECK_EQ(path("5"), "/level");
|
|
//CHECK_EQ(path("10"), "/atk/1");
|
|
CHECK_EQ(path("Sword"), "/skills/0/name");
|
|
|
|
CHECK_EQ(Json_Helper::GetPath(obj, "/missing"), "");
|
|
}
|
|
|
|
TEST_CASE("Remove Root Element") {
|
|
// Clears the object
|
|
auto obj = load("obj.json");
|
|
Json_Helper::RemoveValue(obj, "/");
|
|
CHECK_EQ(obj.dump(), "{}");
|
|
}
|
|
|
|
TEST_CASE("Remove Value") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto remove = [&](std::string_view path) {
|
|
Json_Helper::RemoveValue(obj, path);
|
|
};
|
|
|
|
// Test removing a top-level key
|
|
{
|
|
auto orig = obj;
|
|
remove("/name");
|
|
orig.erase("name");
|
|
CHECK_EQ(obj.dump(), orig.dump());
|
|
}
|
|
|
|
// Test removing an element from an array
|
|
{
|
|
auto orig = obj;
|
|
remove("/atk/1");
|
|
orig["atk"].erase(1);
|
|
CHECK_EQ(obj.dump(), orig.dump());
|
|
}
|
|
|
|
// Test removing a key from a nested object
|
|
{
|
|
auto orig = obj;
|
|
remove("/skills/0/name");
|
|
orig["skills"][0].erase("name");
|
|
CHECK_EQ(obj.dump(), orig.dump());
|
|
}
|
|
|
|
// Test that removing a non-existent path does nothing
|
|
{
|
|
auto orig = obj;
|
|
Json_Helper::RemoveValue(obj, "/missing_path");
|
|
CHECK_EQ(obj.dump(), orig.dump());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Push Value") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto push = [&](std::string_view path, std::string_view value) {
|
|
Json_Helper::PushValue(obj, path, value);
|
|
};
|
|
|
|
auto orig = obj.dump();
|
|
push("/name", "Easy");
|
|
CHECK_EQ(orig, obj.dump());
|
|
|
|
push("/atk", "3");
|
|
CHECK_EQ(obj["atk"], std::vector<json>{1, 5, 10, 30, 20, 3});
|
|
}
|
|
|
|
TEST_CASE("Pop Value") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto pop = [&](std::string_view path, bool success = true) {
|
|
auto [json_obj, element] = Json_Helper::PopValue(obj, path);
|
|
|
|
CHECK_EQ(!json_obj.empty(), success);
|
|
|
|
return element;
|
|
};
|
|
|
|
CHECK_EQ(pop("/atk"), "20");
|
|
CHECK_EQ(pop("/atk"), "30");
|
|
CHECK_EQ(pop("/atk"), "10");
|
|
CHECK_EQ(pop("/atk"), "5");
|
|
CHECK_EQ(pop("/atk"), "1");
|
|
CHECK_EQ(pop("/atk", false), "");
|
|
|
|
CHECK_EQ(pop("/skills"), R"({"name":"Fireball","atk":20})");
|
|
|
|
CHECK_EQ(pop("/name", false), "");
|
|
CHECK_EQ(pop("/missing", false), "");
|
|
}
|
|
|
|
TEST_CASE("Contains") {
|
|
auto obj = load("obj.json");
|
|
|
|
auto check = [&](std::string_view path) {
|
|
return Json_Helper::Contains(obj, path);
|
|
};
|
|
|
|
CHECK_EQ(check("/"), true);
|
|
CHECK_EQ(check("/name"), true);
|
|
CHECK_EQ(check("/atk"), true);
|
|
CHECK_EQ(check("/skills/0"), true);
|
|
CHECK_EQ(check("/skills/2"), false);
|
|
CHECK_EQ(check("/missing"), false);
|
|
}
|
|
|
|
TEST_SUITE_END();
|
|
|
|
#endif
|