1#ifndef YAZE_APP_TEST_ZSCUSTOMOVERWORLD_TEST_SUITE_H
2#define YAZE_APP_TEST_ZSCUSTOMOVERWORLD_TEST_SUITE_H
7#include "absl/strings/str_format.h"
30 std::string
GetName()
const override {
return "ZSCustomOverworld Upgrade Tests"; }
37 if (!current_rom || !current_rom->
is_loaded()) {
38 AddSkippedTest(results,
"ROM_Availability_Check",
"No ROM loaded");
39 return absl::OkStatus();
70 return absl::OkStatus();
76 ImGui::Text(
"%s ZSCustomOverworld Test Configuration",
ICON_MD_UPGRADE);
78 if (current_rom && current_rom->
is_loaded()) {
79 ImGui::TextColored(ImVec4(0.0F, 1.0F, 0.0F, 1.0F),
83 auto version_byte = current_rom->
ReadByte(0x140145);
84 if (version_byte.ok()) {
85 std::string version_name =
"Unknown";
86 if (*version_byte == 0xFF) version_name =
"Vanilla";
87 else if (*version_byte == 0x02) version_name =
"v2";
88 else if (*version_byte == 0x03) version_name =
"v3";
90 ImGui::Text(
"Current ZSCustomOverworld version: %s (0x%02X)",
91 version_name.c_str(), *version_byte);
94 ImGui::TextColored(ImVec4(1.0F, 0.5F, 0.0F, 1.0F),
106 if (ImGui::CollapsingHeader(
"Version Settings")) {
107 ImGui::Text(
"Version-specific addresses and features:");
108 ImGui::Text(
"Vanilla: 0x140145 = 0xFF");
109 ImGui::Text(
"v2: 0x140145 = 0x02, main palettes enabled");
110 ImGui::Text(
"v3: 0x140145 = 0x03, all features enabled");
118 {
"version_flag", {0x140145, 0xFF}},
119 {
"message_ids", {0x3F51D, 0x00}},
120 {
"area_graphics", {0x7C9C, 0x00}},
121 {
"area_palettes", {0x7D1C, 0x00}},
126 {
"version_flag", {0x140145, 0x02}},
127 {
"message_ids", {0x1417F8, 0x00}},
128 {
"area_graphics", {0x7C9C, 0x00}},
129 {
"area_palettes", {0x7D1C, 0x00}},
130 {
"main_palettes", {0x140160, 0x00}},
135 {
"version_flag", {0x140145, 0x03}},
136 {
"message_ids", {0x1417F8, 0x00}},
137 {
"area_graphics", {0x7C9C, 0x00}},
138 {
"area_palettes", {0x7D1C, 0x00}},
139 {
"main_palettes", {0x140160, 0x00}},
140 {
"bg_colors", {0x140000, 0x00}},
141 {
"subscreen_overlays", {0x140340, 0x00}},
142 {
"animated_gfx", {0x1402A0, 0x00}},
143 {
"custom_tiles", {0x140480, 0x00}},
149 result.
name = test_name;
154 result.
duration = std::chrono::milliseconds{0};
155 result.
timestamp = std::chrono::steady_clock::now();
161 if (version ==
"v2") {
163 }
else if (version ==
"v3") {
168 for (
const auto& [key, value] : *data) {
173 if (version ==
"v2") {
176 }
else if (version ==
"v3") {
186 return absl::OkStatus();
191 if (version ==
"v2") {
193 }
else if (version ==
"v3") {
197 for (
const auto& [key, value] : *data) {
198 auto byte_value = rom.
ReadByte(value.first);
199 if (!byte_value.ok() || *byte_value != value.second) {
208 auto start_time = std::chrono::steady_clock::now();
211 result.
name =
"Vanilla_Baseline_Test";
219 auto test_status = test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
222 return absl::InternalError(
"Vanilla address validation failed");
226 auto version_byte = test_rom->
ReadByte(0x140145);
227 if (!version_byte.ok()) {
228 return absl::InternalError(
"Failed to read version flag");
231 if (*version_byte != 0xFF) {
232 return absl::InternalError(absl::StrFormat(
233 "Expected vanilla version flag (0xFF), got 0x%02X", *version_byte));
236 return absl::OkStatus();
239 if (test_status.ok()) {
241 result.
error_message =
"Vanilla baseline test passed - ROM is in vanilla state";
244 result.
error_message =
"Vanilla baseline test failed: " + test_status.ToString();
247 }
catch (
const std::exception& e) {
249 result.
error_message =
"Vanilla baseline test exception: " + std::string(e.what());
252 auto end_time = std::chrono::steady_clock::now();
253 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
254 end_time - start_time);
260 auto start_time = std::chrono::steady_clock::now();
263 result.
name =
"V2_Upgrade_Test";
271 auto test_status = test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
277 return absl::InternalError(
"v2 address validation failed");
281 auto version_byte = test_rom->
ReadByte(0x140145);
282 if (!version_byte.ok()) {
283 return absl::InternalError(
"Failed to read version flag");
286 if (*version_byte != 0x02) {
287 return absl::InternalError(absl::StrFormat(
288 "Expected v2 version flag (0x02), got 0x%02X", *version_byte));
291 return absl::OkStatus();
294 if (test_status.ok()) {
296 result.
error_message =
"v2 upgrade test passed - ROM successfully upgraded to v2";
299 result.
error_message =
"v2 upgrade test failed: " + test_status.ToString();
302 }
catch (
const std::exception& e) {
304 result.
error_message =
"v2 upgrade test exception: " + std::string(e.what());
307 auto end_time = std::chrono::steady_clock::now();
308 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
309 end_time - start_time);
315 auto start_time = std::chrono::steady_clock::now();
318 result.
name =
"V3_Upgrade_Test";
326 auto test_status = test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
332 return absl::InternalError(
"v3 address validation failed");
336 auto version_byte = test_rom->
ReadByte(0x140145);
337 if (!version_byte.ok()) {
338 return absl::InternalError(
"Failed to read version flag");
341 if (*version_byte != 0x03) {
342 return absl::InternalError(absl::StrFormat(
343 "Expected v3 version flag (0x03), got 0x%02X", *version_byte));
346 return absl::OkStatus();
349 if (test_status.ok()) {
351 result.
error_message =
"v3 upgrade test passed - ROM successfully upgraded to v3";
354 result.
error_message =
"v3 upgrade test failed: " + test_status.ToString();
357 }
catch (
const std::exception& e) {
359 result.
error_message =
"v3 upgrade test exception: " + std::string(e.what());
362 auto end_time = std::chrono::steady_clock::now();
363 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
364 end_time - start_time);
370 auto start_time = std::chrono::steady_clock::now();
373 result.
name =
"Address_Validation_Test";
381 auto test_status = test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
384 return absl::InternalError(
"Vanilla address validation failed");
390 return absl::InternalError(
"v2 address validation failed");
396 return absl::InternalError(
"v3 address validation failed");
399 return absl::OkStatus();
402 if (test_status.ok()) {
404 result.
error_message =
"Address validation test passed - all version addresses valid";
407 result.
error_message =
"Address validation test failed: " + test_status.ToString();
410 }
catch (
const std::exception& e) {
412 result.
error_message =
"Address validation test exception: " + std::string(e.what());
415 auto end_time = std::chrono::steady_clock::now();
416 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
417 end_time - start_time);
423 auto start_time = std::chrono::steady_clock::now();
426 result.
name =
"Feature_Toggle_Test";
434 auto test_status = test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
439 auto main_palettes = test_rom->
ReadByte(0x140146);
440 auto area_bg = test_rom->
ReadByte(0x140147);
441 auto subscreen_overlay = test_rom->
ReadByte(0x140148);
442 auto animated_gfx = test_rom->
ReadByte(0x140149);
443 auto custom_tiles = test_rom->
ReadByte(0x14014A);
444 auto mosaic = test_rom->
ReadByte(0x14014B);
446 if (!main_palettes.ok() || !area_bg.ok() || !subscreen_overlay.ok() ||
447 !animated_gfx.ok() || !custom_tiles.ok() || !mosaic.ok()) {
448 return absl::InternalError(
"Failed to read feature flags");
451 if (*main_palettes != 0x01 || *area_bg != 0x01 || *subscreen_overlay != 0x01 ||
452 *animated_gfx != 0x01 || *custom_tiles != 0x01 || *mosaic != 0x01) {
453 return absl::InternalError(
"Feature flags not properly enabled");
461 auto disabled_area_bg = test_rom->
ReadByte(0x140147);
462 auto disabled_animated_gfx = test_rom->
ReadByte(0x140149);
464 if (!disabled_area_bg.ok() || !disabled_animated_gfx.ok()) {
465 return absl::InternalError(
"Failed to read disabled feature flags");
468 if (*disabled_area_bg != 0x00 || *disabled_animated_gfx != 0x00) {
469 return absl::InternalError(
"Feature flags not properly disabled");
472 return absl::OkStatus();
475 if (test_status.ok()) {
477 result.
error_message =
"Feature toggle test passed - features can be enabled/disabled";
480 result.
error_message =
"Feature toggle test failed: " + test_status.ToString();
483 }
catch (
const std::exception& e) {
485 result.
error_message =
"Feature toggle test exception: " + std::string(e.what());
488 auto end_time = std::chrono::steady_clock::now();
489 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
490 end_time - start_time);
496 auto start_time = std::chrono::steady_clock::now();
499 result.
name =
"Data_Integrity_Test";
507 auto test_status = test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
509 auto original_graphics = test_rom->
ReadByte(0x7C9C);
510 auto original_palette = test_rom->
ReadByte(0x7D1C);
511 auto original_sprite_set = test_rom->
ReadByte(0x7A41);
513 if (!original_graphics.ok() || !original_palette.ok() || !original_sprite_set.ok()) {
514 return absl::InternalError(
"Failed to read original data");
521 auto preserved_graphics = test_rom->
ReadByte(0x7C9C);
522 auto preserved_palette = test_rom->
ReadByte(0x7D1C);
523 auto preserved_sprite_set = test_rom->
ReadByte(0x7A41);
525 if (!preserved_graphics.ok() || !preserved_palette.ok() || !preserved_sprite_set.ok()) {
526 return absl::InternalError(
"Failed to read preserved data");
529 if (*preserved_graphics != *original_graphics ||
530 *preserved_palette != *original_palette ||
531 *preserved_sprite_set != *original_sprite_set) {
532 return absl::InternalError(
"Original data not preserved during upgrade");
536 auto bg_colors = test_rom->
ReadByte(0x140000);
537 auto subscreen_overlays = test_rom->
ReadByte(0x140340);
538 auto animated_gfx = test_rom->
ReadByte(0x1402A0);
539 auto custom_tiles = test_rom->
ReadByte(0x140480);
541 if (!bg_colors.ok() || !subscreen_overlays.ok() ||
542 !animated_gfx.ok() || !custom_tiles.ok()) {
543 return absl::InternalError(
"Failed to read new v3 data");
546 if (*bg_colors != 0x00 || *subscreen_overlays != 0x00 ||
547 *animated_gfx != 0x00 || *custom_tiles != 0x00) {
548 return absl::InternalError(
"New v3 data not properly initialized");
551 return absl::OkStatus();
554 if (test_status.ok()) {
556 result.
error_message =
"Data integrity test passed - original data preserved, new data initialized";
559 result.
error_message =
"Data integrity test failed: " + test_status.ToString();
562 }
catch (
const std::exception& e) {
564 result.
error_message =
"Data integrity test exception: " + std::string(e.what());
567 auto end_time = std::chrono::steady_clock::now();
568 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
569 end_time - start_time);
584 std::map<std::string, std::pair<uint32_t, uint8_t>>
v2_data_;
585 std::map<std::string, std::pair<uint32_t, uint8_t>>
v3_data_;
The Rom class is used to load, save, and modify Rom data.
absl::Status WriteByte(int addr, uint8_t value)
absl::StatusOr< uint8_t > ReadByte(int offset)
Rom * GetCurrentRom() const
static TestManager & Get()
ZSCustomOverworld upgrade testing suite.
void InitializeVersionData()
void RunDataIntegrityTest(TestResults &results, Rom *rom)
void RunAddressValidationTest(TestResults &results, Rom *rom)
void RunV2UpgradeTest(TestResults &results, Rom *rom)
void RunVanillaBaselineTest(TestResults &results, Rom *rom)
absl::Status ApplyVersionPatch(Rom &rom, const std::string &version)
std::map< std::string, std::pair< uint32_t, uint8_t > > v3_data_
bool test_data_integrity_
std::map< std::string, std::pair< uint32_t, uint8_t > > v2_data_
bool test_address_validation_
void RunFeatureToggleTest(TestResults &results, Rom *rom)
bool ValidateVersionAddresses(Rom &rom, const std::string &version)
TestCategory GetCategory() const override
bool test_feature_toggle_
void RunV3UpgradeTest(TestResults &results, Rom *rom)
std::map< std::string, std::pair< uint32_t, uint8_t > > vanilla_data_
void AddSkippedTest(TestResults &results, const std::string &test_name, const std::string &reason)
bool test_vanilla_baseline_
std::string GetName() const override
void DrawConfiguration() override
absl::Status RunTests(TestResults &results) override
~ZSCustomOverworldTestSuite() override=default
ZSCustomOverworldTestSuite()=default
#define ICON_MD_CHECK_CIRCLE
#define RETURN_IF_ERROR(expression)
Main namespace for the application.
std::chrono::milliseconds duration
std::string error_message
std::chrono::time_point< std::chrono::steady_clock > timestamp
void AddResult(const TestResult &result)