Files
XCEngine/tests/Core/Asset/test_artifact_container.cpp

148 lines
4.9 KiB
C++

#include <gtest/gtest.h>
#include <XCEngine/Core/Asset/ArtifactContainer.h>
#include <filesystem>
#include <fstream>
using namespace XCEngine::Resources;
namespace Containers = XCEngine::Containers;
namespace Core = XCEngine::Core;
namespace {
void FillPayload(Containers::Array<Core::uint8>& payload,
std::initializer_list<Core::uint8> bytes) {
payload.Clear();
payload.Reserve(bytes.size());
for (const Core::uint8 value : bytes) {
payload.PushBack(value);
}
}
} // namespace
TEST(ArtifactContainer, WritesAndReadsMultipleEntries) {
namespace fs = std::filesystem;
const fs::path projectRoot = fs::temp_directory_path() / "xc_artifact_container_test";
fs::remove_all(projectRoot);
fs::create_directories(projectRoot);
ArtifactContainerWriter writer;
ArtifactContainerEntry mainEntry;
mainEntry.name = "main";
mainEntry.resourceType = ResourceType::Model;
mainEntry.localID = kMainAssetLocalID;
FillPayload(mainEntry.payload, { 1, 2, 3, 4 });
writer.AddEntry(mainEntry);
ArtifactContainerEntry meshEntry;
meshEntry.name = "mesh/0";
meshEntry.resourceType = ResourceType::Mesh;
meshEntry.localID = 42;
meshEntry.flags = 7;
FillPayload(meshEntry.payload, { 9, 8, 7 });
writer.AddEntry(std::move(meshEntry));
Containers::String errorMessage;
const fs::path artifactPath = projectRoot / "Library" / "Artifacts" / "ab" / "artifact.xca";
ASSERT_TRUE(writer.WriteToFile(artifactPath.string().c_str(), &errorMessage))
<< errorMessage.CStr();
ASSERT_TRUE(fs::exists(artifactPath));
ArtifactContainerReader reader;
ASSERT_TRUE(reader.Open(artifactPath.string().c_str(), &errorMessage))
<< errorMessage.CStr();
EXPECT_EQ(reader.GetEntryCount(), 2u);
const ArtifactContainerEntryView* mainView = reader.FindEntryByName("main");
ASSERT_NE(mainView, nullptr);
EXPECT_EQ(mainView->resourceType, ResourceType::Model);
EXPECT_EQ(mainView->localID, kMainAssetLocalID);
const ArtifactContainerEntryView* meshView = reader.FindEntry(ResourceType::Mesh, 42);
ASSERT_NE(meshView, nullptr);
EXPECT_EQ(meshView->name, Containers::String("mesh/0"));
EXPECT_EQ(meshView->flags, 7u);
Containers::Array<Core::uint8> payload;
ASSERT_TRUE(reader.ReadEntryPayload(*meshView, payload, &errorMessage))
<< errorMessage.CStr();
ASSERT_EQ(payload.Size(), 3u);
EXPECT_EQ(payload[0], 9u);
EXPECT_EQ(payload[1], 8u);
EXPECT_EQ(payload[2], 7u);
}
TEST(ArtifactContainer, RejectsCorruptFileHeader) {
namespace fs = std::filesystem;
const fs::path projectRoot = fs::temp_directory_path() / "xc_artifact_container_corrupt_test";
fs::remove_all(projectRoot);
fs::create_directories(projectRoot);
const fs::path artifactPath = projectRoot / "broken.xca";
{
std::ofstream output(artifactPath, std::ios::binary | std::ios::trunc);
output << "broken";
}
ArtifactContainerReader reader;
Containers::String errorMessage;
EXPECT_FALSE(reader.Open(artifactPath.string().c_str(), &errorMessage));
EXPECT_FALSE(errorMessage.Empty());
}
TEST(ArtifactContainer, ResolvesEntryVirtualPaths) {
namespace fs = std::filesystem;
const fs::path projectRoot = fs::temp_directory_path() / "xc_artifact_container_entry_path_test";
fs::remove_all(projectRoot);
fs::create_directories(projectRoot);
ArtifactContainerWriter writer;
ArtifactContainerEntry mainEntry;
mainEntry.name = "main";
mainEntry.resourceType = ResourceType::Model;
mainEntry.localID = kMainAssetLocalID;
FillPayload(mainEntry.payload, { 1, 2, 3 });
writer.AddEntry(mainEntry);
ArtifactContainerEntry meshEntry;
meshEntry.name = "mesh_0.xcmesh";
meshEntry.resourceType = ResourceType::Mesh;
meshEntry.localID = 77;
FillPayload(meshEntry.payload, { 5, 6, 7, 8 });
writer.AddEntry(meshEntry);
const Containers::String containerPath =
(projectRoot / "Library" / "Artifacts" / "ab" / "artifact.xcmodel").string().c_str();
Containers::String errorMessage;
ASSERT_TRUE(writer.WriteToFile(containerPath, &errorMessage))
<< errorMessage.CStr();
const Containers::String virtualPath =
BuildArtifactContainerEntryPath(containerPath, "mesh_0.xcmesh");
Containers::String parsedContainerPath;
Containers::String parsedEntryName;
ASSERT_TRUE(TryParseArtifactContainerEntryPath(
virtualPath,
parsedContainerPath,
parsedEntryName));
EXPECT_EQ(parsedContainerPath, containerPath);
EXPECT_EQ(parsedEntryName, "mesh_0.xcmesh");
Containers::Array<Core::uint8> payload;
ASSERT_TRUE(ReadArtifactContainerPayloadByPath(
virtualPath,
ResourceType::Mesh,
payload,
&errorMessage)) << errorMessage.CStr();
ASSERT_EQ(payload.Size(), 4u);
EXPECT_EQ(payload[0], 5u);
EXPECT_EQ(payload[3], 8u);
}