mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-18 14:59:19 +02:00
eu07_unit_tests: C++ tests (doctest) of the simulation, which set up the
conditions, run the code and check the outcome. No game data, no window.
- the code under test is the core library (eu07_core), the very objects
the game links, built with the game's settings; engine_stubs.cpp stands
in for the logs, settings and scenery layers the library reaches for.
python gets linked with the settings but isn't needed to run the tests
- test vehicles are JSON definitions in tests/unit/data, with the sections
and keys of the game's vehicle definitions (tables as "rows", _keys are
comments), changed by the tests where needed and loaded from memory by
the game's own loader; an unknown section is an error rather than
silently skipped
- test::vehicle creates the mover the way TDynamicObject::Init() does and
steps it the way the simulation loop does, on a straight track of given
friction and gradient, optionally holding the brake pipe pressure the
way a coupled locomotive would
- the random numbers of the simulation are reseeded before every test
case, so a test gives the same result alone (IDE) or among the others
- building the game runs the tests at the end, once the game is linked,
and prints a one line summary ("Unit tests: 11/11 passed (80 checks)").
A failure prints the full report and fails the build, in CI and locally
alike, and removes the game binary so the next build reruns them. A
change of the tests alone relinks the game so they run (Ninja and
Makefile generators). -DWITH_TESTS=OFF leaves them out
- first tests: definitions reach the vehicle, KE service application and
release, deeper reduction brakes harder, every implemented distributor
valve charges/applies/releases, service braking stops a moving wagon
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.1 KiB
C++
65 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include "McZapkie/MOVER.h"
|
|
|
|
namespace test {
|
|
|
|
// definition of a test vehicle: one of the JSON files in tests/unit/data, with the sections and keys
|
|
// of the game's vehicle definitions, changed by the test where it needs to:
|
|
// auto heavy = definition::load("wagon").set("Param", "M", 60000).set("Brake", "BrakeValve", "ESt3");
|
|
class definition {
|
|
public:
|
|
// tests/unit/data/<Name>.json
|
|
static definition load(std::string const &Name);
|
|
|
|
// sets the key of the section, adding either one when it's missing
|
|
definition &set(std::string const &Section, std::string const &Key, nlohmann::ordered_json const &Value);
|
|
// drops the whole section, or one key of it
|
|
definition &remove(std::string const &Section);
|
|
definition &remove(std::string const &Section, std::string const &Key);
|
|
|
|
// the definition in the form the game's vehicle loader reads
|
|
std::string text() const;
|
|
|
|
private:
|
|
nlohmann::ordered_json m_sections;
|
|
};
|
|
|
|
// conditions the vehicle runs in: straight track of the given friction and gradient (rise/run)
|
|
struct track {
|
|
double friction{0.15};
|
|
double gradient{0.0};
|
|
};
|
|
|
|
// one vehicle created the way TDynamicObject::Init() creates it, from the given definition
|
|
class vehicle {
|
|
public:
|
|
explicit vehicle(definition const &Definition, double Velocity = 0.0, std::string const &Name = "test");
|
|
|
|
TMoverParameters &mover() { return *m_mover; }
|
|
TMoverParameters *operator->() { return m_mover.get(); }
|
|
|
|
// keeps the brake pipe at the given pressure [bar], as a locomotive coupled to the vehicle would;
|
|
// a negative value leaves the pipe alone
|
|
void hold_brake_pipe(double Pressure) { m_pipepressure = Pressure; }
|
|
|
|
// advances the physics by one step of Dt, the way the simulation loop does
|
|
void step(track const &Track = {}, double Dt = 0.01);
|
|
// advances the physics by Seconds in steps of Dt
|
|
void run(double Seconds, track const &Track = {}, double Dt = 0.01);
|
|
|
|
// vehicle speed [km/h], signed
|
|
double speed() const { return m_mover->V * 3.6; }
|
|
|
|
private:
|
|
std::unique_ptr<TMoverParameters> m_mover;
|
|
double m_pipepressure{-1.0};
|
|
};
|
|
|
|
} // namespace test
|