diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/core/object/test_class_db.h | 14 | ||||
-rw-r--r-- | tests/core/object/test_object.h | 2 | ||||
-rw-r--r-- | tests/core/os/test_os.h | 4 | ||||
-rw-r--r-- | tests/core/string/test_string.h | 290 | ||||
-rw-r--r-- | tests/core/templates/test_local_vector.h | 11 | ||||
-rw-r--r-- | tests/core/variant/test_dictionary.h | 2 | ||||
-rw-r--r-- | tests/scene/test_sprite_frames.h | 5 | ||||
-rw-r--r-- | tests/scene/test_timer.h | 217 | ||||
-rw-r--r-- | tests/test_macros.h | 67 | ||||
-rw-r--r-- | tests/test_main.cpp | 7 |
10 files changed, 462 insertions, 157 deletions
diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h index 5623c1d495..fb62d0f056 100644 --- a/tests/core/object/test_class_db.h +++ b/tests/core/object/test_class_db.h @@ -550,8 +550,6 @@ void add_exposed_classes(Context &r_context) { for (const MethodInfo &E : method_list) { const MethodInfo &method_info = E; - int argc = method_info.arguments.size(); - if (method_info.name.is_empty()) { continue; } @@ -613,8 +611,9 @@ void add_exposed_classes(Context &r_context) { method.return_type.name = Variant::get_type_name(return_info.type); } - for (int i = 0; i < argc; i++) { - PropertyInfo arg_info = method_info.arguments[i]; + int i = 0; + for (List<PropertyInfo>::ConstIterator itr = method_info.arguments.begin(); itr != method_info.arguments.end(); ++itr, ++i) { + const PropertyInfo &arg_info = *itr; String orig_arg_name = arg_info.name; @@ -686,10 +685,9 @@ void add_exposed_classes(Context &r_context) { TEST_FAIL_COND(!String(signal.name).is_valid_identifier(), "Signal name is not a valid identifier: '", exposed_class.name, ".", signal.name, "'."); - int argc = method_info.arguments.size(); - - for (int i = 0; i < argc; i++) { - PropertyInfo arg_info = method_info.arguments[i]; + int i = 0; + for (List<PropertyInfo>::ConstIterator itr = method_info.arguments.begin(); itr != method_info.arguments.end(); ++itr, ++i) { + const PropertyInfo &arg_info = *itr; String orig_arg_name = arg_info.name; diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 3a3013a102..d714d71416 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -142,7 +142,7 @@ TEST_CASE("[Object] Core getters") { inheritance_list.size() == 1, "The inheritance list should consist of Object only"); CHECK_MESSAGE( - inheritance_list[0] == "Object", + inheritance_list.front()->get() == "Object", "The inheritance list should consist of Object only"); } diff --git a/tests/core/os/test_os.h b/tests/core/os/test_os.h index 63f8b18238..6ee0ff82e7 100644 --- a/tests/core/os/test_os.h +++ b/tests/core/os/test_os.h @@ -79,8 +79,8 @@ TEST_CASE("[OS] Non-UTF-8 environment variables") { TEST_CASE("[OS] Command line arguments") { List<String> arguments = OS::get_singleton()->get_cmdline_args(); bool found = false; - for (int i = 0; i < arguments.size(); i++) { - if (arguments[i] == "--test") { + for (const String &arg : arguments) { + if (arg == "--test") { found = true; break; } diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 64f03e5879..18828c3b70 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -360,18 +360,37 @@ TEST_CASE("[String] Substr") { TEST_CASE("[String] Find") { String s = "Pretty Woman Woman"; - CHECK(s.find("tty") == 3); - CHECK(s.find("Wo", 9) == 13); - CHECK(s.find("Revenge of the Monster Truck") == -1); - CHECK(s.rfind("man") == 15); + MULTICHECK_STRING_EQ(s, find, "tty", 3); + MULTICHECK_STRING_EQ(s, find, "Revenge of the Monster Truck", -1); + MULTICHECK_STRING_INT_EQ(s, find, "Wo", 9, 13); + MULTICHECK_STRING_EQ(s, find, "", -1); + MULTICHECK_STRING_EQ(s, find, "Pretty Woman Woman", 0); + MULTICHECK_STRING_EQ(s, find, "WOMAN", -1); + MULTICHECK_STRING_INT_EQ(s, find, "", 9, -1); + + MULTICHECK_STRING_EQ(s, rfind, "", -1); + MULTICHECK_STRING_EQ(s, rfind, "foo", -1); + MULTICHECK_STRING_EQ(s, rfind, "Pretty Woman Woman", 0); + MULTICHECK_STRING_EQ(s, rfind, "man", 15); + MULTICHECK_STRING_EQ(s, rfind, "WOMAN", -1); + MULTICHECK_STRING_INT_EQ(s, rfind, "", 15, -1); } TEST_CASE("[String] Find no case") { String s = "Pretty Whale Whale"; - CHECK(s.findn("WHA") == 7); - CHECK(s.findn("WHA", 9) == 13); - CHECK(s.findn("Revenge of the Monster SawFish") == -1); - CHECK(s.rfindn("WHA") == 13); + MULTICHECK_STRING_EQ(s, findn, "WHA", 7); + MULTICHECK_STRING_INT_EQ(s, findn, "WHA", 9, 13); + MULTICHECK_STRING_EQ(s, findn, "Revenge of the Monster SawFish", -1); + MULTICHECK_STRING_EQ(s, findn, "", -1); + MULTICHECK_STRING_EQ(s, findn, "wha", 7); + MULTICHECK_STRING_EQ(s, findn, "Wha", 7); + MULTICHECK_STRING_INT_EQ(s, findn, "", 3, -1); + + MULTICHECK_STRING_EQ(s, rfindn, "WHA", 13); + MULTICHECK_STRING_EQ(s, rfindn, "", -1); + MULTICHECK_STRING_EQ(s, rfindn, "wha", 13); + MULTICHECK_STRING_EQ(s, rfindn, "Wha", 13); + MULTICHECK_STRING_INT_EQ(s, rfindn, "", 13, -1); } TEST_CASE("[String] Find MK") { @@ -392,11 +411,9 @@ TEST_CASE("[String] Find MK") { TEST_CASE("[String] Find and replace") { String s = "Happy Birthday, Anna!"; - s = s.replace("Birthday", "Halloween"); - CHECK(s == "Happy Halloween, Anna!"); - - s = s.replace_first("H", "W"); - CHECK(s == "Wappy Halloween, Anna!"); + MULTICHECK_STRING_STRING_EQ(s, replace, "Birthday", "Halloween", "Happy Halloween, Anna!"); + MULTICHECK_STRING_STRING_EQ(s, replace_first, "y", "Y", "HappY Birthday, Anna!"); + MULTICHECK_STRING_STRING_EQ(s, replacen, "Y", "Y", "HappY BirthdaY, Anna!"); } TEST_CASE("[String] Insertion") { @@ -557,51 +574,76 @@ TEST_CASE("[String] String to float") { TEST_CASE("[String] Slicing") { String s = "Mars,Jupiter,Saturn,Uranus"; - const char *slices[4] = { "Mars", "Jupiter", "Saturn", "Uranus" }; - for (int i = 0; i < s.get_slice_count(","); i++) { - CHECK(s.get_slice(",", i) == slices[i]); - } + MULTICHECK_GET_SLICE(s, ",", slices); +} + +TEST_CASE("[String] Begins with") { + // Test cases for true: + MULTICHECK_STRING_EQ(String("res://foobar"), begins_with, "res://", true); + MULTICHECK_STRING_EQ(String("abc"), begins_with, "abc", true); + MULTICHECK_STRING_EQ(String("abc"), begins_with, "", true); + MULTICHECK_STRING_EQ(String(""), begins_with, "", true); + + // Test cases for false: + MULTICHECK_STRING_EQ(String("res"), begins_with, "res://", false); + MULTICHECK_STRING_EQ(String("abcdef"), begins_with, "foo", false); + MULTICHECK_STRING_EQ(String("abc"), begins_with, "ax", false); + MULTICHECK_STRING_EQ(String(""), begins_with, "abc", false); + + // Test "const char *" version also with nullptr. + String s("foo"); + bool state = s.begins_with(nullptr) == false; + CHECK_MESSAGE(state, "nullptr check failed"); + + String empty(""); + state = empty.begins_with(nullptr) == false; + CHECK_MESSAGE(state, "nullptr check with empty string failed"); +} + +TEST_CASE("[String] Ends with") { + // Test cases for true: + MULTICHECK_STRING_EQ(String("res://foobar"), ends_with, "foobar", true); + MULTICHECK_STRING_EQ(String("abc"), ends_with, "abc", true); + MULTICHECK_STRING_EQ(String("abc"), ends_with, "", true); + MULTICHECK_STRING_EQ(String(""), ends_with, "", true); + + // Test cases for false: + MULTICHECK_STRING_EQ(String("res"), ends_with, "res://", false); + MULTICHECK_STRING_EQ(String("abcdef"), ends_with, "foo", false); + MULTICHECK_STRING_EQ(String("abc"), ends_with, "ax", false); + MULTICHECK_STRING_EQ(String(""), ends_with, "abc", false); + + // Test "const char *" version also with nullptr. + String s("foo"); + bool state = s.ends_with(nullptr) == false; + CHECK_MESSAGE(state, "nullptr check failed"); + + String empty(""); + state = empty.ends_with(nullptr) == false; + CHECK_MESSAGE(state, "nullptr check with empty string failed"); } TEST_CASE("[String] Splitting") { String s = "Mars,Jupiter,Saturn,Uranus"; - Vector<String> l; - const char *slices_l[3] = { "Mars", "Jupiter", "Saturn,Uranus" }; - const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" }; - const char *slices_3[4] = { "t", "e", "s", "t" }; - - l = s.split(",", true, 2); - CHECK(l.size() == 3); - for (int i = 0; i < l.size(); i++) { - CHECK(l[i] == slices_l[i]); - } + MULTICHECK_SPLIT(s, split, ",", true, 2, slices_l, 3); - l = s.rsplit(",", true, 2); - CHECK(l.size() == 3); - for (int i = 0; i < l.size(); i++) { - CHECK(l[i] == slices_r[i]); - } + const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" }; + MULTICHECK_SPLIT(s, rsplit, ",", true, 2, slices_r, 3); s = "test"; - l = s.split(); - CHECK(l.size() == 4); - for (int i = 0; i < l.size(); i++) { - CHECK(l[i] == slices_3[i]); - } + const char *slices_3[4] = { "t", "e", "s", "t" }; + MULTICHECK_SPLIT(s, split, "", true, 0, slices_3, 4); s = ""; - l = s.split(); - CHECK(l.size() == 1); - CHECK(l[0] == ""); - - l = s.split("", false); - CHECK(l.size() == 0); + const char *slices_4[1] = { "" }; + MULTICHECK_SPLIT(s, split, "", true, 0, slices_4, 1); + MULTICHECK_SPLIT(s, split, "", false, 0, slices_4, 0); s = "Mars Jupiter Saturn Uranus"; const char *slices_s[4] = { "Mars", "Jupiter", "Saturn", "Uranus" }; - l = s.split_spaces(); + Vector<String> l = s.split_spaces(); for (int i = 0; i < l.size(); i++) { CHECK(l[i] == slices_s[i]); } @@ -644,69 +686,6 @@ TEST_CASE("[String] Splitting") { } } -struct test_27_data { - char const *data; - char const *part; - bool expected; -}; - -TEST_CASE("[String] Begins with") { - test_27_data tc[] = { - // Test cases for true: - { "res://foobar", "res://", true }, - { "abc", "abc", true }, - { "abc", "", true }, - { "", "", true }, - // Test cases for false: - { "res", "res://", false }, - { "abcdef", "foo", false }, - { "abc", "ax", false }, - { "", "abc", false } - }; - size_t count = sizeof(tc) / sizeof(tc[0]); - bool state = true; - for (size_t i = 0; i < count; ++i) { - String s = tc[i].data; - state = s.begins_with(tc[i].part) == tc[i].expected; - CHECK_MESSAGE(state, "first check failed at: ", i); - - String sb = tc[i].part; - state = s.begins_with(sb) == tc[i].expected; - CHECK_MESSAGE(state, "second check failed at: ", i); - } - - // Test "const char *" version also with nullptr. - String s("foo"); - state = s.begins_with(nullptr) == false; - CHECK_MESSAGE(state, "nullptr check failed"); - - String empty(""); - state = empty.begins_with(nullptr) == false; - CHECK_MESSAGE(state, "nullptr check with empty string failed"); -} - -TEST_CASE("[String] Ends with") { - test_27_data tc[] = { - // test cases for true: - { "res://foobar", "foobar", true }, - { "abc", "abc", true }, - { "abc", "", true }, - { "", "", true }, - // test cases for false: - { "res", "res://", false }, - { "", "abc", false }, - { "abcdef", "foo", false }, - { "abc", "xc", false } - }; - size_t count = sizeof(tc) / sizeof(tc[0]); - for (size_t i = 0; i < count; ++i) { - String s = tc[i].data; - String sb = tc[i].part; - bool state = s.ends_with(sb) == tc[i].expected; - CHECK_MESSAGE(state, "check failed at: ", i); - } -} - TEST_CASE("[String] format") { const String value_format = "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\""; @@ -1498,39 +1477,62 @@ TEST_CASE("[String] Cyrillic to_lower()") { } TEST_CASE("[String] Count and countn functionality") { -#define COUNT_TEST(x) \ - { \ - bool success = x; \ - state = state && success; \ - } + String s = String(""); + MULTICHECK_STRING_EQ(s, count, "Test", 0); - bool state = true; + s = "Test"; + MULTICHECK_STRING_EQ(s, count, "", 0); - COUNT_TEST(String("").count("Test") == 0); - COUNT_TEST(String("Test").count("") == 0); - COUNT_TEST(String("Test").count("test") == 0); - COUNT_TEST(String("Test").count("TEST") == 0); - COUNT_TEST(String("TEST").count("TEST") == 1); - COUNT_TEST(String("Test").count("Test") == 1); - COUNT_TEST(String("aTest").count("Test") == 1); - COUNT_TEST(String("Testa").count("Test") == 1); - COUNT_TEST(String("TestTestTest").count("Test") == 3); - COUNT_TEST(String("TestTestTest").count("TestTest") == 1); - COUNT_TEST(String("TestGodotTestGodotTestGodot").count("Test") == 3); - - COUNT_TEST(String("TestTestTestTest").count("Test", 4, 8) == 1); - COUNT_TEST(String("TestTestTestTest").count("Test", 4, 12) == 2); - COUNT_TEST(String("TestTestTestTest").count("Test", 4, 16) == 3); - COUNT_TEST(String("TestTestTestTest").count("Test", 4) == 3); - - COUNT_TEST(String("Test").countn("test") == 1); - COUNT_TEST(String("Test").countn("TEST") == 1); - COUNT_TEST(String("testTest-Testatest").countn("tEst") == 4); - COUNT_TEST(String("testTest-TeStatest").countn("tEsT", 4, 16) == 2); + s = "Test"; + MULTICHECK_STRING_EQ(s, count, "test", 0); - CHECK(state); + s = "Test"; + MULTICHECK_STRING_EQ(s, count, "TEST", 0); + + s = "TEST"; + MULTICHECK_STRING_EQ(s, count, "TEST", 1); + + s = "Test"; + MULTICHECK_STRING_EQ(s, count, "Test", 1); + + s = "aTest"; + MULTICHECK_STRING_EQ(s, count, "Test", 1); + + s = "Testa"; + MULTICHECK_STRING_EQ(s, count, "Test", 1); + + s = "TestTestTest"; + MULTICHECK_STRING_EQ(s, count, "Test", 3); + + s = "TestTestTest"; + MULTICHECK_STRING_EQ(s, count, "TestTest", 1); + + s = "TestGodotTestGodotTestGodot"; + MULTICHECK_STRING_EQ(s, count, "Test", 3); + + s = "TestTestTestTest"; + MULTICHECK_STRING_INT_INT_EQ(s, count, "Test", 4, 8, 1); + + s = "TestTestTestTest"; + MULTICHECK_STRING_INT_INT_EQ(s, count, "Test", 4, 12, 2); + + s = "TestTestTestTest"; + MULTICHECK_STRING_INT_INT_EQ(s, count, "Test", 4, 16, 3); + + s = "TestTestTestTest"; + MULTICHECK_STRING_INT_EQ(s, count, "Test", 4, 3); + + s = "Test"; + MULTICHECK_STRING_EQ(s, countn, "test", 1); + + s = "Test"; + MULTICHECK_STRING_EQ(s, countn, "TEST", 1); + + s = "testTest-Testatest"; + MULTICHECK_STRING_EQ(s, countn, "tEst", 4); -#undef COUNT_TEST + s = "testTest-TeStatest"; + MULTICHECK_STRING_INT_INT_EQ(s, countn, "tEsT", 4, 16, 2); } TEST_CASE("[String] Bigrams") { @@ -1703,9 +1705,19 @@ TEST_CASE("[String] Strip edges") { TEST_CASE("[String] Trim") { String s = "aaaTestbbb"; - CHECK(s.trim_prefix("aaa") == "Testbbb"); - CHECK(s.trim_suffix("bbb") == "aaaTest"); - CHECK(s.trim_suffix("Test") == s); + MULTICHECK_STRING_EQ(s, trim_prefix, "aaa", "Testbbb"); + MULTICHECK_STRING_EQ(s, trim_prefix, "Test", s); + MULTICHECK_STRING_EQ(s, trim_prefix, "", s); + MULTICHECK_STRING_EQ(s, trim_prefix, "aaaTestbbb", ""); + MULTICHECK_STRING_EQ(s, trim_prefix, "bbb", s); + MULTICHECK_STRING_EQ(s, trim_prefix, "AAA", s); + + MULTICHECK_STRING_EQ(s, trim_suffix, "bbb", "aaaTest"); + MULTICHECK_STRING_EQ(s, trim_suffix, "Test", s); + MULTICHECK_STRING_EQ(s, trim_suffix, "", s); + MULTICHECK_STRING_EQ(s, trim_suffix, "aaaTestbbb", ""); + MULTICHECK_STRING_EQ(s, trim_suffix, "aaa", s); + MULTICHECK_STRING_EQ(s, trim_suffix, "BBB", s); } TEST_CASE("[String] Right/Left") { diff --git a/tests/core/templates/test_local_vector.h b/tests/core/templates/test_local_vector.h index 2873a9a028..c9544c625b 100644 --- a/tests/core/templates/test_local_vector.h +++ b/tests/core/templates/test_local_vector.h @@ -63,7 +63,7 @@ TEST_CASE("[LocalVector] Push Back.") { CHECK(vector[4] == 4); } -TEST_CASE("[LocalVector] Find.") { +TEST_CASE("[LocalVector] Find, has.") { LocalVector<int> vector; vector.push_back(3); vector.push_back(1); @@ -85,6 +85,15 @@ TEST_CASE("[LocalVector] Find.") { CHECK(vector.find(-1) == -1); CHECK(vector.find(5) == -1); + + CHECK(vector.has(0)); + CHECK(vector.has(1)); + CHECK(vector.has(2)); + CHECK(vector.has(3)); + CHECK(vector.has(4)); + + CHECK(!vector.has(-1)); + CHECK(!vector.has(5)); } TEST_CASE("[LocalVector] Remove.") { diff --git a/tests/core/variant/test_dictionary.h b/tests/core/variant/test_dictionary.h index 5bc56075da..aba20972d9 100644 --- a/tests/core/variant/test_dictionary.h +++ b/tests/core/variant/test_dictionary.h @@ -105,7 +105,7 @@ TEST_CASE("[Dictionary] get_key_lists()") { map[1] = 3; map.get_key_list(ptr); CHECK(keys.size() == 1); - CHECK(int(keys[0]) == 1); + CHECK(int(keys.front()->get()) == 1); map[2] = 4; map.get_key_list(ptr); CHECK(keys.size() == 3); diff --git a/tests/scene/test_sprite_frames.h b/tests/scene/test_sprite_frames.h index bf127cd42c..55854b90e4 100644 --- a/tests/scene/test_sprite_frames.h +++ b/tests/scene/test_sprite_frames.h @@ -74,9 +74,10 @@ TEST_CASE("[SpriteFrames] Animation addition, list getter, renaming, removal, an sname_list.size() == test_names.size(), "StringName List getter returned list of expected size"); - for (int i = 0; i < test_names.size(); i++) { + int idx = 0; + for (List<StringName>::ConstIterator itr = sname_list.begin(); itr != sname_list.end(); ++itr, ++idx) { CHECK_MESSAGE( - sname_list[i] == StringName(test_names[i]), + *itr == StringName(test_names[idx]), "StringName List getter returned expected values"); } diff --git a/tests/scene/test_timer.h b/tests/scene/test_timer.h new file mode 100644 index 0000000000..913ed92de5 --- /dev/null +++ b/tests/scene/test_timer.h @@ -0,0 +1,217 @@ +/**************************************************************************/ +/* test_timer.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef TEST_TIMER_H +#define TEST_TIMER_H + +#include "scene/main/timer.h" + +#include "tests/test_macros.h" + +namespace TestTimer { + +TEST_CASE("[SceneTree][Timer] Check Timer Setters and Getters") { + Timer *test_timer = memnew(Timer); + + SUBCASE("[Timer] Timer set and get wait time") { + // check default + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 1.0)); + + test_timer->set_wait_time(50.0); + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 50.0)); + + test_timer->set_wait_time(42.0); + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 42.0)); + + // wait time remains unchanged if we attempt to set it negative or zero + ERR_PRINT_OFF; + test_timer->set_wait_time(-22.0); + ERR_PRINT_ON; + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 42.0)); + + ERR_PRINT_OFF; + test_timer->set_wait_time(0.0); + ERR_PRINT_ON; + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 42.0)); + } + + SUBCASE("[Timer] Timer set and get one shot") { + // check default + CHECK(test_timer->is_one_shot() == false); + + test_timer->set_one_shot(true); + CHECK(test_timer->is_one_shot() == true); + + test_timer->set_one_shot(false); + CHECK(test_timer->is_one_shot() == false); + } + + SUBCASE("[Timer] Timer set and get autostart") { + // check default + CHECK(test_timer->has_autostart() == false); + + test_timer->set_autostart(true); + CHECK(test_timer->has_autostart() == true); + + test_timer->set_autostart(false); + CHECK(test_timer->has_autostart() == false); + } + + SUBCASE("[Timer] Timer start and stop") { + test_timer->set_autostart(false); + } + + SUBCASE("[Timer] Timer set and get paused") { + // check default + CHECK(test_timer->is_paused() == false); + + test_timer->set_paused(true); + CHECK(test_timer->is_paused() == true); + + test_timer->set_paused(false); + CHECK(test_timer->is_paused() == false); + } + + memdelete(test_timer); +} + +TEST_CASE("[SceneTree][Timer] Check Timer Start and Stop") { + Timer *test_timer = memnew(Timer); + + SUBCASE("[Timer] Timer start and stop") { + SceneTree::get_singleton()->get_root()->add_child(test_timer); + + test_timer->start(5.0); + + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 5.0)); + CHECK(Math::is_equal_approx(test_timer->get_time_left(), 5.0)); + + test_timer->start(-2.0); + + // the wait time and time left remains unchanged when started with a negative start time + CHECK(Math::is_equal_approx(test_timer->get_wait_time(), 5.0)); + CHECK(Math::is_equal_approx(test_timer->get_time_left(), 5.0)); + + test_timer->stop(); + CHECK(test_timer->is_processing() == false); + CHECK(test_timer->has_autostart() == false); + } + + memdelete(test_timer); +} + +TEST_CASE("[SceneTree][Timer] Check Timer process callback") { + Timer *test_timer = memnew(Timer); + + SUBCASE("[Timer] Timer process callback") { + // check default + CHECK(test_timer->get_timer_process_callback() == Timer::TimerProcessCallback::TIMER_PROCESS_IDLE); + + test_timer->set_timer_process_callback(Timer::TimerProcessCallback::TIMER_PROCESS_PHYSICS); + CHECK(test_timer->get_timer_process_callback() == Timer::TimerProcessCallback::TIMER_PROCESS_PHYSICS); + + test_timer->set_timer_process_callback(Timer::TimerProcessCallback::TIMER_PROCESS_IDLE); + CHECK(test_timer->get_timer_process_callback() == Timer::TimerProcessCallback::TIMER_PROCESS_IDLE); + } + + memdelete(test_timer); +} + +TEST_CASE("[SceneTree][Timer] Check Timer timeout signal") { + Timer *test_timer = memnew(Timer); + SceneTree::get_singleton()->get_root()->add_child(test_timer); + + test_timer->set_process(true); + test_timer->set_physics_process(true); + + SUBCASE("[Timer] Timer process timeout signal must be emitted") { + SIGNAL_WATCH(test_timer, SNAME("timeout")); + test_timer->start(0.1); + + SceneTree::get_singleton()->process(0.2); + + Array signal_args; + signal_args.push_back(Array()); + + SIGNAL_CHECK(SNAME("timeout"), signal_args); + + SIGNAL_UNWATCH(test_timer, SNAME("timeout")); + } + + SUBCASE("[Timer] Timer process timeout signal must not be emitted") { + SIGNAL_WATCH(test_timer, SNAME("timeout")); + test_timer->start(0.1); + + SceneTree::get_singleton()->process(0.05); + + Array signal_args; + signal_args.push_back(Array()); + + SIGNAL_CHECK_FALSE(SNAME("timeout")); + + SIGNAL_UNWATCH(test_timer, SNAME("timeout")); + } + + test_timer->set_timer_process_callback(Timer::TimerProcessCallback::TIMER_PROCESS_PHYSICS); + + SUBCASE("[Timer] Timer physics process timeout signal must be emitted") { + SIGNAL_WATCH(test_timer, SNAME("timeout")); + test_timer->start(0.1); + + SceneTree::get_singleton()->physics_process(0.2); + + Array signal_args; + signal_args.push_back(Array()); + + SIGNAL_CHECK(SNAME("timeout"), signal_args); + + SIGNAL_UNWATCH(test_timer, SNAME("timeout")); + } + + SUBCASE("[Timer] Timer physics process timeout signal must not be emitted") { + SIGNAL_WATCH(test_timer, SNAME("timeout")); + test_timer->start(0.1); + + SceneTree::get_singleton()->physics_process(0.05); + + Array signal_args; + signal_args.push_back(Array()); + + SIGNAL_CHECK_FALSE(SNAME("timeout")); + + SIGNAL_UNWATCH(test_timer, SNAME("timeout")); + } + + memdelete(test_timer); +} + +} // namespace TestTimer + +#endif // TEST_TIMER_H diff --git a/tests/test_macros.h b/tests/test_macros.h index 25e48c1e05..10f4c59a90 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -406,4 +406,71 @@ public: #define SIGNAL_CHECK_FALSE(m_signal) CHECK(SignalWatcher::get_singleton()->check_false(m_signal)); #define SIGNAL_DISCARD(m_signal) SignalWatcher::get_singleton()->discard_signal(m_signal); +#define MULTICHECK_STRING_EQ(m_obj, m_func, m_param1, m_eq) \ + CHECK(m_obj.m_func(m_param1) == m_eq); \ + CHECK(m_obj.m_func(U##m_param1) == m_eq); \ + CHECK(m_obj.m_func(L##m_param1) == m_eq); \ + CHECK(m_obj.m_func(String(m_param1)) == m_eq); + +#define MULTICHECK_STRING_INT_EQ(m_obj, m_func, m_param1, m_param2, m_eq) \ + CHECK(m_obj.m_func(m_param1, m_param2) == m_eq); \ + CHECK(m_obj.m_func(U##m_param1, m_param2) == m_eq); \ + CHECK(m_obj.m_func(L##m_param1, m_param2) == m_eq); \ + CHECK(m_obj.m_func(String(m_param1), m_param2) == m_eq); + +#define MULTICHECK_STRING_INT_INT_EQ(m_obj, m_func, m_param1, m_param2, m_param3, m_eq) \ + CHECK(m_obj.m_func(m_param1, m_param2, m_param3) == m_eq); \ + CHECK(m_obj.m_func(U##m_param1, m_param2, m_param3) == m_eq); \ + CHECK(m_obj.m_func(L##m_param1, m_param2, m_param3) == m_eq); \ + CHECK(m_obj.m_func(String(m_param1), m_param2, m_param3) == m_eq); + +#define MULTICHECK_STRING_STRING_EQ(m_obj, m_func, m_param1, m_param2, m_eq) \ + CHECK(m_obj.m_func(m_param1, m_param2) == m_eq); \ + CHECK(m_obj.m_func(U##m_param1, U##m_param2) == m_eq); \ + CHECK(m_obj.m_func(L##m_param1, L##m_param2) == m_eq); \ + CHECK(m_obj.m_func(String(m_param1), String(m_param2)) == m_eq); + +#define MULTICHECK_GET_SLICE(m_obj, m_param1, m_slices) \ + for (int i = 0; i < m_obj.get_slice_count(m_param1); ++i) { \ + CHECK(m_obj.get_slice(m_param1, i) == m_slices[i]); \ + } \ + for (int i = 0; i < m_obj.get_slice_count(U##m_param1); ++i) { \ + CHECK(m_obj.get_slice(U##m_param1, i) == m_slices[i]); \ + } \ + for (int i = 0; i < m_obj.get_slice_count(L##m_param1); ++i) { \ + CHECK(m_obj.get_slice(L##m_param1, i) == m_slices[i]); \ + } \ + for (int i = 0; i < m_obj.get_slice_count(String(m_param1)); ++i) { \ + CHECK(m_obj.get_slice(String(m_param1), i) == m_slices[i]); \ + } + +#define MULTICHECK_SPLIT(m_obj, m_func, m_param1, m_param2, m_param3, m_slices, m_expected_size) \ + do { \ + Vector<String> string_list; \ + \ + string_list = m_obj.m_func(m_param1, m_param2, m_param3); \ + CHECK(m_expected_size == string_list.size()); \ + for (int i = 0; i < string_list.size(); ++i) { \ + CHECK(string_list[i] == m_slices[i]); \ + } \ + \ + string_list = m_obj.m_func(U##m_param1, m_param2, m_param3); \ + CHECK(m_expected_size == string_list.size()); \ + for (int i = 0; i < string_list.size(); ++i) { \ + CHECK(string_list[i] == m_slices[i]); \ + } \ + \ + string_list = m_obj.m_func(L##m_param1, m_param2, m_param3); \ + CHECK(m_expected_size == string_list.size()); \ + for (int i = 0; i < string_list.size(); ++i) { \ + CHECK(string_list[i] == m_slices[i]); \ + } \ + \ + string_list = m_obj.m_func(String(m_param1), m_param2, m_param3); \ + CHECK(m_expected_size == string_list.size()); \ + for (int i = 0; i < string_list.size(); ++i) { \ + CHECK(string_list[i] == m_slices[i]); \ + } \ + } while (0) + #endif // TEST_MACROS_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 56bd8739c6..69d8113e64 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -118,6 +118,7 @@ #include "tests/scene/test_sprite_frames.h" #include "tests/scene/test_text_edit.h" #include "tests/scene/test_theme.h" +#include "tests/scene/test_timer.h" #include "tests/scene/test_viewport.h" #include "tests/scene/test_visual_shader.h" #include "tests/scene/test_window.h" @@ -187,7 +188,7 @@ int test_main(int argc, char *argv[]) { } // Doctest runner. doctest::Context test_context; - List<String> test_args; + LocalVector<String> test_args; // Clean arguments of "--test" from the args. for (int x = 0; x < argc; x++) { @@ -200,7 +201,7 @@ int test_main(int argc, char *argv[]) { if (test_args.size() > 0) { // Convert Godot command line arguments back to standard arguments. char **doctest_args = new char *[test_args.size()]; - for (int x = 0; x < test_args.size(); x++) { + for (uint32_t x = 0; x < test_args.size(); x++) { // Operation to convert Godot string to non wchar string. CharString cs = test_args[x].utf8(); const char *str = cs.get_data(); @@ -212,7 +213,7 @@ int test_main(int argc, char *argv[]) { test_context.applyCommandLine(test_args.size(), doctest_args); - for (int x = 0; x < test_args.size(); x++) { + for (uint32_t x = 0; x < test_args.size(); x++) { delete[] doctest_args[x]; } delete[] doctest_args; |