summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/SCsub3
-rw-r--r--tests/core/io/test_packet_peer.h204
-rw-r--r--tests/core/io/test_stream_peer.h289
-rw-r--r--tests/core/io/test_stream_peer_buffer.h185
-rw-r--r--tests/core/string/test_string.h71
-rw-r--r--tests/scene/test_code_edit.h25
-rw-r--r--tests/scene/test_physics_material.h107
-rw-r--r--tests/scene/test_sky.h141
-rw-r--r--tests/scene/test_text_edit.h48
-rw-r--r--tests/scene/test_viewport.h7
-rw-r--r--tests/test_main.cpp13
11 files changed, 1091 insertions, 2 deletions
diff --git a/tests/SCsub b/tests/SCsub
index d96a1142e4..169c7c1efa 100644
--- a/tests/SCsub
+++ b/tests/SCsub
@@ -1,4 +1,5 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+from misc.utility.scons_hints import *
Import("env")
diff --git a/tests/core/io/test_packet_peer.h b/tests/core/io/test_packet_peer.h
new file mode 100644
index 0000000000..59c8dadad8
--- /dev/null
+++ b/tests/core/io/test_packet_peer.h
@@ -0,0 +1,204 @@
+/**************************************************************************/
+/* test_packet_peer.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_PACKET_PEER_H
+#define TEST_PACKET_PEER_H
+
+#include "core/io/packet_peer.h"
+#include "tests/test_macros.h"
+
+namespace TestPacketPeer {
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Encode buffer max size") {
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+
+ SUBCASE("Default value") {
+ CHECK_EQ(pps->get_encode_buffer_max_size(), 8 * 1024 * 1024);
+ }
+
+ SUBCASE("Max encode buffer must be at least 1024 bytes") {
+ ERR_PRINT_OFF;
+ pps->set_encode_buffer_max_size(42);
+ ERR_PRINT_ON;
+
+ CHECK_EQ(pps->get_encode_buffer_max_size(), 8 * 1024 * 1024);
+ }
+
+ SUBCASE("Max encode buffer cannot exceed 256 MiB") {
+ ERR_PRINT_OFF;
+ pps->set_encode_buffer_max_size((256 * 1024 * 1024) + 42);
+ ERR_PRINT_ON;
+
+ CHECK_EQ(pps->get_encode_buffer_max_size(), 8 * 1024 * 1024);
+ }
+
+ SUBCASE("Should be next power of two") {
+ pps->set_encode_buffer_max_size(2000);
+
+ CHECK_EQ(pps->get_encode_buffer_max_size(), 2048);
+ }
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Read a variant from peer") {
+ String godot_rules = "Godot Rules!!!";
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ spb->put_var(godot_rules);
+ spb->seek(0);
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+
+ Variant value;
+ CHECK_EQ(pps->get_var(value), Error::OK);
+ CHECK_EQ(String(value), godot_rules);
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Read a variant from peer fails") {
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+
+ Variant value;
+ ERR_PRINT_OFF;
+ CHECK_EQ(pps->get_var(value), Error::ERR_UNCONFIGURED);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Put a variant to peer") {
+ String godot_rules = "Godot Rules!!!";
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+
+ CHECK_EQ(pps->put_var(godot_rules), Error::OK);
+
+ spb->seek(0);
+ CHECK_EQ(String(spb->get_var()), godot_rules);
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Put a variant to peer out of memory failure") {
+ String more_than_1mb = String("*").repeat(1024 + 1);
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+ pps->set_encode_buffer_max_size(1024);
+
+ ERR_PRINT_OFF;
+ CHECK_EQ(pps->put_var(more_than_1mb), Error::ERR_OUT_OF_MEMORY);
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Get packet buffer") {
+ String godot_rules = "Godot Rules!!!";
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ // First 4 bytes are the length of the string.
+ CharString cs = godot_rules.ascii();
+ Vector<uint8_t> buffer = { (uint8_t)(cs.length() + 1), 0, 0, 0 };
+ buffer.resize_zeroed(4 + cs.length() + 1);
+ memcpy(buffer.ptrw() + 4, cs.get_data(), cs.length());
+ spb->set_data_array(buffer);
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+
+ buffer.clear();
+ CHECK_EQ(pps->get_packet_buffer(buffer), Error::OK);
+
+ CHECK_EQ(String(reinterpret_cast<const char *>(buffer.ptr())), godot_rules);
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Get packet buffer from an empty peer") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+
+ Vector<uint8_t> buffer;
+ ERR_PRINT_OFF;
+ CHECK_EQ(pps->get_packet_buffer(buffer), Error::ERR_UNAVAILABLE);
+ ERR_PRINT_ON;
+ CHECK_EQ(buffer.size(), 0);
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Put packet buffer") {
+ String godot_rules = "Godot Rules!!!";
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+
+ CHECK_EQ(pps->put_packet_buffer(godot_rules.to_ascii_buffer()), Error::OK);
+
+ spb->seek(0);
+ CHECK_EQ(spb->get_string(), godot_rules);
+ // First 4 bytes are the length of the string.
+ CharString cs = godot_rules.ascii();
+ Vector<uint8_t> buffer = { (uint8_t)cs.length(), 0, 0, 0 };
+ buffer.resize(4 + cs.length());
+ memcpy(buffer.ptrw() + 4, cs.get_data(), cs.length());
+ CHECK_EQ(spb->get_data_array(), buffer);
+}
+
+TEST_CASE("[PacketPeer][PacketPeerStream] Put packet buffer when is empty") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ Ref<PacketPeerStream> pps;
+ pps.instantiate();
+ pps->set_stream_peer(spb);
+
+ Vector<uint8_t> buffer;
+ CHECK_EQ(pps->put_packet_buffer(buffer), Error::OK);
+
+ CHECK_EQ(spb->get_size(), 0);
+}
+
+} // namespace TestPacketPeer
+
+#endif // TEST_PACKET_PEER_H
diff --git a/tests/core/io/test_stream_peer.h b/tests/core/io/test_stream_peer.h
new file mode 100644
index 0000000000..31bd69edd0
--- /dev/null
+++ b/tests/core/io/test_stream_peer.h
@@ -0,0 +1,289 @@
+/**************************************************************************/
+/* test_stream_peer.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_STREAM_PEER_H
+#define TEST_STREAM_PEER_H
+
+#include "core/io/stream_peer.h"
+#include "tests/test_macros.h"
+
+namespace TestStreamPeer {
+
+TEST_CASE("[StreamPeer] Initialization through StreamPeerBuffer") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ CHECK_EQ(spb->is_big_endian_enabled(), false);
+}
+
+TEST_CASE("[StreamPeer] Get and sets through StreamPeerBuffer") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ SUBCASE("A int8_t value") {
+ int8_t value = 42;
+
+ spb->clear();
+ spb->put_8(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_8(), value);
+ }
+
+ SUBCASE("A uint8_t value") {
+ uint8_t value = 42;
+
+ spb->clear();
+ spb->put_u8(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u8(), value);
+ }
+
+ SUBCASE("A int16_t value") {
+ int16_t value = 42;
+
+ spb->clear();
+ spb->put_16(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_16(), value);
+ }
+
+ SUBCASE("A uint16_t value") {
+ uint16_t value = 42;
+
+ spb->clear();
+ spb->put_u16(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u16(), value);
+ }
+
+ SUBCASE("A int32_t value") {
+ int32_t value = 42;
+
+ spb->clear();
+ spb->put_32(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_32(), value);
+ }
+
+ SUBCASE("A uint32_t value") {
+ uint32_t value = 42;
+
+ spb->clear();
+ spb->put_u32(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u32(), value);
+ }
+
+ SUBCASE("A int64_t value") {
+ int64_t value = 42;
+
+ spb->clear();
+ spb->put_64(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_64(), value);
+ }
+
+ SUBCASE("A int64_t value") {
+ uint64_t value = 42;
+
+ spb->clear();
+ spb->put_u64(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u64(), value);
+ }
+
+ SUBCASE("A float value") {
+ float value = 42.0f;
+
+ spb->clear();
+ spb->put_float(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_float(), value);
+ }
+
+ SUBCASE("A double value") {
+ double value = 42.0;
+
+ spb->clear();
+ spb->put_double(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_double(), value);
+ }
+
+ SUBCASE("A string value") {
+ String value = "Hello, World!";
+
+ spb->clear();
+ spb->put_string(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_string(), value);
+ }
+
+ SUBCASE("A utf8 string value") {
+ String value = String::utf8("Hello✩, World✩!");
+
+ spb->clear();
+ spb->put_utf8_string(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_utf8_string(), value);
+ }
+
+ SUBCASE("A variant value") {
+ Array value;
+ value.push_front(42);
+ value.push_front("Hello, World!");
+
+ spb->clear();
+ spb->put_var(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_var(), value);
+ }
+}
+
+TEST_CASE("[StreamPeer] Get and sets big endian through StreamPeerBuffer") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ spb->set_big_endian(true);
+
+ SUBCASE("A int16_t value") {
+ int16_t value = 42;
+
+ spb->clear();
+ spb->put_16(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_16(), value);
+ }
+
+ SUBCASE("A uint16_t value") {
+ uint16_t value = 42;
+
+ spb->clear();
+ spb->put_u16(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u16(), value);
+ }
+
+ SUBCASE("A int32_t value") {
+ int32_t value = 42;
+
+ spb->clear();
+ spb->put_32(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_32(), value);
+ }
+
+ SUBCASE("A uint32_t value") {
+ uint32_t value = 42;
+
+ spb->clear();
+ spb->put_u32(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u32(), value);
+ }
+
+ SUBCASE("A int64_t value") {
+ int64_t value = 42;
+
+ spb->clear();
+ spb->put_64(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_64(), value);
+ }
+
+ SUBCASE("A int64_t value") {
+ uint64_t value = 42;
+
+ spb->clear();
+ spb->put_u64(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_u64(), value);
+ }
+
+ SUBCASE("A float value") {
+ float value = 42.0f;
+
+ spb->clear();
+ spb->put_float(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_float(), value);
+ }
+
+ SUBCASE("A double value") {
+ double value = 42.0;
+
+ spb->clear();
+ spb->put_double(value);
+ spb->seek(0);
+
+ CHECK_EQ(spb->get_double(), value);
+ }
+}
+
+TEST_CASE("[StreamPeer] Get string when there is no string") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ ERR_PRINT_OFF;
+ CHECK_EQ(spb->get_string(), "");
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[StreamPeer] Get UTF8 string when there is no string") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+
+ ERR_PRINT_OFF;
+ CHECK_EQ(spb->get_utf8_string(), "");
+ ERR_PRINT_ON;
+}
+
+} // namespace TestStreamPeer
+
+#endif // TEST_STREAM_PEER_H
diff --git a/tests/core/io/test_stream_peer_buffer.h b/tests/core/io/test_stream_peer_buffer.h
new file mode 100644
index 0000000000..8ba9c0a72c
--- /dev/null
+++ b/tests/core/io/test_stream_peer_buffer.h
@@ -0,0 +1,185 @@
+/**************************************************************************/
+/* test_stream_peer_buffer.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_STREAM_PEER_BUFFER_H
+#define TEST_STREAM_PEER_BUFFER_H
+
+#include "core/io/stream_peer.h"
+#include "tests/test_macros.h"
+
+namespace TestStreamPeerBuffer {
+
+TEST_CASE("[StreamPeerBuffer] Initialization") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ CHECK_EQ(spb->get_size(), 0);
+ CHECK_EQ(spb->get_position(), 0);
+ CHECK_EQ(spb->get_available_bytes(), 0);
+}
+
+TEST_CASE("[StreamPeerBuffer] Seek") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ uint8_t first = 5;
+ uint8_t second = 7;
+ uint8_t third = 11;
+
+ spb->put_u8(first);
+ spb->put_u8(second);
+ spb->put_u8(third);
+
+ spb->seek(0);
+ CHECK_EQ(spb->get_u8(), first);
+ CHECK_EQ(spb->get_u8(), second);
+ CHECK_EQ(spb->get_u8(), third);
+
+ spb->seek(1);
+ CHECK_EQ(spb->get_position(), 1);
+ CHECK_EQ(spb->get_u8(), second);
+
+ spb->seek(1);
+ ERR_PRINT_OFF;
+ spb->seek(-1);
+ ERR_PRINT_ON;
+ CHECK_EQ(spb->get_position(), 1);
+ ERR_PRINT_OFF;
+ spb->seek(5);
+ ERR_PRINT_ON;
+ CHECK_EQ(spb->get_position(), 1);
+}
+
+TEST_CASE("[StreamPeerBuffer] Resize") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ CHECK_EQ(spb->get_size(), 0);
+ CHECK_EQ(spb->get_position(), 0);
+ CHECK_EQ(spb->get_available_bytes(), 0);
+
+ spb->resize(42);
+ CHECK_EQ(spb->get_size(), 42);
+ CHECK_EQ(spb->get_position(), 0);
+ CHECK_EQ(spb->get_available_bytes(), 42);
+
+ spb->seek(21);
+ CHECK_EQ(spb->get_size(), 42);
+ CHECK_EQ(spb->get_position(), 21);
+ CHECK_EQ(spb->get_available_bytes(), 21);
+}
+
+TEST_CASE("[StreamPeerBuffer] Get underlying data array") {
+ uint8_t first = 5;
+ uint8_t second = 7;
+ uint8_t third = 11;
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ spb->put_u8(first);
+ spb->put_u8(second);
+ spb->put_u8(third);
+
+ Vector<uint8_t> data_array = spb->get_data_array();
+
+ CHECK_EQ(data_array[0], first);
+ CHECK_EQ(data_array[1], second);
+ CHECK_EQ(data_array[2], third);
+}
+
+TEST_CASE("[StreamPeerBuffer] Set underlying data array") {
+ uint8_t first = 5;
+ uint8_t second = 7;
+ uint8_t third = 11;
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ spb->put_u8(1);
+ spb->put_u8(2);
+ spb->put_u8(3);
+
+ Vector<uint8_t> new_data_array;
+ new_data_array.push_back(first);
+ new_data_array.push_back(second);
+ new_data_array.push_back(third);
+
+ spb->set_data_array(new_data_array);
+
+ CHECK_EQ(spb->get_u8(), first);
+ CHECK_EQ(spb->get_u8(), second);
+ CHECK_EQ(spb->get_u8(), third);
+}
+
+TEST_CASE("[StreamPeerBuffer] Duplicate") {
+ uint8_t first = 5;
+ uint8_t second = 7;
+ uint8_t third = 11;
+
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ spb->put_u8(first);
+ spb->put_u8(second);
+ spb->put_u8(third);
+
+ Ref<StreamPeerBuffer> spb2 = spb->duplicate();
+
+ CHECK_EQ(spb2->get_u8(), first);
+ CHECK_EQ(spb2->get_u8(), second);
+ CHECK_EQ(spb2->get_u8(), third);
+}
+
+TEST_CASE("[StreamPeerBuffer] Put data with size equal to zero does nothing") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ uint8_t data = 42;
+
+ Error error = spb->put_data((const uint8_t *)&data, 0);
+
+ CHECK_EQ(error, OK);
+ CHECK_EQ(spb->get_size(), 0);
+ CHECK_EQ(spb->get_position(), 0);
+ CHECK_EQ(spb->get_available_bytes(), 0);
+}
+
+TEST_CASE("[StreamPeerBuffer] Get data with invalid size returns an error") {
+ Ref<StreamPeerBuffer> spb;
+ spb.instantiate();
+ uint8_t data = 42;
+ spb->put_u8(data);
+ spb->seek(0);
+
+ uint8_t data_out = 0;
+ Error error = spb->get_data(&data_out, 3);
+
+ CHECK_EQ(error, ERR_INVALID_PARAMETER);
+ CHECK_EQ(spb->get_size(), 1);
+ CHECK_EQ(spb->get_position(), 1);
+}
+
+} // namespace TestStreamPeerBuffer
+
+#endif // TEST_STREAM_PEER_BUFFER_H
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index a9f615af84..8559737e74 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -1888,7 +1888,7 @@ TEST_CASE("[String] validate_node_name") {
CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters ____removed!");
}
-TEST_CASE("[String] validate_identifier") {
+TEST_CASE("[String] validate_ascii_identifier") {
String empty_string;
CHECK(empty_string.validate_ascii_identifier() == "_");
@@ -1902,6 +1902,20 @@ TEST_CASE("[String] validate_identifier") {
CHECK(name_with_invalid_chars.validate_ascii_identifier() == "Invalid_characters_______");
}
+TEST_CASE("[String] validate_unicode_identifier") {
+ String empty_string;
+ CHECK(empty_string.validate_unicode_identifier() == "_");
+
+ String numeric_only = "12345";
+ CHECK(numeric_only.validate_unicode_identifier() == "_12345");
+
+ String name_with_spaces = "Name with spaces";
+ CHECK(name_with_spaces.validate_unicode_identifier() == "Name_with_spaces");
+
+ String name_with_invalid_chars = U"Invalid characters:@*#&世界";
+ CHECK(name_with_invalid_chars.validate_unicode_identifier() == U"Invalid_characters_____世界");
+}
+
TEST_CASE("[String] Variant indexed get") {
Variant s = String("abcd");
bool valid = false;
@@ -1974,6 +1988,61 @@ TEST_CASE("[String] Variant ptr indexed set") {
CHECK_EQ(s, String("azcd"));
}
+TEST_CASE("[String][URL] Parse URL") {
+#define CHECK_URL(m_url_to_parse, m_expected_schema, m_expected_host, m_expected_port, m_expected_path, m_expected_fragment, m_expected_error) \
+ if (true) { \
+ int port; \
+ String url(m_url_to_parse), schema, host, path, fragment; \
+ \
+ CHECK_EQ(url.parse_url(schema, host, port, path, fragment), m_expected_error); \
+ CHECK_EQ(schema, m_expected_schema); \
+ CHECK_EQ(host, m_expected_host); \
+ CHECK_EQ(path, m_expected_path); \
+ CHECK_EQ(fragment, m_expected_fragment); \
+ CHECK_EQ(port, m_expected_port); \
+ } else \
+ ((void)0)
+
+ // All elements.
+ CHECK_URL("https://www.example.com:8080/path/to/file.html#fragment", "https://", "www.example.com", 8080, "/path/to/file.html", "fragment", Error::OK);
+
+ // Valid URLs.
+ CHECK_URL("https://godotengine.org", "https://", "godotengine.org", 0, "", "", Error::OK);
+ CHECK_URL("https://godotengine.org/", "https://", "godotengine.org", 0, "/", "", Error::OK);
+ CHECK_URL("godotengine.org/", "", "godotengine.org", 0, "/", "", Error::OK);
+ CHECK_URL("HTTPS://godotengine.org/", "https://", "godotengine.org", 0, "/", "", Error::OK);
+ CHECK_URL("https://GODOTENGINE.ORG/", "https://", "godotengine.org", 0, "/", "", Error::OK);
+ CHECK_URL("http://godotengine.org", "http://", "godotengine.org", 0, "", "", Error::OK);
+ CHECK_URL("https://godotengine.org:8080", "https://", "godotengine.org", 8080, "", "", Error::OK);
+ CHECK_URL("https://godotengine.org/blog", "https://", "godotengine.org", 0, "/blog", "", Error::OK);
+ CHECK_URL("https://godotengine.org/blog/", "https://", "godotengine.org", 0, "/blog/", "", Error::OK);
+ CHECK_URL("https://docs.godotengine.org/en/stable", "https://", "docs.godotengine.org", 0, "/en/stable", "", Error::OK);
+ CHECK_URL("https://docs.godotengine.org/en/stable/", "https://", "docs.godotengine.org", 0, "/en/stable/", "", Error::OK);
+ CHECK_URL("https://me:secret@godotengine.org", "https://", "godotengine.org", 0, "", "", Error::OK);
+ CHECK_URL("https://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]/ipv6", "https://", "fedc:ba98:7654:3210:fedc:ba98:7654:3210", 0, "/ipv6", "", Error::OK);
+
+ // Scheme vs Fragment.
+ CHECK_URL("google.com/#goto=http://redirect_url/", "", "google.com", 0, "/", "goto=http://redirect_url/", Error::OK);
+
+ // Invalid URLs.
+
+ // Invalid Scheme.
+ CHECK_URL("https_://godotengine.org", "", "https_", 0, "//godotengine.org", "", Error::ERR_INVALID_PARAMETER);
+
+ // Multiple ports.
+ CHECK_URL("https://godotengine.org:8080:433", "https://", "", 0, "", "", Error::ERR_INVALID_PARAMETER);
+ // Missing ] on literal IPv6.
+ CHECK_URL("https://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/ipv6", "https://", "", 0, "/ipv6", "", Error::ERR_INVALID_PARAMETER);
+ // Missing host.
+ CHECK_URL("https:///blog", "https://", "", 0, "/blog", "", Error::ERR_INVALID_PARAMETER);
+ // Invalid ports.
+ CHECK_URL("https://godotengine.org:notaport", "https://", "godotengine.org", 0, "", "", Error::ERR_INVALID_PARAMETER);
+ CHECK_URL("https://godotengine.org:-8080", "https://", "godotengine.org", -8080, "", "", Error::ERR_INVALID_PARAMETER);
+ CHECK_URL("https://godotengine.org:88888", "https://", "godotengine.org", 88888, "", "", Error::ERR_INVALID_PARAMETER);
+
+#undef CHECK_URL
+}
+
TEST_CASE("[Stress][String] Empty via ' == String()'") {
for (int i = 0; i < 100000; ++i) {
String str = "Hello World!";
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index 9ec1b812df..ef630ad4f7 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -4779,6 +4779,31 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK(code_edit->get_caret_column(3) == 0);
}
+ SUBCASE("[SceneTree][CodeEdit] cut when empty selection clipboard disabled") {
+ DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
+ code_edit->set_empty_selection_clipboard_enabled(false);
+ DS->clipboard_set("");
+
+ code_edit->set_text("this is\nsome\n");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(6);
+ MessageQueue::get_singleton()->flush();
+ SIGNAL_DISCARD("text_set");
+ SIGNAL_DISCARD("text_changed");
+ SIGNAL_DISCARD("lines_edited_from");
+ SIGNAL_DISCARD("caret_changed");
+
+ code_edit->cut();
+ MessageQueue::get_singleton()->flush();
+ CHECK(DS->clipboard_get() == "");
+ CHECK(code_edit->get_text() == "this is\nsome\n");
+ CHECK(code_edit->get_caret_line() == 0);
+ CHECK(code_edit->get_caret_column() == 6);
+ SIGNAL_CHECK_FALSE("caret_changed");
+ SIGNAL_CHECK_FALSE("text_changed");
+ SIGNAL_CHECK_FALSE("lines_edited_from");
+ }
+
SUBCASE("[SceneTree][CodeEdit] new line") {
// Add a new line.
code_edit->set_text("test new line");
diff --git a/tests/scene/test_physics_material.h b/tests/scene/test_physics_material.h
new file mode 100644
index 0000000000..a078166f42
--- /dev/null
+++ b/tests/scene/test_physics_material.h
@@ -0,0 +1,107 @@
+/**************************************************************************/
+/* test_physics_material.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_PHYSICS_MATERIAL_H
+#define TEST_PHYSICS_MATERIAL_H
+
+#include "scene/resources/physics_material.h"
+#include "tests/test_macros.h"
+
+namespace TestPhysics_material {
+
+TEST_CASE("[Physics_material] Defaults") {
+ Ref<PhysicsMaterial> physics_material;
+ physics_material.instantiate();
+
+ CHECK(physics_material->get_friction() == 1.);
+ CHECK(physics_material->is_rough() == false);
+ CHECK(physics_material->get_bounce() == 0.);
+ CHECK(physics_material->is_absorbent() == false);
+}
+
+TEST_CASE("[Physics_material] Friction") {
+ Ref<PhysicsMaterial> physics_material;
+ physics_material.instantiate();
+
+ real_t friction = 0.314;
+ physics_material->set_friction(friction);
+ CHECK(physics_material->get_friction() == friction);
+}
+
+TEST_CASE("[Physics_material] Rough") {
+ Ref<PhysicsMaterial> physics_material;
+ physics_material.instantiate();
+
+ bool rough = true;
+ physics_material->set_rough(rough);
+ CHECK(physics_material->is_rough() == rough);
+
+ real_t friction = 0.314;
+ physics_material->set_friction(friction);
+ CHECK(physics_material->computed_friction() == -friction);
+
+ rough = false;
+ physics_material->set_rough(rough);
+ CHECK(physics_material->is_rough() == rough);
+
+ CHECK(physics_material->computed_friction() == friction);
+}
+
+TEST_CASE("[Physics_material] Bounce") {
+ Ref<PhysicsMaterial> physics_material;
+ physics_material.instantiate();
+
+ real_t bounce = 0.271;
+ physics_material->set_bounce(bounce);
+ CHECK(physics_material->get_bounce() == bounce);
+}
+
+TEST_CASE("[Physics_material] Absorbent") {
+ Ref<PhysicsMaterial> physics_material;
+ physics_material.instantiate();
+
+ bool absorbent = true;
+ physics_material->set_absorbent(absorbent);
+ CHECK(physics_material->is_absorbent() == absorbent);
+
+ real_t bounce = 0.271;
+ physics_material->set_bounce(bounce);
+ CHECK(physics_material->computed_bounce() == -bounce);
+
+ absorbent = false;
+ physics_material->set_absorbent(absorbent);
+ CHECK(physics_material->is_absorbent() == absorbent);
+
+ CHECK(physics_material->computed_bounce() == bounce);
+}
+
+} // namespace TestPhysics_material
+
+#endif // TEST_PHYSICS_MATERIAL_H
diff --git a/tests/scene/test_sky.h b/tests/scene/test_sky.h
new file mode 100644
index 0000000000..812ea9b5ad
--- /dev/null
+++ b/tests/scene/test_sky.h
@@ -0,0 +1,141 @@
+/**************************************************************************/
+/* test_sky.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_SKY_H
+#define TEST_SKY_H
+
+#include "scene/resources/sky.h"
+
+#include "tests/test_macros.h"
+
+namespace TestSky {
+
+TEST_CASE("[SceneTree][Sky] Constructor") {
+ Sky *test_sky = memnew(Sky);
+
+ CHECK(test_sky->get_process_mode() == Sky::PROCESS_MODE_AUTOMATIC);
+ CHECK(test_sky->get_radiance_size() == Sky::RADIANCE_SIZE_256);
+ CHECK(test_sky->get_material().is_null());
+ memdelete(test_sky);
+}
+
+TEST_CASE("[SceneTree][Sky] Radiance size setter and getter") {
+ Sky *test_sky = memnew(Sky);
+
+ // Check default.
+ CHECK(test_sky->get_radiance_size() == Sky::RADIANCE_SIZE_256);
+
+ test_sky->set_radiance_size(Sky::RADIANCE_SIZE_1024);
+ CHECK(test_sky->get_radiance_size() == Sky::RADIANCE_SIZE_1024);
+
+ ERR_PRINT_OFF;
+ // Check setting invalid radiance size.
+ test_sky->set_radiance_size(Sky::RADIANCE_SIZE_MAX);
+ ERR_PRINT_ON;
+
+ CHECK(test_sky->get_radiance_size() == Sky::RADIANCE_SIZE_1024);
+
+ memdelete(test_sky);
+}
+
+TEST_CASE("[SceneTree][Sky] Process mode setter and getter") {
+ Sky *test_sky = memnew(Sky);
+
+ // Check default.
+ CHECK(test_sky->get_process_mode() == Sky::PROCESS_MODE_AUTOMATIC);
+
+ test_sky->set_process_mode(Sky::PROCESS_MODE_INCREMENTAL);
+ CHECK(test_sky->get_process_mode() == Sky::PROCESS_MODE_INCREMENTAL);
+
+ memdelete(test_sky);
+}
+
+TEST_CASE("[SceneTree][Sky] Material setter and getter") {
+ Sky *test_sky = memnew(Sky);
+ Ref<Material> material = memnew(Material);
+
+ SUBCASE("Material passed to the class should remain the same") {
+ test_sky->set_material(material);
+ CHECK(test_sky->get_material() == material);
+ }
+ SUBCASE("Material passed many times to the class should remain the same") {
+ test_sky->set_material(material);
+ test_sky->set_material(material);
+ test_sky->set_material(material);
+ CHECK(test_sky->get_material() == material);
+ }
+ SUBCASE("Material rewrite testing") {
+ Ref<Material> material1 = memnew(Material);
+ Ref<Material> material2 = memnew(Material);
+
+ test_sky->set_material(material1);
+ test_sky->set_material(material2);
+ CHECK_MESSAGE(test_sky->get_material() != material1,
+ "After rewrite, second material should be in class.");
+ CHECK_MESSAGE(test_sky->get_material() == material2,
+ "After rewrite, second material should be in class.");
+ }
+
+ SUBCASE("Assign same material to two skys") {
+ Sky *sky2 = memnew(Sky);
+
+ test_sky->set_material(material);
+ sky2->set_material(material);
+ CHECK_MESSAGE(test_sky->get_material() == sky2->get_material(),
+ "Both skys should have the same material.");
+ memdelete(sky2);
+ }
+
+ SUBCASE("Swapping materials between two skys") {
+ Sky *sky2 = memnew(Sky);
+ Ref<Material> material1 = memnew(Material);
+ Ref<Material> material2 = memnew(Material);
+
+ test_sky->set_material(material1);
+ sky2->set_material(material2);
+ CHECK(test_sky->get_material() == material1);
+ CHECK(sky2->get_material() == material2);
+
+ // Do the swap.
+ Ref<Material> temp = test_sky->get_material();
+ test_sky->set_material(sky2->get_material());
+ sky2->set_material(temp);
+
+ CHECK(test_sky->get_material() == material2);
+ CHECK(sky2->get_material() == material1);
+ memdelete(sky2);
+ }
+
+ memdelete(test_sky);
+}
+
+} // namespace TestSky
+
+#endif // TEST_SKY_H
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index 46a5046b21..c41eebdf3a 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -3585,6 +3585,54 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
SIGNAL_CHECK_FALSE("lines_edited_from");
}
+ SUBCASE("[TextEdit] cut when empty selection clipboard disabled") {
+ text_edit->set_empty_selection_clipboard_enabled(false);
+ DS->clipboard_set("");
+
+ text_edit->set_text("this is\nsome\n");
+ text_edit->set_caret_line(0);
+ text_edit->set_caret_column(6);
+ MessageQueue::get_singleton()->flush();
+ SIGNAL_DISCARD("text_set");
+ SIGNAL_DISCARD("text_changed");
+ SIGNAL_DISCARD("lines_edited_from");
+ SIGNAL_DISCARD("caret_changed");
+
+ text_edit->cut();
+ MessageQueue::get_singleton()->flush();
+ CHECK(DS->clipboard_get() == "");
+ CHECK(text_edit->get_text() == "this is\nsome\n");
+ CHECK(text_edit->get_caret_line() == 0);
+ CHECK(text_edit->get_caret_column() == 6);
+ SIGNAL_CHECK_FALSE("caret_changed");
+ SIGNAL_CHECK_FALSE("text_changed");
+ SIGNAL_CHECK_FALSE("lines_edited_from");
+ }
+
+ SUBCASE("[TextEdit] copy when empty selection clipboard disabled") {
+ text_edit->set_empty_selection_clipboard_enabled(false);
+ DS->clipboard_set("");
+
+ text_edit->set_text("this is\nsome\n");
+ text_edit->set_caret_line(0);
+ text_edit->set_caret_column(6);
+ MessageQueue::get_singleton()->flush();
+ SIGNAL_DISCARD("text_set");
+ SIGNAL_DISCARD("text_changed");
+ SIGNAL_DISCARD("lines_edited_from");
+ SIGNAL_DISCARD("caret_changed");
+
+ text_edit->copy();
+ MessageQueue::get_singleton()->flush();
+ CHECK(DS->clipboard_get() == "");
+ CHECK(text_edit->get_text() == "this is\nsome\n");
+ CHECK(text_edit->get_caret_line() == 0);
+ CHECK(text_edit->get_caret_column() == 6);
+ SIGNAL_CHECK_FALSE("caret_changed");
+ SIGNAL_CHECK_FALSE("text_changed");
+ SIGNAL_CHECK_FALSE("lines_edited_from");
+ }
+
SIGNAL_UNWATCH(text_edit, "text_set");
SIGNAL_UNWATCH(text_edit, "text_changed");
SIGNAL_UNWATCH(text_edit, "lines_edited_from");
diff --git a/tests/scene/test_viewport.h b/tests/scene/test_viewport.h
index 9d02c41719..dde37944ec 100644
--- a/tests/scene/test_viewport.h
+++ b/tests/scene/test_viewport.h
@@ -38,6 +38,7 @@
#include "scene/main/canvas_layer.h"
#include "scene/main/window.h"
#include "scene/resources/2d/rectangle_shape_2d.h"
+#include "servers/physics_server_2d_dummy.h"
#include "tests/test_macros.h"
@@ -1550,6 +1551,12 @@ int TestArea2D::counter = 0;
TEST_CASE("[SceneTree][Viewport] Physics Picking 2D") {
// FIXME: MOUSE_MODE_CAPTURED if-conditions are not testable, because DisplayServerMock doesn't support it.
+ // NOTE: This test requires a real physics server.
+ PhysicsServer2DDummy *physics_server_2d_dummy = Object::cast_to<PhysicsServer2DDummy>(PhysicsServer2D::get_singleton());
+ if (physics_server_2d_dummy) {
+ return;
+ }
+
struct PickingCollider {
TestArea2D *a;
CollisionShape2D *c;
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 2721a4f710..465484d605 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -50,8 +50,11 @@
#include "tests/core/io/test_json.h"
#include "tests/core/io/test_json_native.h"
#include "tests/core/io/test_marshalls.h"
+#include "tests/core/io/test_packet_peer.h"
#include "tests/core/io/test_pck_packer.h"
#include "tests/core/io/test_resource.h"
+#include "tests/core/io/test_stream_peer.h"
+#include "tests/core/io/test_stream_peer_buffer.h"
#include "tests/core/io/test_xml_parser.h"
#include "tests/core/math/test_aabb.h"
#include "tests/core/math/test_astar.h"
@@ -122,6 +125,7 @@
#include "tests/scene/test_parallax_2d.h"
#include "tests/scene/test_path_2d.h"
#include "tests/scene/test_path_follow_2d.h"
+#include "tests/scene/test_physics_material.h"
#include "tests/scene/test_sprite_frames.h"
#include "tests/scene/test_style_box_texture.h"
#include "tests/scene/test_theme.h"
@@ -163,6 +167,7 @@
#include "tests/scene/test_path_follow_3d.h"
#include "tests/scene/test_primitives.h"
#include "tests/scene/test_skeleton_3d.h"
+#include "tests/scene/test_sky.h"
#endif // _3D_DISABLED
#include "modules/modules_tests.gen.h"
@@ -176,8 +181,10 @@
#include "servers/navigation_server_3d.h"
#endif // _3D_DISABLED
#include "servers/physics_server_2d.h"
+#include "servers/physics_server_2d_dummy.h"
#ifndef _3D_DISABLED
#include "servers/physics_server_3d.h"
+#include "servers/physics_server_3d_dummy.h"
#endif // _3D_DISABLED
#include "servers/rendering/rendering_server_default.h"
@@ -292,10 +299,16 @@ struct GodotTestCaseListener : public doctest::IReporter {
#ifndef _3D_DISABLED
physics_server_3d = PhysicsServer3DManager::get_singleton()->new_default_server();
+ if (!physics_server_3d) {
+ physics_server_3d = memnew(PhysicsServer3DDummy);
+ }
physics_server_3d->init();
#endif // _3D_DISABLED
physics_server_2d = PhysicsServer2DManager::get_singleton()->new_default_server();
+ if (!physics_server_2d) {
+ physics_server_2d = memnew(PhysicsServer2DDummy);
+ }
physics_server_2d->init();
#ifndef _3D_DISABLED