feat(test): lua signal test
This commit is contained in:
parent
92ab9f6fb9
commit
44c28b6825
6 changed files with 267 additions and 97 deletions
|
@ -7,6 +7,8 @@ function (create_test TEST_NAME)
|
|||
endfunction ()
|
||||
|
||||
create_test(lua src/luatest.cpp)
|
||||
create_test(luasched src/luaschedtest.cpp)
|
||||
create_test(luasignal src/luasignaltest.cpp)
|
||||
|
||||
# https://stackoverflow.com/a/36729074/16255372
|
||||
add_custom_target(check ${CMAKE_CTEST_COMMAND} --output-on-failure WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
77
tests/src/luaschedtest.cpp
Normal file
77
tests/src/luaschedtest.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "testutillua.h"
|
||||
|
||||
#include "timeutil.h"
|
||||
|
||||
void test_wait1(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "wait(1) print('Wait')");
|
||||
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Wait\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
}
|
||||
|
||||
void test_wait0(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "wait(0) print('Wait')");
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.03);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Wait\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
}
|
||||
|
||||
void test_delay(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "delay(1, function() print('Delay') end)");
|
||||
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Delay\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto m = DataModel::New();
|
||||
m->Init(true);
|
||||
|
||||
test_wait1(m);
|
||||
test_wait0(m);
|
||||
test_delay(m);
|
||||
|
||||
return TEST_STATUS;
|
||||
}
|
103
tests/src/luasignaltest.cpp
Normal file
103
tests/src/luasignaltest.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
|
||||
#include "testutil.h"
|
||||
#include "testutillua.h"
|
||||
|
||||
#include "timeutil.h"
|
||||
#include "objects/part/part.h"
|
||||
#include "objects/service/workspace.h"
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
void test_connect(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
auto part = Part::New();
|
||||
m->GetService<Workspace>()->AddChild(part);
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
luaEval(m, "workspace.Part.Touched:Connect(function() print('Fired!') end)");
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
part->Touched->Fire();
|
||||
ASSERT_EQ("INFO: Fired!\n", out.str());
|
||||
part->Touched->Fire();
|
||||
ASSERT_EQ("INFO: Fired!\nINFO: Fired!\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
part->Destroy();
|
||||
}
|
||||
|
||||
void test_waitwithin(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
auto part = Part::New();
|
||||
m->GetService<Workspace>()->AddChild(part);
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "workspace.Part.Touched:Connect(function() print('Fired!') wait(1) print('Waited') end)");
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
// One shot
|
||||
part->Touched->Fire();
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Fired!\n", out.str());
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Fired!\n", out.str());
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Fired!\nINFO: Waited\n", out.str());
|
||||
|
||||
// Clear
|
||||
out = std::stringstream();
|
||||
Logger::initTest(&out); // Shouldn't *theoretically* be necessary, but just in principle...
|
||||
|
||||
// Double fire
|
||||
part->Touched->Fire();
|
||||
TT_ADVANCETIME(0.2);
|
||||
part->Touched->Fire();
|
||||
ASSERT_EQ("INFO: Fired!\nINFO: Fired!\n", out.str());
|
||||
TT_ADVANCETIME(1-0.2); // Small extra delay is necessary because floating point math
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Fired!\nINFO: Fired!\nINFO: Waited\n", out.str());
|
||||
TT_ADVANCETIME(0.2);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Fired!\nINFO: Fired!\nINFO: Waited\nINFO: Waited\n", out.str());
|
||||
|
||||
tu_set_override(-1UL);
|
||||
Logger::initTest(nullptr);
|
||||
part->Destroy();
|
||||
}
|
||||
|
||||
void test_await(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
auto part = Part::New();
|
||||
m->GetService<Workspace>()->AddChild(part);
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "workspace.Part.Touched:Wait() print('Fired!')");
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
part->Touched->Fire();
|
||||
ASSERT_EQ("INFO: Fired!\n", out.str());
|
||||
part->Touched->Fire(); // Firing again should not affect output
|
||||
ASSERT_EQ("INFO: Fired!\n", out.str());
|
||||
|
||||
tu_set_override(-1UL);
|
||||
Logger::initTest(nullptr);
|
||||
part->Destroy();
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto m = DataModel::New();
|
||||
m->Init(true);
|
||||
|
||||
test_connect(m);
|
||||
test_waitwithin(m);
|
||||
test_await(m);
|
||||
|
||||
return TEST_STATUS;
|
||||
}
|
|
@ -1,32 +1,8 @@
|
|||
#include "objects/service/script/scriptcontext.h"
|
||||
#include "testutil.h"
|
||||
#include "testutillua.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include "objects/datamodel.h"
|
||||
#include "objects/script.h"
|
||||
#include "timeutil.h"
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
std::string luaEvalOut(DATAMODEL_REF m, std::string source) {
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
auto s = Script::New();
|
||||
m->AddChild(s);
|
||||
s->source = source;
|
||||
s->Run();
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void luaEval(DATAMODEL_REF m, std::string source) {
|
||||
auto s = Script::New();
|
||||
m->AddChild(s);
|
||||
s->source = source;
|
||||
s->Run();
|
||||
}
|
||||
|
||||
void test_output(DATAMODEL_REF m) {
|
||||
ASSERT_EQ("INFO: Hello, world!\n", luaEvalOut(m, "print('Hello, world!')"));
|
||||
|
@ -34,77 +10,11 @@ void test_output(DATAMODEL_REF m) {
|
|||
// ASSERT_EQ("ERROR: An error!.\n", luaEvalOut(m, "error('An error!')"));
|
||||
}
|
||||
|
||||
void test_wait1(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "wait(1) print('Wait')");
|
||||
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Wait\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
}
|
||||
|
||||
void test_wait0(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "wait(0) print('Wait')");
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.03);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Wait\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
}
|
||||
|
||||
void test_delay(DATAMODEL_REF m) {
|
||||
auto ctx = m->GetService<ScriptContext>();
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
tu_set_override(0);
|
||||
luaEval(m, "delay(1, function() print('Delay') end)");
|
||||
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("", out.str());
|
||||
|
||||
TT_ADVANCETIME(0.5);
|
||||
ctx->RunSleepingThreads();
|
||||
ASSERT_EQ("INFO: Delay\n", out.str());
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto m = DataModel::New();
|
||||
m->Init(true);
|
||||
|
||||
test_output(m);
|
||||
test_wait1(m);
|
||||
test_wait0(m);
|
||||
test_delay(m);
|
||||
|
||||
return TEST_STATUS;
|
||||
}
|
|
@ -2,21 +2,69 @@
|
|||
|
||||
// https://bastian.rieck.me/blog/2017/simple_unit_tests/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iomanip>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#ifdef __FUNCTION__
|
||||
#define ASSERT(x, msg) if (!(x)) { fprintf(stderr, "ASSERT FAILED : %s:%d : %s : '%s'\n", __FILE__, __LINE__, __FUNCTION__, msg); exit(1); TEST_STATUS = 1; }
|
||||
#define __FUNC_NAME __FUNCTION__
|
||||
#else
|
||||
#define ASSERT(x, msg) if (!(x)) { fprintf(stderr, "ASSERT FAILED : %s:%d : ?? : '%s'\n", __FILE__, __LINE__, msg); TEST_STATUS = 1; }
|
||||
#define __FUNC_NAME __func__
|
||||
#endif
|
||||
|
||||
#define ASSERT_EQ(x, y) ASSERT(x == y, #x " != " #y)
|
||||
#define ASSERT_EQSTR(x, y) ASSERT(strcmp(x, y) == 0, #x " != " #y)
|
||||
#define ASSERT(x, msg) __assert((x), __FILE__, __LINE__, __FUNC_NAME, msg)
|
||||
#define ASSERT_EQ(x, y) __assert_eq((x) == (y), __FILE__, __LINE__, __FUNC_NAME, #x, (y))
|
||||
// #define ASSERT_EQSTR(x, y) ASSERT(strcmp(x, y) == 0, #x " != " #y)
|
||||
#define ASSERT_EQSTR(x, y) ASSERT_EQ(x, y)
|
||||
|
||||
#define DATAMODEL_REF std::shared_ptr<DataModel>
|
||||
|
||||
#define TU_TIME_EXPOSE_TEST
|
||||
#define TT_ADVANCETIME(secs) tu_set_override(tu_clock_micros() + secs * 1'000'000);
|
||||
#define TT_ADVANCETIME(secs) tu_set_override(tu_clock_micros() + (secs) * 1'000'000);
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
int TEST_STATUS = 0;
|
||||
|
||||
inline void __assert(bool cond, std::string file, int line, std::string func, std::string message) {
|
||||
if (cond) return;
|
||||
fprintf(stderr, "ASSERT FAILED : %s:%d : %s : '%s'\n", file.c_str(), line, func.c_str(), message.c_str());
|
||||
TEST_STATUS = 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string quote(T value) {
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string quote<std::string>(std::string value) {
|
||||
std::stringstream ss;
|
||||
ss << std::quoted(value);
|
||||
std::string newstr = ss.str();
|
||||
|
||||
newstr = std::regex_replace(newstr, std::regex("\n"), "\\n");
|
||||
return newstr;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string quote<const char*>(const char* value) {
|
||||
return quote<std::string>(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string quote<char*>(char* value) {
|
||||
return quote<std::string>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void __assert_eq(bool cond, std::string file, int line, std::string func, std::string model, T value) {
|
||||
if (cond) return;
|
||||
std::string message = model + " != " + quote(value);
|
||||
fprintf(stderr, "ASSERT FAILED : %s:%d : %s : '%s'\n", file.c_str(), line, func.c_str(), message.c_str());
|
||||
TEST_STATUS = 1;
|
||||
}
|
30
tests/src/testutillua.h
Normal file
30
tests/src/testutillua.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "testutil.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "logger.h"
|
||||
#include "objects/datamodel.h"
|
||||
#include "objects/script.h"
|
||||
#include "objects/service/script/scriptcontext.h"
|
||||
|
||||
std::string luaEvalOut(DATAMODEL_REF m, std::string source) {
|
||||
std::stringstream out;
|
||||
Logger::initTest(&out);
|
||||
|
||||
auto s = Script::New();
|
||||
m->AddChild(s);
|
||||
s->source = source;
|
||||
s->Run();
|
||||
|
||||
Logger::initTest(nullptr);
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void luaEval(DATAMODEL_REF m, std::string source) {
|
||||
auto s = Script::New();
|
||||
m->AddChild(s);
|
||||
s->source = source;
|
||||
s->Run();
|
||||
}
|
Loading…
Add table
Reference in a new issue