diff --git a/modules/unit_test/.gitignore b/modules/unit_test/.gitignore new file mode 100644 index 000000000..00d0f2904 --- /dev/null +++ b/modules/unit_test/.gitignore @@ -0,0 +1,8 @@ +.import +*.d +*.o +*.meta +*.obj +*.pyc +*.bc +*.os diff --git a/modules/unit_test/SCsub b/modules/unit_test/SCsub new file mode 100644 index 000000000..9ef69eb09 --- /dev/null +++ b/modules/unit_test/SCsub @@ -0,0 +1,16 @@ +import os +import version + +Import('env') + +module_env = env.Clone() + +sources = [ + "register_types.cpp", + "unit_test.cpp", + "unit_test_db.cpp", + "unit_test_runner.cpp", +] + +module_env.add_source_files(env.modules_sources, sources) + diff --git a/modules/unit_test/config.py b/modules/unit_test/config.py new file mode 100644 index 000000000..44288195c --- /dev/null +++ b/modules/unit_test/config.py @@ -0,0 +1,19 @@ + +def can_build(env, platform): + return True + + +def configure(env): + pass + + +def get_doc_classes(): + return [ + "UnitTest", + "UnitTestDB", + "UnitTestRunner" + ] + +def get_doc_path(): + return "doc_classes" + diff --git a/modules/unit_test/register_types.cpp b/modules/unit_test/register_types.cpp new file mode 100644 index 000000000..e00af96b7 --- /dev/null +++ b/modules/unit_test/register_types.cpp @@ -0,0 +1,31 @@ + +#include "register_types.h" + +#include "core/config/engine.h" + +#include "unit_test.h" +#include "unit_test_db.h" +#include "unit_test_runner.h" + +static UnitTestDB *unit_test_manager = NULL; + +void register_unit_test_types(ModuleRegistrationLevel p_level) { + if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) { + unit_test_manager = memnew(UnitTestDB); + ClassDB::register_class(); + Engine::get_singleton()->add_singleton(Engine::Singleton("UnitTestDB", UnitTestDB::get_singleton())); + } + + if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) { + ClassDB::register_class(); + ClassDB::register_class(); + } +} + +void unregister_unit_test_types(ModuleRegistrationLevel p_level) { + if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) { + if (unit_test_manager) { + memdelete(unit_test_manager); + } + } +} diff --git a/modules/unit_test/register_types.h b/modules/unit_test/register_types.h new file mode 100644 index 000000000..83e040973 --- /dev/null +++ b/modules/unit_test/register_types.h @@ -0,0 +1,9 @@ +#ifndef UNIT_TEST_REGISTER_TYPES_H +#define UNIT_TEST_REGISTER_TYPES_H + +#include "modules/register_module_types.h" + +void register_unit_test_types(ModuleRegistrationLevel p_level); +void unregister_unit_test_types(ModuleRegistrationLevel p_level); + +#endif diff --git a/modules/unit_test/unit_test.cpp b/modules/unit_test/unit_test.cpp new file mode 100644 index 000000000..c07d44aac --- /dev/null +++ b/modules/unit_test/unit_test.cpp @@ -0,0 +1,10 @@ +#include "unit_test.h" + +UnitTest::UnitTest() { +} + +UnitTest::~UnitTest() { +} + +void UnitTest::_bind_methods() { +} diff --git a/modules/unit_test/unit_test.h b/modules/unit_test/unit_test.h new file mode 100644 index 000000000..282119bf5 --- /dev/null +++ b/modules/unit_test/unit_test.h @@ -0,0 +1,37 @@ +#ifndef UNIT_TEST_H +#define UNIT_TEST_H + +#include "core/string/ustring.h" + +#include "core/object/reference.h" + +class QueryResult; + +class UnitTest : public Reference { + GDCLASS(UnitTest, Reference); + +public: + // ThreadPoolJob like api + // asserts, prints, file check helpers, etc etc + // bool process() -> return true when finished + // bool _process() + + // assert(a == "b", "Testing whenther a == b") + // assert_equals(a, "b") ? -> could generate text automatically + + // process type: process, physics process + + //api to get results + + //ajutomatically count tests, and some data (process time, physics and normal iteration nums) + + //get_runner() -> returns runner + + UnitTest(); + virtual ~UnitTest(); + +protected: + static void _bind_methods(); +}; + +#endif diff --git a/modules/unit_test/unit_test_db.cpp b/modules/unit_test/unit_test_db.cpp new file mode 100644 index 000000000..861232af2 --- /dev/null +++ b/modules/unit_test/unit_test_db.cpp @@ -0,0 +1,20 @@ + +#include "unit_test_db.h" + +UnitTestDB *UnitTestDB::_instance; + +UnitTestDB *UnitTestDB::get_singleton() { + return _instance; +} + +UnitTestDB::UnitTestDB() { + _instance = this; +} + +UnitTestDB::~UnitTestDB() { + _instance = NULL; +} + +void UnitTestDB::_bind_methods() { + //ClassDB::bind_method(D_METHOD("", ""), &UnitTestDB::); +} diff --git a/modules/unit_test/unit_test_db.h b/modules/unit_test/unit_test_db.h new file mode 100644 index 000000000..dbbf7f9d6 --- /dev/null +++ b/modules/unit_test/unit_test_db.h @@ -0,0 +1,32 @@ +#ifndef UNIT_TEST_MANAGER_H +#define UNIT_TEST_MANAGER_H + +#include "core/object/object.h" + +class UnitTestDB : public Object { + GDCLASS(UnitTestDB, Object); + +public: + //UnitTests api + + //testing hint -> auto set (probably from main) if --test arg (should automatically set the scene root ast TestRunner eventually) + //main -> --test_engine, or --load_engine_tests or --register_engine_tests ? -> register module tests + //should probably have folders settings (also in project settings) -> only load them if necessary + + //api for registering unit tests manually -> keep them separate + + //api for getting all unit tests -> load everything from folders, append stuff manually registered -> return it + + static UnitTestDB *get_singleton(); + + UnitTestDB(); + ~UnitTestDB(); + +protected: + static void _bind_methods(); + +private: + static UnitTestDB *_instance; +}; + +#endif diff --git a/modules/unit_test/unit_test_runner.cpp b/modules/unit_test/unit_test_runner.cpp new file mode 100644 index 000000000..3feaa48ea --- /dev/null +++ b/modules/unit_test/unit_test_runner.cpp @@ -0,0 +1,11 @@ + +#include "unit_test_runner.h" + +UnitTestRunner::UnitTestRunner() { +} + +UnitTestRunner::~UnitTestRunner() { +} + +void UnitTestRunner::_bind_methods() { +} diff --git a/modules/unit_test/unit_test_runner.h b/modules/unit_test/unit_test_runner.h new file mode 100644 index 000000000..05c28801b --- /dev/null +++ b/modules/unit_test/unit_test_runner.h @@ -0,0 +1,21 @@ +#ifndef UNIT_TEST_RUNNER_H +#define UNIT_TEST_RUNNER_H + +#include "scene/main/node.h" + +class UnitTestRunner : public Node { + GDCLASS(UnitTestRunner, Node); + +public: + // after enter tree gets all tests from db, call process on them when one returns true, go to the next one, exit after done + + //should have api to easily get things that references can't get to easily but needed + + UnitTestRunner(); + ~UnitTestRunner(); + +protected: + static void _bind_methods(); +}; + +#endif