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"
31 return "ZSCustomOverworld Upgrade Tests";
41 if (!current_rom || !current_rom->
is_loaded()) {
42 AddSkippedTest(results,
"ROM_Availability_Check",
"No ROM loaded");
43 return absl::OkStatus();
74 return absl::OkStatus();
80 ImGui::Text(
"%s ZSCustomOverworld Test Configuration",
ICON_MD_UPGRADE);
82 if (current_rom && current_rom->
is_loaded()) {
83 ImGui::TextColored(ImVec4(0.0F, 1.0F, 0.0F, 1.0F),
"%s Current ROM: %s",
87 auto version_byte = current_rom->
ReadByte(0x140145);
88 if (version_byte.ok()) {
89 std::string version_name =
"Unknown";
90 if (*version_byte == 0xFF)
91 version_name =
"Vanilla";
92 else if (*version_byte == 0x02)
94 else if (*version_byte == 0x03)
97 ImGui::Text(
"Current ZSCustomOverworld version: %s (0x%02X)",
98 version_name.c_str(), *version_byte);
101 ImGui::TextColored(ImVec4(1.0F, 0.5F, 0.0F, 1.0F),
113 if (ImGui::CollapsingHeader(
"Version Settings")) {
114 ImGui::Text(
"Version-specific addresses and features:");
115 ImGui::Text(
"Vanilla: 0x140145 = 0xFF");
116 ImGui::Text(
"v2: 0x140145 = 0x02, main palettes enabled");
117 ImGui::Text(
"v3: 0x140145 = 0x03, all features enabled");
125 {
"version_flag", {0x140145, 0xFF}},
126 {
"message_ids", {0x3F51D, 0x00}},
127 {
"area_graphics", {0x7C9C, 0x00}},
128 {
"area_palettes", {0x7D1C, 0x00}},
133 {
"version_flag", {0x140145, 0x02}},
134 {
"message_ids", {0x1417F8, 0x00}},
135 {
"area_graphics", {0x7C9C, 0x00}},
136 {
"area_palettes", {0x7D1C, 0x00}},
137 {
"main_palettes", {0x140160, 0x00}},
142 {
"version_flag", {0x140145, 0x03}},
143 {
"message_ids", {0x1417F8, 0x00}},
144 {
"area_graphics", {0x7C9C, 0x00}},
145 {
"area_palettes", {0x7D1C, 0x00}},
146 {
"main_palettes", {0x140160, 0x00}},
147 {
"bg_colors", {0x140000, 0x00}},
148 {
"subscreen_overlays", {0x140340, 0x00}},
149 {
"animated_gfx", {0x1402A0, 0x00}},
150 {
"custom_tiles", {0x140480, 0x00}},
155 const std::string& reason) {
157 result.
name = test_name;
162 result.
duration = std::chrono::milliseconds{0};
163 result.
timestamp = std::chrono::steady_clock::now();
169 if (version ==
"v2") {
171 }
else if (version ==
"v3") {
176 for (
const auto& [key, value] : *data) {
181 if (version ==
"v2") {
184 }
else if (version ==
"v3") {
197 return absl::OkStatus();
202 if (version ==
"v2") {
204 }
else if (version ==
"v3") {
208 for (
const auto& [key, value] : *data) {
209 auto byte_value = rom.
ReadByte(value.first);
210 if (!byte_value.ok() || *byte_value != value.second) {
219 auto start_time = std::chrono::steady_clock::now();
222 result.
name =
"Vanilla_Baseline_Test";
231 test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
234 return absl::InternalError(
"Vanilla address validation failed");
238 auto version_byte = test_rom->
ReadByte(0x140145);
239 if (!version_byte.ok()) {
240 return absl::InternalError(
"Failed to read version flag");
243 if (*version_byte != 0xFF) {
244 return absl::InternalError(absl::StrFormat(
245 "Expected vanilla version flag (0xFF), got 0x%02X",
249 return absl::OkStatus();
252 if (test_status.ok()) {
255 "Vanilla baseline test passed - ROM is in vanilla state";
259 "Vanilla baseline test failed: " + test_status.ToString();
262 }
catch (
const std::exception& e) {
265 "Vanilla baseline test exception: " + std::string(e.what());
268 auto end_time = std::chrono::steady_clock::now();
269 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
270 end_time - start_time);
276 auto start_time = std::chrono::steady_clock::now();
279 result.
name =
"V2_Upgrade_Test";
288 test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
294 return absl::InternalError(
"v2 address validation failed");
298 auto version_byte = test_rom->
ReadByte(0x140145);
299 if (!version_byte.ok()) {
300 return absl::InternalError(
"Failed to read version flag");
303 if (*version_byte != 0x02) {
304 return absl::InternalError(
305 absl::StrFormat(
"Expected v2 version flag (0x02), got 0x%02X",
309 return absl::OkStatus();
312 if (test_status.ok()) {
315 "v2 upgrade test passed - ROM successfully upgraded to v2";
319 "v2 upgrade test failed: " + test_status.ToString();
322 }
catch (
const std::exception& e) {
325 "v2 upgrade test exception: " + std::string(e.what());
328 auto end_time = std::chrono::steady_clock::now();
329 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
330 end_time - start_time);
336 auto start_time = std::chrono::steady_clock::now();
339 result.
name =
"V3_Upgrade_Test";
348 test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
354 return absl::InternalError(
"v3 address validation failed");
358 auto version_byte = test_rom->
ReadByte(0x140145);
359 if (!version_byte.ok()) {
360 return absl::InternalError(
"Failed to read version flag");
363 if (*version_byte != 0x03) {
364 return absl::InternalError(
365 absl::StrFormat(
"Expected v3 version flag (0x03), got 0x%02X",
369 return absl::OkStatus();
372 if (test_status.ok()) {
375 "v3 upgrade test passed - ROM successfully upgraded to v3";
379 "v3 upgrade test failed: " + test_status.ToString();
382 }
catch (
const std::exception& e) {
385 "v3 upgrade test exception: " + std::string(e.what());
388 auto end_time = std::chrono::steady_clock::now();
389 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
390 end_time - start_time);
396 auto start_time = std::chrono::steady_clock::now();
399 result.
name =
"Address_Validation_Test";
408 test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
411 return absl::InternalError(
"Vanilla address validation failed");
417 return absl::InternalError(
"v2 address validation failed");
423 return absl::InternalError(
"v3 address validation failed");
426 return absl::OkStatus();
429 if (test_status.ok()) {
432 "Address validation test passed - all version addresses valid";
436 "Address validation test failed: " + test_status.ToString();
439 }
catch (
const std::exception& e) {
442 "Address validation test exception: " + std::string(e.what());
445 auto end_time = std::chrono::steady_clock::now();
446 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
447 end_time - start_time);
453 auto start_time = std::chrono::steady_clock::now();
456 result.
name =
"Feature_Toggle_Test";
465 test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
470 auto main_palettes = test_rom->
ReadByte(0x140146);
471 auto area_bg = test_rom->
ReadByte(0x140147);
472 auto subscreen_overlay = test_rom->
ReadByte(0x140148);
473 auto animated_gfx = test_rom->
ReadByte(0x140149);
474 auto custom_tiles = test_rom->
ReadByte(0x14014A);
475 auto mosaic = test_rom->
ReadByte(0x14014B);
477 if (!main_palettes.ok() || !area_bg.ok() ||
478 !subscreen_overlay.ok() || !animated_gfx.ok() ||
479 !custom_tiles.ok() || !mosaic.ok()) {
480 return absl::InternalError(
"Failed to read feature flags");
483 if (*main_palettes != 0x01 || *area_bg != 0x01 ||
484 *subscreen_overlay != 0x01 || *animated_gfx != 0x01 ||
485 *custom_tiles != 0x01 || *mosaic != 0x01) {
486 return absl::InternalError(
"Feature flags not properly enabled");
496 auto disabled_area_bg = test_rom->
ReadByte(0x140147);
497 auto disabled_animated_gfx = test_rom->
ReadByte(0x140149);
499 if (!disabled_area_bg.ok() || !disabled_animated_gfx.ok()) {
500 return absl::InternalError(
501 "Failed to read disabled feature flags");
504 if (*disabled_area_bg != 0x00 || *disabled_animated_gfx != 0x00) {
505 return absl::InternalError(
"Feature flags not properly disabled");
508 return absl::OkStatus();
511 if (test_status.ok()) {
514 "Feature toggle test passed - features can be enabled/disabled";
518 "Feature toggle test failed: " + test_status.ToString();
521 }
catch (
const std::exception& e) {
524 "Feature toggle test exception: " + std::string(e.what());
527 auto end_time = std::chrono::steady_clock::now();
528 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
529 end_time - start_time);
535 auto start_time = std::chrono::steady_clock::now();
538 result.
name =
"Data_Integrity_Test";
547 test_manager.TestRomWithCopy(rom, [&](
Rom* test_rom) -> absl::Status {
549 auto original_graphics = test_rom->
ReadByte(0x7C9C);
550 auto original_palette = test_rom->
ReadByte(0x7D1C);
551 auto original_sprite_set = test_rom->
ReadByte(0x7A41);
553 if (!original_graphics.ok() || !original_palette.ok() ||
554 !original_sprite_set.ok()) {
555 return absl::InternalError(
"Failed to read original data");
562 auto preserved_graphics = test_rom->
ReadByte(0x7C9C);
563 auto preserved_palette = test_rom->
ReadByte(0x7D1C);
564 auto preserved_sprite_set = test_rom->
ReadByte(0x7A41);
566 if (!preserved_graphics.ok() || !preserved_palette.ok() ||
567 !preserved_sprite_set.ok()) {
568 return absl::InternalError(
"Failed to read preserved data");
571 if (*preserved_graphics != *original_graphics ||
572 *preserved_palette != *original_palette ||
573 *preserved_sprite_set != *original_sprite_set) {
574 return absl::InternalError(
575 "Original data not preserved during upgrade");
579 auto bg_colors = test_rom->
ReadByte(0x140000);
580 auto subscreen_overlays = test_rom->
ReadByte(0x140340);
581 auto animated_gfx = test_rom->
ReadByte(0x1402A0);
582 auto custom_tiles = test_rom->
ReadByte(0x140480);
584 if (!bg_colors.ok() || !subscreen_overlays.ok() ||
585 !animated_gfx.ok() || !custom_tiles.ok()) {
586 return absl::InternalError(
"Failed to read new v3 data");
589 if (*bg_colors != 0x00 || *subscreen_overlays != 0x00 ||
590 *animated_gfx != 0x00 || *custom_tiles != 0x00) {
591 return absl::InternalError(
592 "New v3 data not properly initialized");
595 return absl::OkStatus();
598 if (test_status.ok()) {
601 "Data integrity test passed - original data preserved, new data "
606 "Data integrity test failed: " + test_status.ToString();
609 }
catch (
const std::exception& e) {
612 "Data integrity test exception: " + std::string(e.what());
615 auto end_time = std::chrono::steady_clock::now();
616 result.
duration = std::chrono::duration_cast<std::chrono::milliseconds>(
617 end_time - start_time);
632 std::map<std::string, std::pair<uint32_t, uint8_t>>
v2_data_;
633 std::map<std::string, std::pair<uint32_t, uint8_t>>
v3_data_;
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
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(expr)
std::chrono::milliseconds duration
std::string error_message
std::chrono::time_point< std::chrono::steady_clock > timestamp
void AddResult(const TestResult &result)