summaryrefslogtreecommitdiff
path: root/main/tests
diff options
context:
space:
mode:
Diffstat (limited to 'main/tests')
-rw-r--r--main/tests/test_gdscript.cpp58
-rw-r--r--main/tests/test_gui.h3
-rw-r--r--main/tests/test_image.cpp69
-rw-r--r--main/tests/test_image.h45
-rw-r--r--main/tests/test_main.cpp8
-rw-r--r--main/tests/test_math.cpp8
-rw-r--r--main/tests/test_oa_hash_map.cpp19
-rw-r--r--main/tests/test_physics.cpp1
-rw-r--r--main/tests/test_physics.h4
-rw-r--r--main/tests/test_render.h4
-rw-r--r--main/tests/test_shader_lang.cpp23
-rw-r--r--main/tests/test_string.cpp98
12 files changed, 158 insertions, 182 deletions
diff --git a/main/tests/test_gdscript.cpp b/main/tests/test_gdscript.cpp
index 60f9568fbd..b2b2c22bf9 100644
--- a/main/tests/test_gdscript.cpp
+++ b/main/tests/test_gdscript.cpp
@@ -127,6 +127,7 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
case GDScriptParser::OperatorNode::OP_PARENT_CALL:
txt += ".";
+ FALLTHROUGH;
case GDScriptParser::OperatorNode::OP_CALL: {
ERR_FAIL_COND_V(c_node->arguments.size() < 1, "");
@@ -283,24 +284,27 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
case GDScriptParser::OperatorNode::OP_BIT_XOR: {
txt = _parser_expr(c_node->arguments[0]) + "^" + _parser_expr(c_node->arguments[1]);
} break;
- default: {}
+ default: {
+ }
}
} break;
+ case GDScriptParser::Node::TYPE_CAST: {
+ const GDScriptParser::CastNode *cast_node = static_cast<const GDScriptParser::CastNode *>(p_expr);
+ txt = _parser_expr(cast_node->source_node) + " as " + cast_node->cast_type.to_string();
+
+ } break;
case GDScriptParser::Node::TYPE_NEWLINE: {
//skippie
} break;
default: {
- String error = "Parser bug at " + itos(p_expr->line) + ", invalid expression type: " + itos(p_expr->type);
- ERR_EXPLAIN(error);
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Parser bug at " + itos(p_expr->line) + ", invalid expression type: " + itos(p_expr->type));
}
}
return txt;
- //return "("+txt+")";
}
static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_indent) {
@@ -360,9 +364,6 @@ static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_i
case GDScriptParser::ControlFlowNode::CF_MATCH: {
// FIXME: Implement
} break;
- case GDScriptParser::ControlFlowNode::CF_SWITCH: {
-
- } break;
case GDScriptParser::ControlFlowNode::CF_CONTINUE: {
_print_indent(p_indent, "continue");
@@ -566,7 +567,7 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
case GDScriptFunction::OPCODE_OPERATOR: {
int op = code[ip + 1];
- txt += "op ";
+ txt += " op ";
String opname = Variant::get_operator_name(Variant::Operator(op));
@@ -670,6 +671,17 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
incr += 2;
} break;
+ case GDScriptFunction::OPCODE_CAST_TO_SCRIPT: {
+
+ txt += " cast ";
+ txt += DADDR(3);
+ txt += "=";
+ txt += DADDR(1);
+ txt += " as ";
+ txt += DADDR(2);
+ incr += 4;
+
+ } break;
case GDScriptFunction::OPCODE_CONSTRUCT: {
Variant::Type t = Variant::Type(code[ip + 1]);
@@ -895,8 +907,7 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
if (incr == 0) {
- ERR_EXPLAIN("unhandled opcode: " + itos(code[ip]));
- ERR_BREAK(incr == 0);
+ ERR_BREAK_MSG(true, "Unhandled opcode: " + itos(code[ip]));
}
ip += incr;
@@ -911,18 +922,17 @@ MainLoop *test(TestType p_type) {
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
if (cmdlargs.empty()) {
- //try editor!
return NULL;
}
String test = cmdlargs.back()->get();
+ if (!test.ends_with(".gd") && !test.ends_with(".gdc")) {
+ print_line("This test expects a path to a GDScript file as its last parameter. Got: " + test);
+ return NULL;
+ }
FileAccess *fa = FileAccess::open(test, FileAccess::READ);
-
- if (!fa) {
- ERR_EXPLAIN("Could not open file: " + test);
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!fa, NULL, "Could not open file: " + test);
Vector<uint8_t> buf;
int flen = fa->get_len();
@@ -956,7 +966,7 @@ MainLoop *test(TestType p_type) {
if (tk.get_token() == GDScriptTokenizer::TK_IDENTIFIER)
text = "'" + tk.get_token_identifier() + "' (identifier)";
else if (tk.get_token() == GDScriptTokenizer::TK_CONSTANT) {
- Variant c = tk.get_token_constant();
+ const Variant &c = tk.get_token_constant();
if (c.get_type() == Variant::STRING)
text = "\"" + String(c) + "\"";
else
@@ -1016,19 +1026,17 @@ MainLoop *test(TestType p_type) {
return NULL;
}
- GDScript *script = memnew(GDScript);
+ Ref<GDScript> gds;
+ gds.instance();
GDScriptCompiler gdc;
- err = gdc.compile(&parser, script);
+ err = gdc.compile(&parser, gds.ptr());
if (err) {
print_line("Compile Error:\n" + itos(gdc.get_error_line()) + ":" + itos(gdc.get_error_column()) + ":" + gdc.get_error());
- memdelete(script);
return NULL;
}
- Ref<GDScript> gds = Ref<GDScript>(script);
-
Ref<GDScript> current = gds;
while (current.is_valid()) {
@@ -1041,10 +1049,10 @@ MainLoop *test(TestType p_type) {
} else if (p_type == TEST_BYTECODE) {
- Vector<uint8_t> buf = GDScriptTokenizerBuffer::parse_code_string(code);
+ Vector<uint8_t> buf2 = GDScriptTokenizerBuffer::parse_code_string(code);
String dst = test.get_basename() + ".gdc";
FileAccess *fw = FileAccess::open(dst, FileAccess::WRITE);
- fw->store_buffer(buf.ptr(), buf.size());
+ fw->store_buffer(buf2.ptr(), buf2.size());
memdelete(fw);
}
diff --git a/main/tests/test_gui.h b/main/tests/test_gui.h
index 1752818981..075bc40aa7 100644
--- a/main/tests/test_gui.h
+++ b/main/tests/test_gui.h
@@ -33,9 +33,6 @@
#include "core/os/main_loop.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
namespace TestGUI {
MainLoop *test();
diff --git a/main/tests/test_image.cpp b/main/tests/test_image.cpp
deleted file mode 100644
index ee4f43bae0..0000000000
--- a/main/tests/test_image.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*************************************************************************/
-/* test_image.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* 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. */
-/*************************************************************************/
-
-#include "test_image.h"
-
-#include "core/io/image_loader.h"
-#include "core/math/math_funcs.h"
-#include "core/os/main_loop.h"
-#include "core/print_string.h"
-
-namespace TestImage {
-
-class TestMainLoop : public MainLoop {
-
- bool quit;
-
-public:
- virtual void input_event(const Ref<InputEvent> &p_event) {
- }
-
- virtual void init() {
-
- quit = false;
- }
- virtual bool iteration(float p_time) {
-
- return quit;
- }
-
- virtual bool idle(float p_time) {
- return quit;
- }
-
- virtual void finish() {
- }
-};
-
-MainLoop *test() {
-
- return memnew(TestMainLoop);
-}
-} // namespace TestImage
diff --git a/main/tests/test_image.h b/main/tests/test_image.h
deleted file mode 100644
index b9b3c0cb48..0000000000
--- a/main/tests/test_image.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* test_image.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* 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_IMAGE_H
-#define TEST_IMAGE_H
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
-#include "core/os/main_loop.h"
-
-namespace TestImage {
-
-MainLoop *test();
-}
-
-#endif
diff --git a/main/tests/test_main.cpp b/main/tests/test_main.cpp
index 49f5cc5a18..22f1d7319f 100644
--- a/main/tests/test_main.cpp
+++ b/main/tests/test_main.cpp
@@ -36,7 +36,6 @@
#include "test_astar.h"
#include "test_gdscript.h"
#include "test_gui.h"
-#include "test_image.h"
#include "test_math.h"
#include "test_oa_hash_map.h"
#include "test_ordered_hash_map.h"
@@ -61,7 +60,6 @@ const char **tests_get_names() {
"gd_parser",
"gd_compiler",
"gd_bytecode",
- "image",
"ordered_hash_map",
"astar",
NULL
@@ -134,11 +132,6 @@ MainLoop *test_main(String p_test, const List<String> &p_args) {
return TestGDScript::test(TestGDScript::TEST_BYTECODE);
}
- if (p_test == "image") {
-
- return TestImage::test();
- }
-
if (p_test == "ordered_hash_map") {
return TestOrderedHashMap::test();
@@ -149,6 +142,7 @@ MainLoop *test_main(String p_test, const List<String> &p_args) {
return TestAStar::test();
}
+ print_line("Unknown test: " + p_test);
return NULL;
}
diff --git a/main/tests/test_math.cpp b/main/tests/test_math.cpp
index a082abcaba..68ecb2b1b2 100644
--- a/main/tests/test_math.cpp
+++ b/main/tests/test_math.cpp
@@ -30,9 +30,9 @@
#include "test_math.h"
+#include "core/math/basis.h"
#include "core/math/camera_matrix.h"
#include "core/math/math_funcs.h"
-#include "core/math/matrix3.h"
#include "core/math/transform.h"
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
@@ -494,11 +494,7 @@ MainLoop *test() {
}
FileAccess *fa = FileAccess::open(test, FileAccess::READ);
-
- if (!fa) {
- ERR_EXPLAIN("Could not open file: " + test);
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!fa, NULL, "Could not open file: " + test);
Vector<uint8_t> buf;
int flen = fa->get_len();
diff --git a/main/tests/test_oa_hash_map.cpp b/main/tests/test_oa_hash_map.cpp
index 070420e432..bf5b4588ea 100644
--- a/main/tests/test_oa_hash_map.cpp
+++ b/main/tests/test_oa_hash_map.cpp
@@ -121,6 +121,25 @@ MainLoop *test() {
delete[] keys;
}
+ // regression test / test for issue related to #31402
+ {
+
+ OS::get_singleton()->print("test for issue #31402 started...\n");
+
+ const int num_test_values = 12;
+ int test_values[num_test_values] = { 0, 24, 48, 72, 96, 120, 144, 168, 192, 216, 240, 264 };
+
+ int dummy = 0;
+ OAHashMap<int, int> map;
+ map.clear();
+
+ for (int i = 0; i < num_test_values; ++i) {
+ map.set(test_values[i], dummy);
+ }
+
+ OS::get_singleton()->print("test for issue #31402 passed.\n");
+ }
+
return NULL;
}
} // namespace TestOAHashMap
diff --git a/main/tests/test_physics.cpp b/main/tests/test_physics.cpp
index 84f504a78d..6850c4d88a 100644
--- a/main/tests/test_physics.cpp
+++ b/main/tests/test_physics.cpp
@@ -329,7 +329,6 @@ public:
make_grid(5, 5, 2.5, 1, gxf);
test_fall();
quit = false;
- return;
}
virtual bool iteration(float p_time) {
diff --git a/main/tests/test_physics.h b/main/tests/test_physics.h
index 699e31f492..a281f669e0 100644
--- a/main/tests/test_physics.h
+++ b/main/tests/test_physics.h
@@ -31,10 +31,6 @@
#ifndef TEST_PHYSICS_H
#define TEST_PHYSICS_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/main_loop.h"
namespace TestPhysics {
diff --git a/main/tests/test_render.h b/main/tests/test_render.h
index 3810760b56..6dda57db5b 100644
--- a/main/tests/test_render.h
+++ b/main/tests/test_render.h
@@ -31,10 +31,6 @@
#ifndef TEST_RENDER_H
#define TEST_RENDER_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/main_loop.h"
namespace TestRender {
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index ebaf7fd602..d66e706b6f 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -110,7 +110,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
String ucode = "uniform ";
- ucode += _prestr(E->get().precission);
+ ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type);
ucode += " " + String(E->key());
@@ -137,7 +137,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
String vcode = "varying ";
- vcode += _prestr(E->get().precission);
+ vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + String(E->key());
@@ -149,11 +149,11 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
String header;
header = _typestr(fnode->return_type) + " " + fnode->name + "(";
- for (int i = 0; i < fnode->arguments.size(); i++) {
+ for (int j = 0; j < fnode->arguments.size(); j++) {
- if (i > 0)
+ if (j > 0)
header += ", ";
- header += _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + fnode->arguments[i].name;
+ header += _prestr(fnode->arguments[j].precision) + _typestr(fnode->arguments[j].type) + " " + fnode->arguments[j].name;
}
header += ")\n";
@@ -197,6 +197,13 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
case SL::Node::TYPE_VARIABLE_DECLARATION: {
// FIXME: Implement
} break;
+ case SL::Node::TYPE_ARRAY: {
+ SL::ArrayNode *vnode = (SL::ArrayNode *)p_node;
+ code = vnode->name;
+ } break;
+ case SL::Node::TYPE_ARRAY_DECLARATION: {
+ // FIXME: Implement
+ } break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;
return get_constant_text(cnode->datatype, cnode->values);
@@ -336,9 +343,9 @@ MainLoop *test() {
print_line("Error at line: " + rtos(sl.get_error_line()) + ": " + sl.get_error_text());
return NULL;
} else {
- String code;
- recreate_code(&code, sl.get_shader());
- print_line("code:\n\n" + code);
+ String code2;
+ recreate_code(&code2, sl.get_shader());
+ print_line("code:\n\n" + code2);
}
return NULL;
diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp
index 511646db0a..7a41880645 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -33,6 +33,7 @@
//#include "core/math/math_funcs.h"
#include "core/io/ip_address.h"
#include "core/os/os.h"
+#include "modules/regex/regex.h"
#include <stdio.h>
#include "test_string.h"
@@ -56,7 +57,7 @@ bool test_2() {
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
String s = "Dolly";
- String t = s;
+ const String &t = s;
OS::get_singleton()->print("\tExpected: Dolly\n");
OS::get_singleton()->print("\tResulted: %ls\n", t.c_str());
@@ -69,7 +70,7 @@ bool test_3() {
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
String s("Sheep");
- String t(s);
+ const String &t(s);
OS::get_singleton()->print("\tExpected: Sheep\n");
OS::get_singleton()->print("\tResulted: %ls\n", t.c_str());
@@ -429,9 +430,25 @@ bool test_25() {
bool test_26() {
- //TODO: Do replacement RegEx test
- return true;
-};
+ OS::get_singleton()->print("\n\nTest 26: RegEx substitution\n");
+
+#ifndef MODULE_REGEX_ENABLED
+ OS::get_singleton()->print("\tRegEx module disabled, can't run test.");
+ return false;
+#else
+ String s = "Double all the vowels.";
+
+ OS::get_singleton()->print("\tString: %ls\n", s.c_str());
+ OS::get_singleton()->print("\tRepeating instances of 'aeiou' once\n");
+
+ RegEx re("(?<vowel>[aeiou])");
+ s = re.sub(s, "$0$vowel", true);
+
+ OS::get_singleton()->print("\tResult: %ls\n", s.c_str());
+
+ return (s == "Doouublee aall thee vooweels.");
+#endif
+}
struct test_27_data {
char const *data;
@@ -457,7 +474,7 @@ bool test_27() {
state = s.begins_with(sb) == tc[i].expected;
}
if (!state) {
- OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n");
+ OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: %s\n\t\tbegin: %s\n\t\texpected: %s\n", tc[i].data, tc[i].begin, tc[i].expected ? "true" : "false");
break;
}
};
@@ -1005,8 +1022,8 @@ bool test_32() {
STRIP_TEST(String("abca").lstrip("a") == "bca");
STRIP_TEST(String("abc").rstrip("a") == "abc");
STRIP_TEST(String("abca").rstrip("a") == "abc");
- // in utf-8 "¿" has the same first byte as "µ"
- // and the same second as "ÿ"
+ // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5)
+ // and the same second as "ÿ" (\u00ff)
STRIP_TEST(String::utf8("¿").lstrip(String::utf8("µÿ")) == String::utf8("¿"));
STRIP_TEST(String::utf8("¿").rstrip(String::utf8("µÿ")) == String::utf8("¿"));
STRIP_TEST(String::utf8("µ¿ÿ").lstrip(String::utf8("µÿ")) == String::utf8("¿ÿ"));
@@ -1034,8 +1051,8 @@ bool test_32() {
STRIP_TEST(String("abca").lstrip("qwajkl") == "bca");
STRIP_TEST(String("abc").rstrip("qwajkl") == "abc");
STRIP_TEST(String("abca").rstrip("qwajkl") == "abc");
- // in utf-8 "¿" has the same first byte as "µ"
- // and the same second as "ÿ"
+ // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5)
+ // and the same second as "ÿ" (\u00ff)
STRIP_TEST(String::utf8("¿").lstrip(String::utf8("qwaµÿjkl")) == String::utf8("¿"));
STRIP_TEST(String::utf8("¿").rstrip(String::utf8("qwaµÿjkl")) == String::utf8("¿"));
STRIP_TEST(String::utf8("µ¿ÿ").lstrip(String::utf8("qwaµÿjkl")) == String::utf8("¿ÿ"));
@@ -1046,6 +1063,64 @@ bool test_32() {
#undef STRIP_TEST
}
+bool test_33() {
+ OS::get_singleton()->print("\n\nTest 33: parse_utf8(null, -1)\n");
+
+ String empty;
+ return empty.parse_utf8(NULL, -1);
+}
+
+bool test_34() {
+ OS::get_singleton()->print("\n\nTest 34: Cyrillic to_lower()\n");
+
+ String upper = String::utf8("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ");
+ String lower = String::utf8("абвгдеёжзийклмнопрстуфхцчшщъыьэюя");
+
+ String test = upper.to_lower();
+
+ bool state = test == lower;
+
+ return state;
+}
+
+bool test_35() {
+#define COUNT_TEST(x) \
+ { \
+ bool success = x; \
+ state = state && success; \
+ if (!success) { \
+ OS::get_singleton()->print("\tfailed at: %s\n", #x); \
+ } \
+ }
+
+ OS::get_singleton()->print("\n\nTest 35: count and countn function\n");
+ bool state = true;
+
+ 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);
+
+ return state;
+}
+
typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = {
@@ -1082,6 +1157,9 @@ TestFunc test_funcs[] = {
test_30,
test_31,
test_32,
+ test_33,
+ test_34,
+ test_35,
0
};