// Headless checks for the v25 viewer colour-mode/overlay save block (no window needed). // Modeled on test_events.cpp. #include "Viewer.hpp" #include #include #include static int failures = 0; static void check(bool cond, const char* what) { std::printf(" [%s] %s\n", cond ? "PASS" : "FAIL", what); if (!cond) ++failures; } int main() { std::printf("Viewer state: v25 colour-mode/overlay save/load round-trip\n"); Viewer v; PlanetConfig cfg; cfg.subdivisions = 2; cfg.seed = 777; v.cfg = cfg; v.planet.generate(cfg); // Set every overlay to a value that differs from the Viewer's own defaults, plus a non-default // colour mode, so a bug that left fields untouched (rather than round-tripped) would show up. v.mode = ColorMode::Biome; v.showBorders = false; // default true v.showDrift = false; // default true v.showRivers = false; // default true v.showGrat = true; // default false v.dayNightOn = false; // default true v.showTides = true; // default false v.showCurrents = true; // default false v.showClouds = false; // default true v.showVolcanoes = false; // default true v.showNames = true; // default false v.showSettlements = false; // default true v.showDiplomacy = false; // default true v.showRealms = true; // default false const char* path = "/tmp/fanworgen_viewerstate_test.save"; v.saveGame(path); Viewer r; r.loadGame(path); check(r.mode == ColorMode::Biome, "v25 save/load restores the colour mode"); check(r.showBorders == false, "v25 restores showBorders"); check(r.showDrift == false, "v25 restores showDrift"); check(r.showRivers == false, "v25 restores showRivers"); check(r.showGrat == true, "v25 restores showGrat"); check(r.dayNightOn == false, "v25 restores dayNightOn"); check(r.showTides == true, "v25 restores showTides"); check(r.showCurrents == true, "v25 restores showCurrents"); check(r.showClouds == false, "v25 restores showClouds"); check(r.showVolcanoes == false, "v25 restores showVolcanoes"); check(r.showNames == true, "v25 restores showNames"); check(r.showSettlements == false, "v25 restores showSettlements"); check(r.showDiplomacy == false, "v25 restores showDiplomacy"); check(r.showRealms == true, "v25 restores showRealms"); check(r.screen == AppScreen::World, "loadGame() switches the app screen to World"); check(r.menuState.worldEverGenerated, "loadGame() marks a world as having been generated"); // Negative test: patch the save's version back to 24 (pre-v25, no mode/overlay block) and load // into a fresh Viewer whose defaults differ from the saved-but-truncated values above -- must // not crash, and must leave mode/overlays exactly at the fresh Viewer's own pre-load values. { std::fstream fs(path, std::ios::in | std::ios::out | std::ios::binary); uint32_t oldVer = 24; fs.seekp(4); fs.write((char*)&oldVer, 4); } Viewer old; ColorMode preLoadMode = old.mode; bool preLoadBorders = old.showBorders, preLoadRealms = old.showRealms; old.loadGame(path); check(old.mode == preLoadMode, "pre-v25 saves leave the colour mode at its pre-load value"); check(old.showBorders == preLoadBorders, "pre-v25 saves leave showBorders at its pre-load value"); check(old.showRealms == preLoadRealms, "pre-v25 saves leave showRealms at its pre-load value"); std::printf(failures ? "\nFAILURES: %d\n" : "\nALL VIEWER STATE CHECKS PASSED\n", failures); return failures ? 1 : 0; }