From bca5fd3f1a16be40922db8b566f8f0776248b072 Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Wed, 23 Jul 2025 22:52:26 +0100 Subject: [PATCH] chore: add tests for font icon json writing and loading --- .../T6/FontIcon/JsonLoaderFontIconT6Test.cpp | 156 +++++++++++++++++ .../T6/FontIcon/DumperFontIconJsonT6Test.cpp | 159 ++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 test/ObjLoadingTests/Game/T6/FontIcon/JsonLoaderFontIconT6Test.cpp create mode 100644 test/ObjWritingTests/Game/T6/FontIcon/DumperFontIconJsonT6Test.cpp diff --git a/test/ObjLoadingTests/Game/T6/FontIcon/JsonLoaderFontIconT6Test.cpp b/test/ObjLoadingTests/Game/T6/FontIcon/JsonLoaderFontIconT6Test.cpp new file mode 100644 index 00000000..f99d761f --- /dev/null +++ b/test/ObjLoadingTests/Game/T6/FontIcon/JsonLoaderFontIconT6Test.cpp @@ -0,0 +1,156 @@ +#include "Game/T6/FontIcon/JsonLoaderFontIconT6.h" + +#include "Game/T6/CommonT6.h" +#include "Game/T6/GameT6.h" +#include "SearchPath/MockSearchPath.h" +#include "Utils/MemoryManager.h" + +#include +#include +#include + +using namespace T6; +using namespace Catch; +using namespace std::literals; + +namespace +{ + void GivenMaterial(const std::string& name, AssetCreationContext& context, MemoryManager& memory) + { + auto* material = memory.Alloc(); + material->info.name = memory.Dup(name.c_str()); + + AssetRegistration registration(name); + registration.SetAsset(material); + context.AddAsset(std::move(registration)); + } + + TEST_CASE("JsonLoaderFontIcon(T6): Can parse font icon", "[t6][font-icon][assetloader]") + { + MockSearchPath searchPath; + searchPath.AddFileData("fonticon/test.json", + R"FONT_ICON( +{ + "$schema": "http://openassettools.dev/schema/font-icon.v1.json", + "_game": "t6", + "_type": "font-icon", + "_version": 1, + "entries": [ + { + "aliases": [ + "BUTTON_LUI_DPAD_ALL" + ], + "material": "xenonbutton_dpad_all", + "name": "XenonButtondpadAll", + "scale": { + "x": 1.0, + "y": 1.0 + }, + "size": 32 + }, + { + "aliasHashes": [ + 3463582170 + ], + "aliases": [], + "material": "ui_button_xenon_lstick_anim_d", + "name": "XenonButtonLStickAnimatedD", + "scale": { + "x": 1.5, + "y": 1.5 + }, + "size": 32 + }, + { + "aliases": [ + "BUTTON_MOVE", + "BUTTON_EMBLEM_MOVE", + "BUTTON_LUI_LEFT_STICK_UP", + "BUTTON_MOVESTICK" + ], + "material": "xenonbutton_ls", + "name": "XenonButtonStickAnimatedL", + "scale": { + "x": 1.0, + "y": 1.0 + }, + "size": 32 + } + ] +})FONT_ICON"); + + Zone zone("MockZone", 0, IGame::GetGameById(GameId::T6)); + + MemoryManager memory; + AssetCreatorCollection creatorCollection(zone); + IgnoredAssetLookup ignoredAssetLookup; + AssetCreationContext context(zone, &creatorCollection, &ignoredAssetLookup); + + GivenMaterial("xenonbutton_dpad_all", context, memory); + GivenMaterial("ui_button_xenon_lstick_anim_d", context, memory); + GivenMaterial("xenonbutton_ls", context, memory); + + auto loader = CreateJsonFontIconLoader(memory, searchPath); + auto result = loader->CreateAsset("fonticon/test.csv", context); + REQUIRE(result.HasBeenSuccessful()); + + const auto* assetInfo = reinterpret_cast*>(result.GetAssetInfo()); + const auto* fontIcon = assetInfo->Asset(); + + REQUIRE(fontIcon->name == "fonticon/test.csv"s); + + REQUIRE(fontIcon->numEntries == 3); + REQUIRE(fontIcon->fontIconEntry != nullptr); + + const auto& entry0 = fontIcon->fontIconEntry[0]; + REQUIRE(entry0.fontIconName.string == "XenonButtondpadAll"s); + REQUIRE(entry0.fontIconName.hash == static_cast(0x9220177B)); + REQUIRE(entry0.fontIconMaterialHandle->info.name == "xenonbutton_dpad_all"s); + REQUIRE(entry0.fontIconSize == 32); + REQUIRE(entry0.xScale == 1.0f); + REQUIRE(entry0.yScale == 1.0f); + + const auto& entry1 = fontIcon->fontIconEntry[1]; + REQUIRE(entry1.fontIconName.string == "XenonButtonLStickAnimatedD"s); + REQUIRE(entry1.fontIconName.hash == static_cast(0x9E7D535A)); + REQUIRE(entry1.fontIconMaterialHandle->info.name == "ui_button_xenon_lstick_anim_d"s); + REQUIRE(entry1.fontIconSize == 32); + REQUIRE(entry1.xScale == 1.5f); + REQUIRE(entry1.yScale == 1.5f); + + const auto& entry2 = fontIcon->fontIconEntry[2]; + REQUIRE(entry2.fontIconName.string == "XenonButtonStickAnimatedL"s); + REQUIRE(entry2.fontIconName.hash == static_cast(0xABF58CD6)); + REQUIRE(entry2.fontIconMaterialHandle->info.name == "xenonbutton_ls"s); + REQUIRE(entry2.fontIconSize == 32); + REQUIRE(entry2.xScale == 1.0f); + REQUIRE(entry2.yScale == 1.0f); + + REQUIRE(fontIcon->numAliasEntries == 6); + REQUIRE(fontIcon->fontIconAlias != nullptr); + + auto& alias0 = fontIcon->fontIconAlias[0]; + REQUIRE(alias0.aliasHash == static_cast(0xCE7211DA)); + REQUIRE(alias0.buttonHash == entry1.fontIconName.hash); + + const auto& alias1 = fontIcon->fontIconAlias[1]; + REQUIRE(alias1.aliasHash == static_cast(0xDD3B363A)); + REQUIRE(alias1.buttonHash == entry0.fontIconName.hash); + + const auto& alias2 = fontIcon->fontIconAlias[2]; + REQUIRE(alias2.aliasHash == static_cast(0xFFFBB17)); + REQUIRE(alias2.buttonHash == entry2.fontIconName.hash); + + const auto& alias3 = fontIcon->fontIconAlias[3]; + REQUIRE(alias3.aliasHash == static_cast(0x1893B6A8)); + REQUIRE(alias3.buttonHash == entry2.fontIconName.hash); + + const auto& alias4 = fontIcon->fontIconAlias[4]; + REQUIRE(alias4.aliasHash == static_cast(0x18A33DB5)); + REQUIRE(alias4.buttonHash == entry2.fontIconName.hash); + + const auto& alias5 = fontIcon->fontIconAlias[5]; + REQUIRE(alias5.aliasHash == static_cast(0x5A15AB35)); + REQUIRE(alias5.buttonHash == entry2.fontIconName.hash); + } +} // namespace diff --git a/test/ObjWritingTests/Game/T6/FontIcon/DumperFontIconJsonT6Test.cpp b/test/ObjWritingTests/Game/T6/FontIcon/DumperFontIconJsonT6Test.cpp new file mode 100644 index 00000000..c8837e7b --- /dev/null +++ b/test/ObjWritingTests/Game/T6/FontIcon/DumperFontIconJsonT6Test.cpp @@ -0,0 +1,159 @@ +#include "Game/T6/FontIcon/DumperFontIconJsonT6.h" + +#include "Asset/AssetRegistration.h" +#include "Game/T6/CommonT6.h" +#include "Game/T6/GameT6.h" +#include "NormalizedJson.h" +#include "Pool/AssetPoolDynamic.h" +#include "SearchPath/MockOutputPath.h" +#include "SearchPath/MockSearchPath.h" +#include "Utils/MemoryManager.h" + +#include +#include +#include + +using namespace T6; +using namespace Catch; +using namespace std::literals; + +namespace +{ + Material* GivenMaterial(const std::string& name, MemoryManager& memory) + { + auto* material = memory.Alloc(); + material->info.name = memory.Dup(name.c_str()); + + return material; + } + + void GivenFontIcon(const std::string& name, FontIcon& fontIcon, MemoryManager& memory) + { + fontIcon.name = memory.Dup(name.c_str()); + + fontIcon.numEntries = 3; + fontIcon.fontIconEntry = memory.Alloc(fontIcon.numEntries); + + auto& entry0 = fontIcon.fontIconEntry[0]; + entry0.fontIconName.string = "XenonButtondpadAll"; + entry0.fontIconName.hash = Common::Com_HashString(entry0.fontIconName.string); + entry0.fontIconMaterialHandle = GivenMaterial("xenonbutton_dpad_all", memory); + entry0.fontIconSize = 32; + entry0.xScale = 1.0f; + entry0.yScale = 1.0f; + + auto& entry1 = fontIcon.fontIconEntry[1]; + entry1.fontIconName.string = "XenonButtonLStickAnimatedD"; + entry1.fontIconName.hash = Common::Com_HashString(entry1.fontIconName.string); + entry1.fontIconMaterialHandle = GivenMaterial("ui_button_xenon_lstick_anim_d", memory); + entry1.fontIconSize = 32; + entry1.xScale = 1.5f; + entry1.yScale = 1.5f; + + auto& entry2 = fontIcon.fontIconEntry[2]; + entry2.fontIconName.string = "XenonButtonStickAnimatedL"; + entry2.fontIconName.hash = Common::Com_HashString(entry2.fontIconName.string); + entry2.fontIconMaterialHandle = GivenMaterial("xenonbutton_ls", memory); + entry2.fontIconSize = 32; + entry2.xScale = 1.0f; + entry2.yScale = 1.0f; + + fontIcon.numAliasEntries = 6; + fontIcon.fontIconAlias = memory.Alloc(fontIcon.numAliasEntries); + + auto& alias0 = fontIcon.fontIconAlias[0]; + alias0.aliasHash = Common::Com_HashString("BUTTON_LUI_DPAD_ALL"); + alias0.buttonHash = entry0.fontIconName.hash; + + auto& alias1 = fontIcon.fontIconAlias[1]; + alias1.aliasHash = static_cast(0xCE7211DA); + alias1.buttonHash = entry1.fontIconName.hash; + + auto& alias2 = fontIcon.fontIconAlias[2]; + alias2.aliasHash = Common::Com_HashString("BUTTON_MOVE"); + alias2.buttonHash = entry2.fontIconName.hash; + + auto& alias3 = fontIcon.fontIconAlias[3]; + alias3.aliasHash = Common::Com_HashString("BUTTON_EMBLEM_MOVE"); + alias3.buttonHash = entry2.fontIconName.hash; + + auto& alias4 = fontIcon.fontIconAlias[4]; + alias4.aliasHash = Common::Com_HashString("BUTTON_LUI_LEFT_STICK_UP"); + alias4.buttonHash = entry2.fontIconName.hash; + + auto& alias5 = fontIcon.fontIconAlias[5]; + alias5.aliasHash = Common::Com_HashString("BUTTON_MOVESTICK"); + alias5.buttonHash = entry2.fontIconName.hash; + } + + TEST_CASE("DumperFontIconJson(T6): Can dump font icon", "[t6][font-icon][assetdumper]") + { + std::string expected(R"FONT_ICON( +{ + "$schema": "http://openassettools.dev/schema/font-icon.v1.json", + "_game": "t6", + "_type": "font-icon", + "_version": 1, + "entries": [ + { + "aliases": [ + "BUTTON_LUI_DPAD_ALL" + ], + "material": "xenonbutton_dpad_all", + "name": "XenonButtondpadAll", + "scale": { + "x": 1.0, + "y": 1.0 + }, + "size": 32 + }, + { + "aliasHashes": [ + 3463582170 + ], + "aliases": [], + "material": "ui_button_xenon_lstick_anim_d", + "name": "XenonButtonLStickAnimatedD", + "scale": { + "x": 1.5, + "y": 1.5 + }, + "size": 32 + }, + { + "aliases": [ + "BUTTON_MOVE", + "BUTTON_EMBLEM_MOVE", + "BUTTON_LUI_LEFT_STICK_UP", + "BUTTON_MOVESTICK" + ], + "material": "xenonbutton_ls", + "name": "XenonButtonStickAnimatedL", + "scale": { + "x": 1.0, + "y": 1.0 + }, + "size": 32 + } + ] +})FONT_ICON"); + + Zone zone("MockZone", 0, IGame::GetGameById(GameId::T6)); + + MemoryManager memory; + MockSearchPath mockObjPath; + MockOutputPath mockOutput; + AssetDumpingContext context(zone, "", mockOutput, mockObjPath); + + AssetPoolDynamic materialPool(0); + + FontIcon asset; + GivenFontIcon("fonticon/test.csv", asset, memory); + + DumpFontIconAsJson(context, asset); + + const auto* file = mockOutput.GetMockedFile("fonticon/test.json"); + REQUIRE(file); + REQUIRE(JsonNormalized(file->AsString()) == JsonNormalized(expected)); + } +} // namespace