1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Add tests to iterate on all .parkpatch files

This commit is contained in:
Tulio Leao
2024-02-25 17:28:16 -03:00
parent 046ded718c
commit 1ebaac86be
5 changed files with 101 additions and 15 deletions

View File

@@ -30,6 +30,8 @@
#include <iostream>
static bool s_dryRun = false;
// Generic keys
static const std::string s_scenarioNameKey = "scenario_name";
static const std::string s_fullSHAKey = "sha256";
@@ -129,6 +131,10 @@ static void ApplyLandOwnershipFixes(const json_t& landOwnershipFixes, int owners
? Json::GetBoolean(ownershipParameters[s_cannotDowngradeKey], false)
: false;
auto coordinatesVector = getCoordinates(ownershipParameters);
if (s_dryRun)
{
return;
}
FixLandOwnershipTilesWithOwnership(coordinatesVector, ownershipType, cannotDowngrade);
}
@@ -174,6 +180,10 @@ static void ApplyWaterFixes(const json_t& scenarioPatch)
Guard::Assert(0, "Water fix sub-array should set a height");
return;
}
if (s_dryRun)
{
continue;
}
auto waterHeight = waterFixes[i][s_heightKey];
auto coordinatesVector = getCoordinates(waterFixes[i]);
@@ -237,6 +247,11 @@ static void ApplyTrackTypeFixes(const json_t& trackTilesFixes)
auto destinationTrackType = toTrackType(Json::GetString(fixOperations[i][s_toKey]));
auto coordinatesVector = getCoordinates(fixOperations[i]);
if (s_dryRun)
{
continue;
}
for (const auto& tile : coordinatesVector)
{
auto* tileElement = MapGetFirstElementAt(tile);
@@ -370,6 +385,12 @@ static void ApplyRideFixes(const json_t& scenarioPatch)
RideId rideId = RideId::FromUnderlying(Json::GetNumber<uint16_t>(rideFixes[i][s_rideIdKey]));
auto operation = Json::GetString(rideFixes[i][s_operationKey]);
if (s_dryRun)
{
continue;
}
if (operation == "swap_entrance_exit")
{
SwapRideEntranceAndExit(rideId);
@@ -401,6 +422,11 @@ static u8string GetPatchFileName(u8string_view scenarioHash)
static bool ValidateSHA256(const json_t& scenarioPatch, u8string_view scenarioHash)
{
if (s_dryRun)
{
return true;
}
if (!scenarioPatch.contains(s_scenarioNameKey))
{
Guard::Assert(0, "All .parkpatch files should contain the name of the original scenario");
@@ -420,6 +446,24 @@ static bool ValidateSHA256(const json_t& scenarioPatch, u8string_view scenarioHa
return scenarioSHA == scenarioHash;
}
void RCT12::ApplyScenarioPatch(u8string_view scenarioPatchFile, u8string scenarioSHA, bool isScenario)
{
auto scenarioPatch = Json::ReadFromFile(scenarioPatchFile);
if (!ValidateSHA256(scenarioPatch, scenarioSHA))
{
Guard::Assert(0, "Invalid full SHA256. Check for shortened SHA collision");
return;
}
// TODO: Land ownership is applied even when loading saved scenario. Should it?
ApplyLandOwnershipFixes(scenarioPatch);
if (isScenario)
{
ApplyWaterFixes(scenarioPatch);
ApplyTileFixes(scenarioPatch);
ApplyRideFixes(scenarioPatch);
}
}
void RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioPath, bool isScenario)
{
auto scenarioSHA = getScenarioSHA256(scenarioPath);
@@ -427,19 +471,11 @@ void RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioPath, bool isScenar
std::cout << "Patch is: " << patchPath << " full SHA" << scenarioSHA << std::endl;
if (File::Exists(patchPath))
{
auto scenarioPatch = Json::ReadFromFile(patchPath);
if (!ValidateSHA256(scenarioPatch, scenarioSHA))
{
Guard::Assert(0, "Invalid full SHA256. Check for shortened SHA collision");
return;
}
// TODO: Land ownership is applied even when loading saved scenario. Should it?
ApplyLandOwnershipFixes(scenarioPatch);
if (isScenario)
{
ApplyWaterFixes(scenarioPatch);
ApplyTileFixes(scenarioPatch);
ApplyRideFixes(scenarioPatch);
}
ApplyScenarioPatch(patchPath, scenarioSHA, isScenario);
}
}
void RCT12::SetDryRun(bool enable)
{
s_dryRun = enable;
}

View File

@@ -14,4 +14,7 @@
namespace RCT12
{
void FetchAndApplyScenarioPatch(u8string_view scenarioPath, bool isScenario);
}
void ApplyScenarioPatch(u8string_view scenarioPatchFile, u8string scenarioSHA, bool isScenario);
/*SetDryRun should be used only for testing*/
void SetDryRun(bool enable);
} // namespace RCT12

View File

@@ -28,6 +28,7 @@ set(test_files
"${CMAKE_CURRENT_SOURCE_DIR}/RideRatings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/S6ImportExportTests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/SawyerCodingTest.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ScenarioPatcherTests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/StringTest.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/TestData.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/TestData.h"

View File

@@ -0,0 +1,45 @@
/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "TestData.h"
#include <gtest/gtest.h>
#include <openrct2/Context.h>
#include <openrct2/PlatformEnvironment.h>
#include <openrct2/core/FileSystem.hpp>
#include <openrct2/core/Guard.hpp>
#include <openrct2/rct12/ScenarioPatcher.h>
/* Test that all JSONs are with the expected formatting, otherwise the fetcher will abort
NOTE: This will *not* test that it actually applies the patch, due to the scenarios
not being available on the CI environment.
*/
TEST(FetchAndApplyScenarioPatch, expected_json_format)
{
auto context = OpenRCT2::CreateContext();
bool initialised = context->Initialise();
ASSERT_TRUE(initialised);
auto env = context->GetPlatformEnvironment();
auto scenarioPatches = env->GetDirectoryPath(OpenRCT2::DIRBASE::OPENRCT2, OpenRCT2::DIRID::SCENARIO_PATCHES);
std::error_code ec;
RCT12::SetDryRun(true);
Guard::SetAssertBehaviour(ASSERT_BEHAVIOUR::ABORT);
static const u8string dummySHA;
for (const fs::directory_entry& entry : fs::directory_iterator(scenarioPatches, ec))
{
auto path = entry.path().u8string();
if (String::EndsWith(path, ".parkpatch"))
{
RCT12::ApplyScenarioPatch(path, dummySHA, true);
}
}
SUCCEED();
}

View File

@@ -97,6 +97,7 @@
<ClCompile Include="RideRatings.cpp" />
<ClCompile Include="S6ImportExportTests.cpp" />
<ClCompile Include="SawyerCodingTest.cpp" />
<ClCompile Include="ScenarioPatcherTests.cpp" />
<ClCompile Include="TestData.cpp" />
<ClCompile Include="tests.cpp" />
<ClCompile Include="StringTest.cpp" />