From 4e58f4dffa89d48cc0a70723afa743919083fd2f Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 19 May 2026 20:55:51 +0200 Subject: [PATCH] Codechange: introduce regression script for GS --- regression/CMakeLists.txt | 1 + regression/gs/CMakeLists.txt | 8 ++++ regression/gs/info.nut | 14 ++++++ regression/gs/main.nut | 83 +++++++++++++++++++++++++++++++++++ regression/gs/require.nut | 9 ++++ regression/gs/result.txt | 44 +++++++++++++++++++ regression/gs/test.sav | Bin 0 -> 16376 bytes 7 files changed, 159 insertions(+) create mode 100644 regression/gs/CMakeLists.txt create mode 100644 regression/gs/info.nut create mode 100644 regression/gs/main.nut create mode 100644 regression/gs/require.nut create mode 100644 regression/gs/result.txt create mode 100644 regression/gs/test.sav diff --git a/regression/CMakeLists.txt b/regression/CMakeLists.txt index 340e29c2d9..a02a538e17 100644 --- a/regression/CMakeLists.txt +++ b/regression/CMakeLists.txt @@ -22,3 +22,4 @@ add_subdirectory(regression) add_subdirectory(stationlist) + add_subdirectory(gs) diff --git a/regression/gs/CMakeLists.txt b/regression/gs/CMakeLists.txt new file mode 100644 index 0000000000..e25b8642b0 --- /dev/null +++ b/regression/gs/CMakeLists.txt @@ -0,0 +1,8 @@ +include(CreateRegression) +create_regression("game" + ${CMAKE_CURRENT_SOURCE_DIR}/info.nut + ${CMAKE_CURRENT_SOURCE_DIR}/main.nut + ${CMAKE_CURRENT_SOURCE_DIR}/require.nut + ${CMAKE_CURRENT_SOURCE_DIR}/result.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test.sav +) diff --git a/regression/gs/info.nut b/regression/gs/info.nut new file mode 100644 index 0000000000..57647bc67c --- /dev/null +++ b/regression/gs/info.nut @@ -0,0 +1,14 @@ +class Regression extends GSInfo { + function GetAuthor() { return "OpenTTD GS Developers Team"; } + function GetName() { return "Regression"; } + function GetShortName() { return "REGR"; } + function GetDescription() { return "This runs regression-tests on some commands. On the same map the result should always be the same."; } + function GetVersion() { return 1; } + function GetAPIVersion() { return "16"; } + function GetDate() { return "2026-05-19"; } + function CreateInstance() { return "Regression"; } + function UseAsRandomAI() { return false; } +} + +RegisterGS(Regression()); + diff --git a/regression/gs/main.nut b/regression/gs/main.nut new file mode 100644 index 0000000000..0a991ee5fb --- /dev/null +++ b/regression/gs/main.nut @@ -0,0 +1,83 @@ +class Regression extends GSController { + function Start(); +}; + + + +function Regression::TestInit() +{ + print(""); + print("--TestInit--"); + print(" Ops: " + this.GetOpsTillSuspend()); + print(" TickTest: " + this.GetTick()); + this.Sleep(1); + print(" TickTest: " + this.GetTick()); + print(" Ops: " + this.GetOpsTillSuspend()); + print(" SetCommandDelay: " + GSController.SetCommandDelay(1)); + print(" IsValid(vehicle.plane_speed): " + GSGameSettings.IsValid("vehicle.plane_speed")); + print(" vehicle.plane_speed: " + GSGameSettings.GetValue("vehicle.plane_speed")); + require("require.nut"); + print(" TestEnum.value1: " + ::TestEnum.value1); + print(" test_constant: " + ::test_constant); + print(" TestEnum.value2: " + TestEnum.value2); + print(" test_constant: " + test_constant); + print(" min(6, 3): " + min(6, 3)); + print(" min(3, 6): " + min(3, 6)); + print(" max(6, 3): " + max(6, 3)); + print(" max(3, 6): " + max(3, 6)); +} + +function Regression::Company() +{ + print(""); + print("--Company--"); + + /* Test GSXXXMode() in scopes */ + { + local test = GSTestMode(); + print(" SetName(): " + GSCompany.SetName("Regression")); + print(" SetName(): " + GSCompany.SetName("Regression")); + { + local exec = GSExecMode(); + print(" SetName(): " + GSCompany.SetName("Regression")); + print(" SetName(): " + GSCompany.SetName("Regression")); + print(" GetLastErrorString(): " + GSError.GetLastErrorString()); + } + } + + print(" GetName(): " + GSCompany.GetName(GSCompany.COMPANY_SELF)); + print(" GetPresidentName(): " + GSCompany.GetPresidentName(GSCompany.COMPANY_SELF)); + print(" SetPresidentName(): " + GSCompany.SetPresidentName("Regression GS")); + print(" GetPresidentName(): " + GSCompany.GetPresidentName(GSCompany.COMPANY_SELF)); + + print(""); + print("--CompanyMode--"); + + local company = GSCompanyMode(GSCompany.COMPANY_FIRST); + { + local test = GSTestMode(); + print(" SetName(): " + GSCompany.SetName("Regression")); + print(" SetName(): " + GSCompany.SetName("Regression")); + { + local exec = GSExecMode(); + print(" SetName(): " + GSCompany.SetName("Regression")); + print(" SetName(): " + GSCompany.SetName("Regression")); + print(" GetLastErrorString(): " + GSError.GetLastErrorString()); + } + } + + print(" GetName(): " + GSCompany.GetName(GSCompany.COMPANY_SELF)); + print(" GetPresidentName(): " + GSCompany.GetPresidentName(GSCompany.COMPANY_SELF)); + print(" SetPresidentName(): " + GSCompany.SetPresidentName("Regression GS")); + print(" GetPresidentName(): " + GSCompany.GetPresidentName(GSCompany.COMPANY_SELF)); +} + +function Regression::Start() +{ + this.TestInit(); + this.Company(); + + print(""); + print("Done..."); + print(""); +} diff --git a/regression/gs/require.nut b/regression/gs/require.nut new file mode 100644 index 0000000000..872a929a5f --- /dev/null +++ b/regression/gs/require.nut @@ -0,0 +1,9 @@ +print(" Required this file"); + +const test_constant = 1; + +enum TestEnum { + value0, + value1, + value2 +}; diff --git a/regression/gs/result.txt b/regression/gs/result.txt new file mode 100644 index 0000000000..03cd98fb1b --- /dev/null +++ b/regression/gs/result.txt @@ -0,0 +1,44 @@ + +--TestInit-- + Ops: 9988 + TickTest: 1 + TickTest: 2 + Ops: 9990 + SetCommandDelay: (null : 0x00000000) + IsValid(vehicle.plane_speed): true + vehicle.plane_speed: 4 + Required this file + TestEnum.value1: 1 + test_constant: 1 + TestEnum.value2: 2 + test_constant: 1 + min(6, 3): 3 + min(3, 6): 3 + max(6, 3): 6 + max(3, 6): 6 + +--Company-- + SetName(): false + SetName(): false + SetName(): false + SetName(): false + GetLastErrorString(): ERR_PRECONDITION_INVALID_COMPANY + GetName(): (null : 0x00000000) + GetPresidentName(): (null : 0x00000000) + SetPresidentName(): false + GetPresidentName(): (null : 0x00000000) + +--CompanyMode-- + SetName(): true + SetName(): true + SetName(): true + SetName(): false + GetLastErrorString(): ERR_NAME_IS_NOT_UNIQUE + GetName(): Regression + GetPresidentName(): S. G. Bloggs + SetPresidentName(): true + GetPresidentName(): Regression GS + +Done... + +ERROR: The script died unexpectedly. diff --git a/regression/gs/test.sav b/regression/gs/test.sav new file mode 100644 index 0000000000000000000000000000000000000000..ff654e0cd4e7865eb923de202d65067a89e7a8a2 GIT binary patch literal 16376 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