mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-08 01:53:52 +00:00
test(extract): lock in DBC→JSON emission round-trip
4 tests covering the open_format_emitter:
- emitJsonFromDbc round-trips a hand-built 2-record DBC through
DBCFile::load (which auto-detects JSON via the '{' prefix) and
recovers identical record/field/value data.
- Missing input file → graceful failure (no JSON written).
- Bad DBC magic → graceful failure.
- emitOpenFormats walks a subdirectory and writes the side-file
in the right place (matches the extractor's recursive walk).
Brings ctest target count to 31.
This commit is contained in:
parent
d4c69a2b46
commit
6872ba2bcb
2 changed files with 135 additions and 0 deletions
|
|
@ -414,6 +414,33 @@ target_link_libraries(test_open_formats PRIVATE catch2_main)
|
|||
add_test(NAME open_formats COMMAND test_open_formats)
|
||||
register_test_target(test_open_formats)
|
||||
|
||||
# ── test_open_format_emitter ─────────────────────────────────
|
||||
# Locks in the asset_extract → wowee open-format conversion path.
|
||||
add_executable(test_open_format_emitter
|
||||
test_open_format_emitter.cpp
|
||||
${CMAKE_SOURCE_DIR}/tools/asset_extract/open_format_emitter.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/dbc_loader.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/blp_loader.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/m2_loader.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/wmo_loader.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/adt_loader.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/wowee_model.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/wowee_building.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/pipeline/wowee_collision.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/core/logger.cpp
|
||||
)
|
||||
target_include_directories(test_open_format_emitter PRIVATE
|
||||
${TEST_INCLUDE_DIRS}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
target_include_directories(test_open_format_emitter SYSTEM PRIVATE
|
||||
${TEST_SYSTEM_INCLUDE_DIRS}
|
||||
${CMAKE_SOURCE_DIR}/extern/nlohmann
|
||||
)
|
||||
target_link_libraries(test_open_format_emitter PRIVATE catch2_main)
|
||||
add_test(NAME open_format_emitter COMMAND test_open_format_emitter)
|
||||
register_test_target(test_open_format_emitter)
|
||||
|
||||
# ── test_camera ──────────────────────────────────────────────
|
||||
add_executable(test_camera
|
||||
test_camera.cpp
|
||||
|
|
|
|||
108
tests/test_open_format_emitter.cpp
Normal file
108
tests/test_open_format_emitter.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
// Tests for the asset_extract open-format emitter — verifies that the
|
||||
// MPQ→loose-files pipeline produces wowee-readable side-files for the
|
||||
// most common file types without touching the originals.
|
||||
#include <catch_amalgamated.hpp>
|
||||
#include "tools/asset_extract/open_format_emitter.hpp"
|
||||
#include "pipeline/dbc_loader.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
using namespace wowee::tools;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
static const std::string TEST_DIR = "test_emitter_out";
|
||||
|
||||
static void cleanup() { fs::remove_all(TEST_DIR); }
|
||||
|
||||
TEST_CASE("emitJsonFromDbc produces wowee-DBC-loadable JSON", "[emitter]") {
|
||||
fs::create_directories(TEST_DIR);
|
||||
std::string dbcPath = TEST_DIR + "/sample.dbc";
|
||||
std::string jsonPath = TEST_DIR + "/sample.json";
|
||||
|
||||
// Hand-build a 2-record DBC (3 fields each, no string block) so the
|
||||
// round trip is small and deterministic.
|
||||
{
|
||||
std::ofstream f(dbcPath, std::ios::binary);
|
||||
const char magic[4] = {'W','D','B','C'};
|
||||
f.write(magic, 4);
|
||||
uint32_t recordCount = 2, fieldCount = 3, recordSize = 12, stringBlockSize = 1;
|
||||
f.write(reinterpret_cast<const char*>(&recordCount), 4);
|
||||
f.write(reinterpret_cast<const char*>(&fieldCount), 4);
|
||||
f.write(reinterpret_cast<const char*>(&recordSize), 4);
|
||||
f.write(reinterpret_cast<const char*>(&stringBlockSize), 4);
|
||||
// 2 records of 3 uint32s
|
||||
uint32_t rec[6] = {1, 100, 200,
|
||||
2, 300, 400};
|
||||
f.write(reinterpret_cast<const char*>(rec), sizeof(rec));
|
||||
char nul = 0;
|
||||
f.write(&nul, 1);
|
||||
}
|
||||
|
||||
REQUIRE(emitJsonFromDbc(dbcPath, jsonPath));
|
||||
REQUIRE(fs::exists(jsonPath));
|
||||
|
||||
// The JSON should round-trip back through DBCFile::loadJSON.
|
||||
std::ifstream in(jsonPath, std::ios::binary | std::ios::ate);
|
||||
auto sz = in.tellg();
|
||||
std::vector<uint8_t> bytes(static_cast<size_t>(sz));
|
||||
in.seekg(0);
|
||||
in.read(reinterpret_cast<char*>(bytes.data()), sz);
|
||||
|
||||
wowee::pipeline::DBCFile dbc;
|
||||
// Public DBCFile::load detects '{' prefix and dispatches to loadJSON.
|
||||
REQUIRE(dbc.load(bytes));
|
||||
REQUIRE(dbc.getRecordCount() == 2);
|
||||
REQUIRE(dbc.getFieldCount() == 3);
|
||||
REQUIRE(dbc.getUInt32(0, 0) == 1);
|
||||
REQUIRE(dbc.getUInt32(0, 1) == 100);
|
||||
REQUIRE(dbc.getUInt32(1, 2) == 400);
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
TEST_CASE("emitJsonFromDbc fails gracefully on missing input", "[emitter]") {
|
||||
REQUIRE_FALSE(emitJsonFromDbc("does_not_exist.dbc", "should_not_be_written.json"));
|
||||
REQUIRE_FALSE(fs::exists("should_not_be_written.json"));
|
||||
}
|
||||
|
||||
TEST_CASE("emitJsonFromDbc fails gracefully on bad magic", "[emitter]") {
|
||||
fs::create_directories(TEST_DIR);
|
||||
std::string dbcPath = TEST_DIR + "/bad.dbc";
|
||||
std::string jsonPath = TEST_DIR + "/bad.json";
|
||||
{
|
||||
std::ofstream f(dbcPath, std::ios::binary);
|
||||
const char junk[20] = {'F','A','I','L', 0};
|
||||
f.write(junk, 20);
|
||||
}
|
||||
REQUIRE_FALSE(emitJsonFromDbc(dbcPath, jsonPath));
|
||||
cleanup();
|
||||
}
|
||||
|
||||
TEST_CASE("emitOpenFormats walks a directory and writes side-files", "[emitter]") {
|
||||
fs::create_directories(TEST_DIR + "/sub");
|
||||
// One DBC in a subdir
|
||||
{
|
||||
std::ofstream f(TEST_DIR + "/sub/test.dbc", std::ios::binary);
|
||||
const char magic[4] = {'W','D','B','C'};
|
||||
f.write(magic, 4);
|
||||
uint32_t r = 1, fc = 1, rs = 4, sb = 1;
|
||||
f.write(reinterpret_cast<const char*>(&r), 4);
|
||||
f.write(reinterpret_cast<const char*>(&fc), 4);
|
||||
f.write(reinterpret_cast<const char*>(&rs), 4);
|
||||
f.write(reinterpret_cast<const char*>(&sb), 4);
|
||||
uint32_t v = 42;
|
||||
f.write(reinterpret_cast<const char*>(&v), 4);
|
||||
char nul = 0;
|
||||
f.write(&nul, 1);
|
||||
}
|
||||
OpenFormatStats stats;
|
||||
emitOpenFormats(TEST_DIR, /*png*/ false, /*json*/ true,
|
||||
/*wom*/ false, /*wob*/ false, /*terrain*/ false, stats);
|
||||
REQUIRE(stats.jsonDbcOk == 1);
|
||||
REQUIRE(stats.jsonDbcFail == 0);
|
||||
REQUIRE(fs::exists(TEST_DIR + "/sub/test.json"));
|
||||
cleanup();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue