18
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-15 02:29:07 +01:00
Files
maszyna/tests/unit/test_script_screens.cpp

104 lines
4.0 KiB
C++

#include "stdafx.h"
#include "doctest.h"
#include "scripting/scriptscreenrules.h"
#include "utilities/parser.h"
// the parts of the script screens that don't need the runtime: the .mmd entries, the refresh schedule counted in
// frames and the files a screen may read
using script_screens::frame_schedule;
using script_screens::screen_config;
TEST_CASE("script screens: a cab screen entry with every key") {
cParser parser("{ ekran.wasm target: screen01 frames: 6 parameters: id=1&mode=full } next:", cParser::buffer_TEXT);
screen_config config;
config.deserialize(parser);
CHECK(config.script == "ekran.wasm");
CHECK(config.target == "screen01");
CHECK(config.frames == 6);
CHECK(config.parameters == "id=1&mode=full");
// the parser stops at the end of the block
CHECK(parser.getToken<std::string>() == "next:");
}
TEST_CASE("script screens: the optional keys keep their defaults, an unknown key is skipped with its value") {
cParser parser("{ tablica.wasm later: 12 instance: name background: tablica_off }", cParser::buffer_TEXT);
screen_config config;
config.deserialize(parser);
CHECK(config.script == "tablica.wasm");
CHECK(config.target == "none");
CHECK(config.frames == 0);
CHECK(config.parameters.empty());
CHECK(config.instancing == "name");
CHECK(config.background == "tablica_off");
}
TEST_CASE("script screens: the interval set in eu07.ini, or the screen's own when it is longer") {
CHECK(frame_schedule::effective_interval(4, 0) == 4);
CHECK(frame_schedule::effective_interval(4, 10) == 10);
CHECK(frame_schedule::effective_interval(4, 2) == 4);
// never less than every frame
CHECK(frame_schedule::effective_interval(0, 0) == 1);
CHECK(frame_schedule::effective_interval(-3, -1) == 1);
}
TEST_CASE("script screens: a screen is due once per interval") {
frame_schedule schedule{100, 3, 0};
CHECK(schedule.poll(100));
// asked again in the same frame (the vehicle drawn in more than one pass)
CHECK_FALSE(schedule.poll(100));
CHECK_FALSE(schedule.poll(101));
CHECK_FALSE(schedule.poll(102));
CHECK(schedule.poll(103));
CHECK_FALSE(schedule.poll(105));
CHECK(schedule.poll(106));
}
TEST_CASE("script screens: a screen out of sight for a while is due on the first frame it is asked again") {
frame_schedule schedule{0, 5, 0};
CHECK(schedule.poll(0));
CHECK(schedule.poll(42));
CHECK_FALSE(schedule.poll(46));
CHECK(schedule.poll(47));
}
TEST_CASE("script screens: the phase spreads the screens over the frames of an interval") {
auto const interval{30};
auto const phase{frame_schedule::phase("make:dynamic/pkp/ed72/tablica.wasm?$timetable=ed72-001", interval)};
CHECK(phase >= 0);
CHECK(phase < interval);
// the same name always gets the same phase
CHECK(phase == frame_schedule::phase("make:dynamic/pkp/ed72/tablica.wasm?$timetable=ed72-001", interval));
// a screen refreshed every frame has no phase
CHECK(frame_schedule::phase("anything", 1) == 0);
frame_schedule schedule{1000, interval, phase};
auto first{std::uint64_t{0}};
for (auto frame = std::uint64_t{1000}; frame < 1000 + interval; ++frame) {
if (schedule.poll(frame)) {
first = frame;
break;
}
}
CHECK(first == 1000 + static_cast<std::uint64_t>(phase));
}
TEST_CASE("script screens: a screen reads files only below its own folder") {
CHECK(script_screens::is_safe_relative_path("font.png"));
CHECK(script_screens::is_safe_relative_path("data/font.png"));
CHECK(script_screens::is_safe_relative_path("data\\font.png"));
CHECK(script_screens::is_safe_relative_path("data/..font.png"));
CHECK_FALSE(script_screens::is_safe_relative_path(""));
CHECK_FALSE(script_screens::is_safe_relative_path("../eu07.ini"));
CHECK_FALSE(script_screens::is_safe_relative_path("data/../../eu07.ini"));
CHECK_FALSE(script_screens::is_safe_relative_path("data\\..\\x"));
CHECK_FALSE(script_screens::is_safe_relative_path(".."));
CHECK_FALSE(script_screens::is_safe_relative_path("/etc/passwd"));
CHECK_FALSE(script_screens::is_safe_relative_path("\\windows"));
CHECK_FALSE(script_screens::is_safe_relative_path("c:/windows/win.ini"));
}