feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_PROJECT_SETTINGS_H
|
||||
#define TEST_PROJECT_SETTINGS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/dir_access.h"
|
||||
|
|
@ -113,7 +112,7 @@ TEST_CASE("[ProjectSettings] localize_path") {
|
|||
TestProjectSettingsInternalsAccessor::resource_path() = DirAccess::create(DirAccess::ACCESS_FILESYSTEM)->get_current_dir();
|
||||
String root_path = ProjectSettings::get_singleton()->get_resource_path();
|
||||
#ifdef WINDOWS_ENABLED
|
||||
String root_path_win = ProjectSettings::get_singleton()->get_resource_path().replace("/", "\\");
|
||||
String root_path_win = ProjectSettings::get_singleton()->get_resource_path().replace_char('/', '\\');
|
||||
#endif
|
||||
|
||||
CHECK_EQ(ProjectSettings::get_singleton()->localize_path("filename"), "res://filename");
|
||||
|
|
@ -160,5 +159,3 @@ TEST_CASE("[ProjectSettings] localize_path") {
|
|||
}
|
||||
|
||||
} // namespace TestProjectSettings
|
||||
|
||||
#endif // TEST_PROJECT_SETTINGS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_INPUT_EVENT_H
|
||||
#define TEST_INPUT_EVENT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "core/math/rect2.h"
|
||||
|
|
@ -44,10 +43,8 @@ TEST_CASE("[InputEvent] Signal is emitted when device is changed") {
|
|||
input_event.instantiate();
|
||||
|
||||
SIGNAL_WATCH(*input_event, CoreStringName(changed));
|
||||
Array args1;
|
||||
Array empty_args;
|
||||
empty_args.push_back(args1);
|
||||
|
||||
Array empty_args = { {} };
|
||||
input_event->set_device(1);
|
||||
|
||||
SIGNAL_CHECK("changed", empty_args);
|
||||
|
|
@ -111,5 +108,3 @@ TEST_CASE("[InputEvent] Test xformed_by") {
|
|||
CHECK(iemm2->get_position().is_equal_approx(Vector2(2.0f, 3.0f)));
|
||||
}
|
||||
} // namespace TestInputEvent
|
||||
|
||||
#endif // TEST_INPUT_EVENT_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_INPUT_EVENT_KEY_H
|
||||
#define TEST_INPUT_EVENT_KEY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "core/os/keyboard.h"
|
||||
|
|
@ -335,5 +334,3 @@ TEST_CASE("[IsMatch] Keys are correctly matched") {
|
|||
CHECK(key3.is_match(loc_ref, false) == true);
|
||||
}
|
||||
} // namespace TestInputEventKey
|
||||
|
||||
#endif // TEST_INPUT_EVENT_KEY_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_INPUT_EVENT_MOUSE_H
|
||||
#define TEST_INPUT_EVENT_MOUSE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -77,5 +76,3 @@ TEST_CASE("[InputEventMouse] Setting the global mouse position works correctly")
|
|||
CHECK(mousekey.get_global_position() != Vector2{ 1, 1 });
|
||||
}
|
||||
} // namespace TestInputEventMouse
|
||||
|
||||
#endif // TEST_INPUT_EVENT_MOUSE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_SHORTCUT_H
|
||||
#define TEST_SHORTCUT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/input/input_event.h"
|
||||
#include "core/input/shortcut.h"
|
||||
|
|
@ -61,10 +60,7 @@ TEST_CASE("[Shortcut] Setting and getting an event should result in the same eve
|
|||
// Cast to InputEvent so the internal code recognizes the objects.
|
||||
Ref<InputEvent> e1 = k1;
|
||||
Ref<InputEvent> e2 = k2;
|
||||
|
||||
Array input_array;
|
||||
input_array.append(e1);
|
||||
input_array.append(e2);
|
||||
Array input_array = { e1, e2 };
|
||||
|
||||
Shortcut s;
|
||||
s.set_events(input_array);
|
||||
|
|
@ -132,8 +128,7 @@ TEST_CASE("[Shortcut] 'matches_event' should correctly match the same event") {
|
|||
Ref<InputEvent> e_different = different;
|
||||
Ref<InputEvent> e_copy = copy;
|
||||
|
||||
Array a;
|
||||
a.append(e_original);
|
||||
Array a = { e_original };
|
||||
Shortcut s;
|
||||
s.set_events(a);
|
||||
|
||||
|
|
@ -155,9 +150,7 @@ TEST_CASE("[Shortcut] 'get_as_text' text representation should be correct") {
|
|||
different->set_keycode(Key::ESCAPE);
|
||||
|
||||
Ref<InputEvent> key_event1 = same;
|
||||
|
||||
Array a;
|
||||
a.append(key_event1);
|
||||
Array a = { key_event1 };
|
||||
Shortcut s;
|
||||
s.set_events(a);
|
||||
|
||||
|
|
@ -176,17 +169,14 @@ TEST_CASE("[Shortcut] Event validity should be correctly checked.") {
|
|||
Ref<InputEvent> valid_event = valid;
|
||||
Ref<InputEvent> invalid_event = invalid;
|
||||
|
||||
Array a;
|
||||
a.append(invalid_event);
|
||||
a.append(valid_event);
|
||||
Array a = { invalid_event, valid_event };
|
||||
|
||||
Shortcut s;
|
||||
s.set_events(a);
|
||||
|
||||
CHECK(s.has_valid_event() == true);
|
||||
|
||||
Array b;
|
||||
b.append(invalid_event);
|
||||
Array b = { invalid_event };
|
||||
|
||||
Shortcut shortcut_with_invalid_event;
|
||||
shortcut_with_invalid_event.set_events(b);
|
||||
|
|
@ -214,13 +204,8 @@ TEST_CASE("[Shortcut] Equal arrays should be recognized as such.") {
|
|||
Array same_as_same;
|
||||
same_as_same.append(key_event1);
|
||||
|
||||
Array different1;
|
||||
different1.append(key_event2);
|
||||
|
||||
Array different2;
|
||||
different2.append(key_event1);
|
||||
different2.append(key_event2);
|
||||
|
||||
Array different1 = { key_event2 };
|
||||
Array different2 = { key_event1, key_event2 };
|
||||
Array different3;
|
||||
|
||||
Shortcut s;
|
||||
|
|
@ -231,5 +216,3 @@ TEST_CASE("[Shortcut] Equal arrays should be recognized as such.") {
|
|||
CHECK(s.is_event_array_equal(same, different3) == false);
|
||||
}
|
||||
} // namespace TestShortcut
|
||||
|
||||
#endif // TEST_SHORTCUT_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_CONFIG_FILE_H
|
||||
#define TEST_CONFIG_FILE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/config_file.h"
|
||||
#include "core/os/os.h"
|
||||
|
|
@ -160,5 +159,3 @@ antiAliasing=false
|
|||
"The saved configuration file should match the expected format.");
|
||||
}
|
||||
} // namespace TestConfigFile
|
||||
|
||||
#endif // TEST_CONFIG_FILE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_FILE_ACCESS_H
|
||||
#define TEST_FILE_ACCESS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -197,8 +196,28 @@ TEST_CASE("[FileAccess] Get/Store floating point half precision values") {
|
|||
|
||||
DirAccess::remove_file_or_error(file_path_new);
|
||||
}
|
||||
|
||||
SUBCASE("4096 bytes fastlz compressed") {
|
||||
const String file_path = TestUtils::get_data_path("exactly_4096_bytes_fastlz.bin");
|
||||
|
||||
Ref<FileAccess> f = FileAccess::open_compressed(file_path, FileAccess::READ, FileAccess::COMPRESSION_FASTLZ);
|
||||
const Vector<uint8_t> full_data = f->get_buffer(4096 * 2);
|
||||
CHECK(full_data.size() == 4096);
|
||||
CHECK(f->eof_reached());
|
||||
|
||||
// Data should be empty.
|
||||
PackedByteArray reference;
|
||||
reference.resize_zeroed(4096);
|
||||
CHECK(reference == full_data);
|
||||
|
||||
f->seek(0);
|
||||
const Vector<uint8_t> partial_data = f->get_buffer(4095);
|
||||
CHECK(partial_data.size() == 4095);
|
||||
CHECK(!f->eof_reached());
|
||||
|
||||
reference.resize_zeroed(4095);
|
||||
CHECK(reference == partial_data);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TestFileAccess
|
||||
|
||||
#endif // TEST_FILE_ACCESS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_HTTP_CLIENT_H
|
||||
#define TEST_HTTP_CLIENT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/http_client.h"
|
||||
|
||||
|
|
@ -59,10 +58,7 @@ TEST_CASE("[HTTPClient] query_string_from_dict") {
|
|||
Dictionary dict2;
|
||||
dict2["key1"] = "value";
|
||||
dict2["key2"] = 123;
|
||||
Array values;
|
||||
values.push_back(1);
|
||||
values.push_back(2);
|
||||
values.push_back(3);
|
||||
Array values = { 1, 2, 3 };
|
||||
dict2["key3"] = values;
|
||||
dict2["key4"] = Variant();
|
||||
String multiple_keys = client->query_string_from_dict(dict2);
|
||||
|
|
@ -106,5 +102,3 @@ TEST_CASE("[HTTPClient] connect_to_host") {
|
|||
#endif // MODULE_MBEDTLS_ENABLED || WEB_ENABLED
|
||||
|
||||
} // namespace TestHTTPClient
|
||||
|
||||
#endif // TEST_HTTP_CLIENT_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_IMAGE_H
|
||||
#define TEST_IMAGE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/os/os.h"
|
||||
|
|
@ -444,5 +443,3 @@ TEST_CASE("[Image] Convert image") {
|
|||
}
|
||||
|
||||
} // namespace TestImage
|
||||
|
||||
#endif // TEST_IMAGE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_IP_H
|
||||
#define TEST_IP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/ip.h"
|
||||
|
||||
|
|
@ -47,5 +46,3 @@ TEST_CASE("[IP] resolve_hostname") {
|
|||
}
|
||||
|
||||
} // namespace TestIP
|
||||
|
||||
#endif // TEST_IP_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_JSON_H
|
||||
#define TEST_JSON_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/json.h"
|
||||
|
||||
|
|
@ -153,21 +152,13 @@ TEST_CASE("[JSON] Parsing escape sequences") {
|
|||
|
||||
JSON json;
|
||||
|
||||
TypedArray<String> valid_escapes;
|
||||
valid_escapes.push_back("\";\"");
|
||||
valid_escapes.push_back("\\;\\");
|
||||
valid_escapes.push_back("/;/");
|
||||
valid_escapes.push_back("b;\b");
|
||||
valid_escapes.push_back("f;\f");
|
||||
valid_escapes.push_back("n;\n");
|
||||
valid_escapes.push_back("r;\r");
|
||||
valid_escapes.push_back("t;\t");
|
||||
TypedArray<String> valid_escapes = { "\";\"", "\\;\\", "/;/", "b;\b", "f;\f", "n;\n", "r;\r", "t;\t" };
|
||||
|
||||
SUBCASE("Basic valid escape sequences") {
|
||||
for (int i = 0; i < valid_escapes.size(); i++) {
|
||||
String valid_escape = valid_escapes[i];
|
||||
String valid_escape_string = valid_escape.get_slice(";", 0);
|
||||
String valid_escape_value = valid_escape.get_slice(";", 1);
|
||||
String valid_escape_string = valid_escape.get_slicec(';', 0);
|
||||
String valid_escape_value = valid_escape.get_slicec(';', 1);
|
||||
|
||||
String json_string = "\"\\";
|
||||
json_string += valid_escape_string;
|
||||
|
|
@ -205,7 +196,7 @@ TEST_CASE("[JSON] Parsing escape sequences") {
|
|||
bool skip = false;
|
||||
for (int j = 0; j < valid_escapes.size(); j++) {
|
||||
String valid_escape = valid_escapes[j];
|
||||
String valid_escape_string = valid_escape.get_slice(";", 0);
|
||||
String valid_escape_string = valid_escape.get_slicec(';', 0);
|
||||
if (valid_escape_string[0] == i) {
|
||||
skip = true;
|
||||
break;
|
||||
|
|
@ -318,5 +309,3 @@ TEST_CASE("[JSON] Serialization") {
|
|||
}
|
||||
}
|
||||
} // namespace TestJSON
|
||||
|
||||
#endif // TEST_JSON_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_JSON_NATIVE_H
|
||||
#define TEST_JSON_NATIVE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/json.h"
|
||||
|
||||
|
|
@ -162,25 +161,13 @@ TEST_CASE("[JSON][Native] Conversion between native and JSON formats") {
|
|||
|
||||
// `Array`.
|
||||
|
||||
Array arr;
|
||||
arr.push_back(true);
|
||||
arr.push_back(1);
|
||||
arr.push_back("abc");
|
||||
|
||||
Array arr = { true, 1, "abc" };
|
||||
test(arr, R"([true,"i:1","s:abc"])");
|
||||
|
||||
TypedArray<int64_t> int_arr;
|
||||
int_arr.push_back(1);
|
||||
int_arr.push_back(2);
|
||||
int_arr.push_back(3);
|
||||
|
||||
TypedArray<int64_t> int_arr = { 1, 2, 3 };
|
||||
test(int_arr, R"({"type":"Array","elem_type":"int","args":["i:1","i:2","i:3"]})");
|
||||
|
||||
Array arr2;
|
||||
arr2.push_back(1);
|
||||
arr2.push_back(res);
|
||||
arr2.push_back(9);
|
||||
|
||||
Array arr2 = { 1, res, 9 };
|
||||
const String arr2_repr = vformat(R"(["i:1",%s,"i:9"])", res_repr);
|
||||
|
||||
test(arr2, arr2_repr, true);
|
||||
|
|
@ -189,9 +176,7 @@ TEST_CASE("[JSON][Native] Conversion between native and JSON formats") {
|
|||
CHECK(decode(arr2_repr).get_construct_string() == "[1, null, 9]");
|
||||
ERR_PRINT_ON;
|
||||
|
||||
TypedArray<Resource> res_arr;
|
||||
res_arr.push_back(res);
|
||||
|
||||
TypedArray<Resource> res_arr = { res };
|
||||
const String res_arr_repr = vformat(R"({"type":"Array","elem_type":"Resource","args":[%s]})", res_repr);
|
||||
|
||||
test(res_arr, res_arr_repr, true);
|
||||
|
|
@ -223,5 +208,3 @@ TEST_CASE("[JSON][Native] Conversion between native and JSON formats") {
|
|||
}
|
||||
|
||||
} // namespace TestJSONNative
|
||||
|
||||
#endif // TEST_JSON_NATIVE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_LOGGER_H
|
||||
#define TEST_LOGGER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/io/logger.h"
|
||||
|
|
@ -166,5 +165,3 @@ TEST_CASE("[Logger][CompositeLogger] Logs the same into multiple loggers") {
|
|||
}
|
||||
|
||||
} // namespace TestLogger
|
||||
|
||||
#endif // TEST_LOGGER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_MARSHALLS_H
|
||||
#define TEST_MARSHALLS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/marshalls.h"
|
||||
|
||||
|
|
@ -491,5 +490,3 @@ TEST_CASE("[Marshalls] Typed dictionary decoding") {
|
|||
}
|
||||
|
||||
} // namespace TestMarshalls
|
||||
|
||||
#endif // TEST_MARSHALLS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_PACKET_PEER_H
|
||||
#define TEST_PACKET_PEER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/packet_peer.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -200,5 +199,3 @@ TEST_CASE("[PacketPeer][PacketPeerStream] Put packet buffer when is empty") {
|
|||
}
|
||||
|
||||
} // namespace TestPacketPeer
|
||||
|
||||
#endif // TEST_PACKET_PEER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_PCK_PACKER_H
|
||||
#define TEST_PCK_PACKER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access_pack.h"
|
||||
#include "core/io/pck_packer.h"
|
||||
|
|
@ -118,5 +117,3 @@ TEST_CASE("[PCKPacker] Pack a PCK file with some files and directories") {
|
|||
"The generated non-empty PCK file shouldn't be too large.");
|
||||
}
|
||||
} // namespace TestPCKPacker
|
||||
|
||||
#endif // TEST_PCK_PACKER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_RESOURCE_H
|
||||
#define TEST_RESOURCE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
|
|
@ -167,5 +166,3 @@ TEST_CASE("[Resource] Breaking circular references on save") {
|
|||
resource_c->remove_meta("next");
|
||||
}
|
||||
} // namespace TestResource
|
||||
|
||||
#endif // TEST_RESOURCE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_RESOURCE_UID_H
|
||||
#define TEST_RESOURCE_UID_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/resource_uid.h"
|
||||
|
||||
|
|
@ -67,5 +66,3 @@ TEST_CASE("[ResourceUID] Must encode and decode various UIDs correctly") {
|
|||
}
|
||||
|
||||
} // namespace TestResourceUID
|
||||
|
||||
#endif // TEST_RESOURCE_UID_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_STREAM_PEER_H
|
||||
#define TEST_STREAM_PEER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -307,5 +306,3 @@ TEST_CASE("[StreamPeer] Get UTF8 string when there is no string") {
|
|||
}
|
||||
|
||||
} // namespace TestStreamPeer
|
||||
|
||||
#endif // TEST_STREAM_PEER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_STREAM_PEER_BUFFER_H
|
||||
#define TEST_STREAM_PEER_BUFFER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -181,5 +180,3 @@ TEST_CASE("[StreamPeerBuffer] Get data with invalid size returns an error") {
|
|||
}
|
||||
|
||||
} // namespace TestStreamPeerBuffer
|
||||
|
||||
#endif // TEST_STREAM_PEER_BUFFER_H
|
||||
|
|
|
|||
195
engine/tests/core/io/test_stream_peer_gzip.h
Normal file
195
engine/tests/core/io/test_stream_peer_gzip.h
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/**************************************************************************/
|
||||
/* test_stream_peer_gzip.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer_gzip.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
namespace TestStreamPeerGZIP {
|
||||
|
||||
const String hello = "Hello World!!!";
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Initialization") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
CHECK_EQ(spgz->get_available_bytes(), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Compress/Decompress") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
|
||||
bool is_deflate = false;
|
||||
|
||||
SUBCASE("GZIP") {
|
||||
is_deflate = false;
|
||||
}
|
||||
|
||||
SUBCASE("DEFLATE") {
|
||||
is_deflate = true;
|
||||
}
|
||||
|
||||
CHECK_EQ(spgz->start_compression(is_deflate), Error::OK);
|
||||
CHECK_EQ(spgz->put_data(hello.to_ascii_buffer().ptr(), hello.to_ascii_buffer().size()), Error::OK);
|
||||
CHECK_EQ(spgz->finish(), Error::OK);
|
||||
|
||||
Vector<uint8_t> hello_compressed;
|
||||
int hello_compressed_size = spgz->get_available_bytes();
|
||||
hello_compressed.resize(hello_compressed_size);
|
||||
CHECK_EQ(spgz->get_data(hello_compressed.ptrw(), hello_compressed_size), Error::OK);
|
||||
|
||||
spgz->clear();
|
||||
|
||||
CHECK_EQ(spgz->start_decompression(is_deflate), Error::OK);
|
||||
CHECK_EQ(spgz->put_data(hello_compressed.ptr(), hello_compressed.size()), Error::OK);
|
||||
|
||||
Vector<uint8_t> hello_decompressed;
|
||||
int hello_decompressed_size = spgz->get_available_bytes();
|
||||
hello_decompressed.resize(hello_decompressed_size);
|
||||
CHECK_EQ(spgz->get_data(hello_decompressed.ptrw(), hello_decompressed_size), Error::OK);
|
||||
CHECK_EQ(hello_decompressed, hello.to_ascii_buffer());
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Compress/Decompress big chunks of data") { // GH-97201
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
CHECK_EQ(spgz->start_compression(false), Error::OK);
|
||||
|
||||
Vector<uint8_t> big_data;
|
||||
big_data.resize(2500);
|
||||
// Filling it with random data because the issue is related to the size of the data when it's compress.
|
||||
// Random data results in bigger compressed data size.
|
||||
for (int i = 0; i < big_data.size(); i++) {
|
||||
big_data.write[i] = Math::random(48, 122);
|
||||
}
|
||||
CHECK_EQ(spgz->put_data(big_data.ptr(), big_data.size()), Error::OK);
|
||||
CHECK_EQ(spgz->finish(), Error::OK);
|
||||
|
||||
Vector<uint8_t> big_data_compressed;
|
||||
int big_data_compressed_size = spgz->get_available_bytes();
|
||||
big_data_compressed.resize(big_data_compressed_size);
|
||||
CHECK_EQ(spgz->get_data(big_data_compressed.ptrw(), big_data_compressed_size), Error::OK);
|
||||
|
||||
spgz->clear();
|
||||
|
||||
CHECK_EQ(spgz->start_decompression(false), Error::OK);
|
||||
CHECK_EQ(spgz->put_data(big_data_compressed.ptr(), big_data_compressed.size()), Error::OK);
|
||||
|
||||
Vector<uint8_t> big_data_decompressed;
|
||||
int big_data_decompressed_size = spgz->get_available_bytes();
|
||||
big_data_decompressed.resize(big_data_decompressed_size);
|
||||
CHECK_EQ(spgz->get_data(big_data_decompressed.ptrw(), big_data_decompressed_size), Error::OK);
|
||||
CHECK_EQ(big_data_decompressed, big_data);
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Can't start twice") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
CHECK_EQ(spgz->start_compression(false), Error::OK);
|
||||
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_EQ(spgz->start_compression(false), Error::ERR_ALREADY_IN_USE);
|
||||
CHECK_EQ(spgz->start_decompression(false), Error::ERR_ALREADY_IN_USE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Can't start with a buffer size equal or less than zero") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_EQ(spgz->start_compression(false, 0), Error::ERR_INVALID_PARAMETER);
|
||||
CHECK_EQ(spgz->start_compression(false, -1), Error::ERR_INVALID_PARAMETER);
|
||||
CHECK_EQ(spgz->start_decompression(false, 0), Error::ERR_INVALID_PARAMETER);
|
||||
CHECK_EQ(spgz->start_decompression(false, -1), Error::ERR_INVALID_PARAMETER);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Can't put/get data with a buffer size less than zero") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
CHECK_EQ(spgz->start_compression(false), Error::OK);
|
||||
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_EQ(spgz->put_data(hello.to_ascii_buffer().ptr(), -1), Error::ERR_INVALID_PARAMETER);
|
||||
|
||||
Vector<uint8_t> hello_compressed;
|
||||
hello_compressed.resize(5);
|
||||
CHECK_EQ(spgz->get_data(hello_compressed.ptrw(), -1), Error::ERR_INVALID_PARAMETER);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Needs to be started before use") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_EQ(spgz->put_data(hello.to_ascii_buffer().ptr(), hello.to_ascii_buffer().size()), Error::ERR_UNCONFIGURED);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Can't be finished after clear or if it's decompressing") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
|
||||
CHECK_EQ(spgz->start_compression(false), Error::OK);
|
||||
spgz->clear();
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_EQ(spgz->finish(), Error::ERR_UNAVAILABLE);
|
||||
ERR_PRINT_ON;
|
||||
|
||||
spgz->clear();
|
||||
CHECK_EQ(spgz->start_decompression(false), Error::OK);
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_EQ(spgz->finish(), Error::ERR_UNAVAILABLE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
||||
TEST_CASE("[StreamPeerGZIP] Fails to get if nothing was compress/decompress") {
|
||||
Ref<StreamPeerGZIP> spgz;
|
||||
spgz.instantiate();
|
||||
|
||||
SUBCASE("Compression") {
|
||||
CHECK_EQ(spgz->start_compression(false), Error::OK);
|
||||
}
|
||||
|
||||
SUBCASE("Decompression") {
|
||||
CHECK_EQ(spgz->start_decompression(false), Error::OK);
|
||||
}
|
||||
|
||||
ERR_PRINT_OFF;
|
||||
Vector<uint8_t> hello_compressed;
|
||||
hello_compressed.resize(5);
|
||||
CHECK_EQ(spgz->get_data(hello_compressed.ptrw(), hello_compressed.size()), Error::ERR_UNAVAILABLE);
|
||||
ERR_PRINT_ON;
|
||||
}
|
||||
|
||||
} // namespace TestStreamPeerGZIP
|
||||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_TCP_SERVER_H
|
||||
#define TEST_TCP_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/stream_peer_tcp.h"
|
||||
#include "core/io/tcp_server.h"
|
||||
|
|
@ -251,5 +250,3 @@ TEST_CASE("[TCPServer] Should disconnect client") {
|
|||
}
|
||||
|
||||
} // namespace TestTCPServer
|
||||
|
||||
#endif // TEST_TCP_SERVER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_UDP_SERVER_H
|
||||
#define TEST_UDP_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/packet_peer_udp.h"
|
||||
#include "core/io/udp_server.h"
|
||||
|
|
@ -215,5 +214,3 @@ TEST_CASE("[UDPServer] Should not accept new connections after stop") {
|
|||
}
|
||||
|
||||
} // namespace TestUDPServer
|
||||
|
||||
#endif // TEST_UDP_SERVER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_XML_PARSER_H
|
||||
#define TEST_XML_PARSER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/xml_parser.h"
|
||||
|
||||
|
|
@ -231,5 +230,3 @@ TEST_CASE("[XMLParser] CDATA") {
|
|||
CHECK_EQ(parser.get_node_name(), "a");
|
||||
}
|
||||
} // namespace TestXMLParser
|
||||
|
||||
#endif // TEST_XML_PARSER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_AABB_H
|
||||
#define TEST_AABB_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/aabb.h"
|
||||
|
||||
|
|
@ -38,8 +37,8 @@
|
|||
namespace TestAABB {
|
||||
|
||||
TEST_CASE("[AABB] Constructor methods") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
const AABB aabb_copy = AABB(aabb);
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb_copy = AABB(aabb);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
aabb == aabb_copy,
|
||||
|
|
@ -53,7 +52,7 @@ TEST_CASE("[AABB] String conversion") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Basic getters") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.get_position().is_equal_approx(Vector3(-1.5, 2, -2.5)),
|
||||
"get_position() should return the expected value.");
|
||||
|
|
@ -144,7 +143,7 @@ TEST_CASE("[AABB] Surface getters") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Intersection") {
|
||||
const AABB aabb_big = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb_big = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
|
||||
AABB aabb_small = AABB(Vector3(-1.5, 2, -2.5), Vector3(1, 1, 1));
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -230,7 +229,7 @@ TEST_CASE("[AABB] Intersection") {
|
|||
"intersects_ray() should return false for being outside.");
|
||||
|
||||
// Finding ray intersections.
|
||||
const AABB aabb_simple = AABB(Vector3(), Vector3(1, 1, 1));
|
||||
constexpr AABB aabb_simple = AABB(Vector3(), Vector3(1, 1, 1));
|
||||
bool inside = false;
|
||||
Vector3 intersection_point;
|
||||
Vector3 intersection_normal;
|
||||
|
|
@ -252,7 +251,7 @@ TEST_CASE("[AABB] Intersection") {
|
|||
CHECK_MESSAGE(intersection_normal.is_equal_approx(Vector3(0, -1, 0)), "find_intersects_ray() inside intersection normal incorrect.");
|
||||
|
||||
// Zero sized AABB.
|
||||
const AABB aabb_zero = AABB(Vector3(), Vector3(1, 0, 1));
|
||||
constexpr AABB aabb_zero = AABB(Vector3(), Vector3(1, 0, 1));
|
||||
aabb_zero.find_intersects_ray(Vector3(0.5, 0, 0.5), Vector3(0, 1, 0), inside, &intersection_point, &intersection_normal);
|
||||
CHECK_MESSAGE(inside == false, "find_intersects_ray() should return outside on borders of zero sized AABB.");
|
||||
CHECK_MESSAGE(intersection_point.is_equal_approx(Vector3(0.5, 0, 0.5)), "find_intersects_ray() border intersection point incorrect for zero sized AABB.");
|
||||
|
|
@ -268,7 +267,7 @@ TEST_CASE("[AABB] Intersection") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Merging") {
|
||||
const AABB aabb_big = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb_big = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
|
||||
AABB aabb_small = AABB(Vector3(-1.5, 2, -2.5), Vector3(1, 1, 1));
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -287,7 +286,7 @@ TEST_CASE("[AABB] Merging") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Encloses") {
|
||||
const AABB aabb_big = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb_big = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
|
||||
CHECK_MESSAGE(
|
||||
aabb_big.encloses(aabb_big),
|
||||
|
|
@ -315,7 +314,7 @@ TEST_CASE("[AABB] Encloses") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Get endpoints") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.get_endpoint(0).is_equal_approx(Vector3(-1.5, 2, -2.5)),
|
||||
"The endpoint at index 0 should match the expected value.");
|
||||
|
|
@ -352,7 +351,7 @@ TEST_CASE("[AABB] Get endpoints") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Get longest/shortest axis") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.get_longest_axis() == Vector3(0, 0, 1),
|
||||
"get_longest_axis() should return the expected value.");
|
||||
|
|
@ -375,7 +374,7 @@ TEST_CASE("[AABB] Get longest/shortest axis") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Get support") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.get_support(Vector3(1, 0, 0)) == Vector3(2.5, 2, -2.5),
|
||||
"get_support() should return the expected value.");
|
||||
|
|
@ -397,7 +396,7 @@ TEST_CASE("[AABB] Get support") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Grow") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.grow(0.25).is_equal_approx(AABB(Vector3(-1.75, 1.75, -2.75), Vector3(4.5, 5.5, 6.5))),
|
||||
"grow() with positive value should return the expected AABB.");
|
||||
|
|
@ -410,7 +409,7 @@ TEST_CASE("[AABB] Grow") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Has point") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.has_point(Vector3(-1, 3, 0)),
|
||||
"has_point() with contained point should return the expected value.");
|
||||
|
|
@ -442,7 +441,7 @@ TEST_CASE("[AABB] Has point") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Expanding") {
|
||||
const AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
constexpr AABB aabb = AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6));
|
||||
CHECK_MESSAGE(
|
||||
aabb.expand(Vector3(-1, 3, 0)).is_equal_approx(aabb),
|
||||
"expand() with contained point should return the expected AABB.");
|
||||
|
|
@ -461,8 +460,8 @@ TEST_CASE("[AABB] Expanding") {
|
|||
}
|
||||
|
||||
TEST_CASE("[AABB] Finite number checks") {
|
||||
const Vector3 x(0, 1, 2);
|
||||
const Vector3 infinite(NAN, NAN, NAN);
|
||||
constexpr Vector3 x(0, 1, 2);
|
||||
constexpr Vector3 infinite(Math::NaN, Math::NaN, Math::NaN);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
AABB(x, x).is_finite(),
|
||||
|
|
@ -481,5 +480,3 @@ TEST_CASE("[AABB] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestAABB
|
||||
|
||||
#endif // TEST_AABB_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_ASTAR_H
|
||||
#define TEST_ASTAR_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/a_star.h"
|
||||
|
||||
|
|
@ -215,7 +214,7 @@ TEST_CASE("[AStar3D] Add/Remove") {
|
|||
|
||||
TEST_CASE("[Stress][AStar3D] Find paths") {
|
||||
// Random stress tests with Floyd-Warshall.
|
||||
const int N = 30;
|
||||
constexpr int N = 30;
|
||||
Math::seed(0);
|
||||
|
||||
for (int test = 0; test < 1000; test++) {
|
||||
|
|
@ -281,7 +280,7 @@ TEST_CASE("[Stress][AStar3D] Find paths") {
|
|||
float d[N][N];
|
||||
for (int u = 0; u < N; u++) {
|
||||
for (int v = 0; v < N; v++) {
|
||||
d[u][v] = (u == v || adj[u][v]) ? p[u].distance_to(p[v]) : INFINITY;
|
||||
d[u][v] = (u == v || adj[u][v]) ? p[u].distance_to(p[v]) : Math::INF;
|
||||
}
|
||||
}
|
||||
for (int w = 0; w < N; w++) {
|
||||
|
|
@ -358,5 +357,3 @@ TEST_CASE("[Stress][AStar3D] Find paths") {
|
|||
}
|
||||
}
|
||||
} // namespace TestAStar
|
||||
|
||||
#endif // TEST_ASTAR_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_BASIS_H
|
||||
#define TEST_BASIS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/basis.h"
|
||||
#include "core/math/random_number_generator.h"
|
||||
|
|
@ -39,11 +38,11 @@
|
|||
namespace TestBasis {
|
||||
|
||||
Vector3 deg_to_rad(const Vector3 &p_rotation) {
|
||||
return p_rotation / 180.0 * Math_PI;
|
||||
return p_rotation / 180.0 * Math::PI;
|
||||
}
|
||||
|
||||
Vector3 rad2deg(const Vector3 &p_rotation) {
|
||||
return p_rotation / Math_PI * 180.0;
|
||||
return p_rotation / Math::PI * 180.0;
|
||||
}
|
||||
|
||||
String get_rot_order_name(EulerOrder ro) {
|
||||
|
|
@ -219,7 +218,7 @@ TEST_CASE("[Stress][Basis] Euler conversions") {
|
|||
TEST_CASE("[Basis] Set axis angle") {
|
||||
Vector3 axis;
|
||||
real_t angle;
|
||||
real_t pi = (real_t)Math_PI;
|
||||
real_t pi = (real_t)Math::PI;
|
||||
|
||||
// Testing the singularity when the angle is 0°.
|
||||
Basis identity(1, 0, 0, 0, 1, 0, 0, 0, 1);
|
||||
|
|
@ -270,8 +269,8 @@ TEST_CASE("[Basis] Set axis angle") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Basis] Finite number checks") {
|
||||
const Vector3 x(0, 1, 2);
|
||||
const Vector3 infinite(NAN, NAN, NAN);
|
||||
constexpr Vector3 x(0, 1, 2);
|
||||
constexpr Vector3 infinite(Math::NaN, Math::NaN, Math::NaN);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Basis(x, x, x).is_finite(),
|
||||
|
|
@ -328,7 +327,7 @@ TEST_CASE("[Basis] Is conformal checks") {
|
|||
"Basis with non-uniform scale should not be conformal.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
Basis(Vector3(Math_SQRT12, Math_SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_conformal(),
|
||||
Basis(Vector3(Math::SQRT12, Math::SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_conformal(),
|
||||
"Basis with the X axis skewed 45 degrees should not be conformal.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -358,7 +357,7 @@ TEST_CASE("[Basis] Is orthogonal checks") {
|
|||
"Basis with a flip, rotation, and uniform scale should be orthogonal.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
Basis(Vector3(Math_SQRT12, Math_SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_orthogonal(),
|
||||
Basis(Vector3(Math::SQRT12, Math::SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_orthogonal(),
|
||||
"Basis with the X axis skewed 45 degrees should not be orthogonal.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -388,7 +387,7 @@ TEST_CASE("[Basis] Is orthonormal checks") {
|
|||
"Basis with a flip, rotation, and uniform scale should not be orthonormal.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
Basis(Vector3(Math_SQRT12, Math_SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_orthonormal(),
|
||||
Basis(Vector3(Math::SQRT12, Math::SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_orthonormal(),
|
||||
"Basis with the X axis skewed 45 degrees should not be orthonormal.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
|
|
@ -418,7 +417,7 @@ TEST_CASE("[Basis] Is rotation checks") {
|
|||
"Basis with a squeeze should not be a rotation.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
Basis(Vector3(Math_SQRT12, Math_SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_rotation(),
|
||||
Basis(Vector3(Math::SQRT12, Math::SQRT12, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)).is_rotation(),
|
||||
"Basis with the X axis skewed 45 degrees should not be a rotation.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
|
|
@ -427,5 +426,3 @@ TEST_CASE("[Basis] Is rotation checks") {
|
|||
}
|
||||
|
||||
} // namespace TestBasis
|
||||
|
||||
#endif // TEST_BASIS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_COLOR_H
|
||||
#define TEST_COLOR_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/color.h"
|
||||
|
||||
|
|
@ -38,7 +37,7 @@
|
|||
namespace TestColor {
|
||||
|
||||
TEST_CASE("[Color] Constructor methods") {
|
||||
const Color blue_rgba = Color(0.25098, 0.376471, 1, 0.501961);
|
||||
constexpr Color blue_rgba = Color(0.25098, 0.376471, 1, 0.501961);
|
||||
const Color blue_html = Color::html("#4060ff80");
|
||||
const Color blue_hex = Color::hex(0x4060ff80);
|
||||
const Color blue_hex64 = Color::hex64(0x4040'6060'ffff'8080);
|
||||
|
|
@ -61,7 +60,7 @@ TEST_CASE("[Color] Constructor methods") {
|
|||
html_invalid.is_equal_approx(Color()),
|
||||
"Creation with invalid HTML notation should result in a Color with the default values.");
|
||||
|
||||
const Color green_rgba = Color(0, 1, 0, 0.25);
|
||||
constexpr Color green_rgba = Color(0, 1, 0, 0.25);
|
||||
const Color green_hsva = Color(0, 0, 0).from_hsv(120 / 360.0, 1, 1, 0.25);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -70,8 +69,8 @@ TEST_CASE("[Color] Constructor methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Color] Operators") {
|
||||
const Color blue = Color(0.2, 0.2, 1);
|
||||
const Color dark_red = Color(0.3, 0.1, 0.1);
|
||||
constexpr Color blue = Color(0.2, 0.2, 1);
|
||||
constexpr Color dark_red = Color(0.3, 0.1, 0.1);
|
||||
|
||||
// Color components may be negative. Also, the alpha component may be greater than 1.0.
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -98,7 +97,7 @@ TEST_CASE("[Color] Operators") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Color] Reading methods") {
|
||||
const Color dark_blue = Color(0, 0, 0.5, 0.4);
|
||||
constexpr Color dark_blue = Color(0, 0, 0.5, 0.4);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
dark_blue.get_h() == doctest::Approx(240.0f / 360.0f),
|
||||
|
|
@ -112,8 +111,8 @@ TEST_CASE("[Color] Reading methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Color] Conversion methods") {
|
||||
const Color cyan = Color(0, 1, 1);
|
||||
const Color cyan_transparent = Color(0, 1, 1, 0);
|
||||
constexpr Color cyan = Color(0, 1, 1);
|
||||
constexpr Color cyan_transparent = Color(0, 1, 1, 0);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
cyan.to_html() == "00ffffff",
|
||||
|
|
@ -145,7 +144,7 @@ TEST_CASE("[Color] Conversion methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Color] Linear <-> sRGB conversion") {
|
||||
const Color color = Color(0.35, 0.5, 0.6, 0.7);
|
||||
constexpr Color color = Color(0.35, 0.5, 0.6, 0.7);
|
||||
const Color color_linear = color.srgb_to_linear();
|
||||
const Color color_srgb = color.linear_to_srgb();
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -204,13 +203,13 @@ TEST_CASE("[Color] Validation methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Color] Manipulation methods") {
|
||||
const Color blue = Color(0, 0, 1, 0.4);
|
||||
constexpr Color blue = Color(0, 0, 1, 0.4);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
blue.inverted().is_equal_approx(Color(1, 1, 0, 0.4)),
|
||||
"Inverted color should have its red, green and blue components inverted.");
|
||||
|
||||
const Color purple = Color(0.5, 0.2, 0.5, 0.25);
|
||||
constexpr Color purple = Color(0.5, 0.2, 0.5, 0.25);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
purple.lightened(0.2).is_equal_approx(Color(0.6, 0.36, 0.6, 0.25)),
|
||||
|
|
@ -219,13 +218,11 @@ TEST_CASE("[Color] Manipulation methods") {
|
|||
purple.darkened(0.2).is_equal_approx(Color(0.4, 0.16, 0.4, 0.25)),
|
||||
"Color should be darkened by the expected amount.");
|
||||
|
||||
const Color red = Color(1, 0, 0, 0.2);
|
||||
const Color yellow = Color(1, 1, 0, 0.8);
|
||||
constexpr Color red = Color(1, 0, 0, 0.2);
|
||||
constexpr Color yellow = Color(1, 1, 0, 0.8);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
red.lerp(yellow, 0.5).is_equal_approx(Color(1, 0.5, 0, 0.5)),
|
||||
"Red interpolated with yellow should be orange (with interpolated alpha).");
|
||||
}
|
||||
} // namespace TestColor
|
||||
|
||||
#endif // TEST_COLOR_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_EXPRESSION_H
|
||||
#define TEST_EXPRESSION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/expression.h"
|
||||
|
||||
|
|
@ -322,15 +321,11 @@ TEST_CASE("[Expression] Boolean expressions") {
|
|||
TEST_CASE("[Expression] Expressions with variables") {
|
||||
Expression expression;
|
||||
|
||||
PackedStringArray parameter_names;
|
||||
parameter_names.push_back("foo");
|
||||
parameter_names.push_back("bar");
|
||||
PackedStringArray parameter_names = { "foo", "bar" };
|
||||
CHECK_MESSAGE(
|
||||
expression.parse("foo + bar + 50", parameter_names) == OK,
|
||||
"The expression should parse successfully.");
|
||||
Array values;
|
||||
values.push_back(60);
|
||||
values.push_back(20);
|
||||
Array values = { 60, 20 };
|
||||
CHECK_MESSAGE(
|
||||
int(expression.execute(values)) == 130,
|
||||
"The expression should return the expected value.");
|
||||
|
|
@ -341,9 +336,7 @@ TEST_CASE("[Expression] Expressions with variables") {
|
|||
CHECK_MESSAGE(
|
||||
expression.parse("foo + bar + 50", parameter_names_invalid) == OK,
|
||||
"The expression should parse successfully.");
|
||||
Array values_invalid;
|
||||
values_invalid.push_back(60);
|
||||
values_invalid.push_back(20);
|
||||
Array values_invalid = { 60, 20 };
|
||||
// Invalid parameters will parse successfully but print an error message when executing.
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -352,31 +345,21 @@ TEST_CASE("[Expression] Expressions with variables") {
|
|||
ERR_PRINT_ON;
|
||||
|
||||
// Mismatched argument count (more values than parameters).
|
||||
PackedStringArray parameter_names_mismatch;
|
||||
parameter_names_mismatch.push_back("foo");
|
||||
parameter_names_mismatch.push_back("bar");
|
||||
PackedStringArray parameter_names_mismatch = { "foo", "bar" };
|
||||
CHECK_MESSAGE(
|
||||
expression.parse("foo + bar + 50", parameter_names_mismatch) == OK,
|
||||
"The expression should parse successfully.");
|
||||
Array values_mismatch;
|
||||
values_mismatch.push_back(60);
|
||||
values_mismatch.push_back(20);
|
||||
values_mismatch.push_back(110);
|
||||
Array values_mismatch = { 60, 20, 110 };
|
||||
CHECK_MESSAGE(
|
||||
int(expression.execute(values_mismatch)) == 130,
|
||||
"The expression should return the expected value.");
|
||||
|
||||
// Mismatched argument count (more parameters than values).
|
||||
PackedStringArray parameter_names_mismatch2;
|
||||
parameter_names_mismatch2.push_back("foo");
|
||||
parameter_names_mismatch2.push_back("bar");
|
||||
parameter_names_mismatch2.push_back("baz");
|
||||
PackedStringArray parameter_names_mismatch2 = { "foo", "bar", "baz" };
|
||||
CHECK_MESSAGE(
|
||||
expression.parse("foo + bar + baz + 50", parameter_names_mismatch2) == OK,
|
||||
"The expression should parse successfully.");
|
||||
Array values_mismatch2;
|
||||
values_mismatch2.push_back(60);
|
||||
values_mismatch2.push_back(20);
|
||||
Array values_mismatch2 = { 60, 20 };
|
||||
// Having more parameters than values will parse successfully but print an
|
||||
// error message when executing.
|
||||
ERR_PRINT_OFF;
|
||||
|
|
@ -505,5 +488,3 @@ TEST_CASE("[Expression] Unusual expressions") {
|
|||
// "`(-9223372036854775807 - 1) / -1` should return the expected result.");
|
||||
}
|
||||
} // namespace TestExpression
|
||||
|
||||
#endif // TEST_EXPRESSION_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_GEOMETRY_2D_H
|
||||
#define TEST_GEOMETRY_2D_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/geometry_2d.h"
|
||||
|
||||
|
|
@ -164,11 +163,11 @@ TEST_CASE("[Geometry2D] Segment intersection") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Geometry2D] Segment intersection with circle") {
|
||||
real_t minus_one = -1.0;
|
||||
real_t zero = 0.0;
|
||||
real_t one_quarter = 0.25;
|
||||
real_t three_quarters = 0.75;
|
||||
real_t one = 1.0;
|
||||
constexpr real_t minus_one = -1.0;
|
||||
constexpr real_t zero = 0.0;
|
||||
constexpr real_t one_quarter = 0.25;
|
||||
constexpr real_t three_quarters = 0.75;
|
||||
constexpr real_t one = 1.0;
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Geometry2D::segment_intersects_circle(Vector2(0, 0), Vector2(4, 0), Vector2(0, 0), 1.0) == doctest::Approx(one_quarter),
|
||||
|
|
@ -262,22 +261,25 @@ TEST_CASE("[Geometry2D] Segment intersection with polygon") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Geometry2D] Closest point to segment") {
|
||||
Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) };
|
||||
CHECK(Geometry2D::get_closest_point_to_segment(Vector2(4.1, 4.1), s).is_equal_approx(Vector2(4, 4)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-4.1, -4.1), s).is_equal_approx(Vector2(-4, -4)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0)));
|
||||
Vector2 a = Vector2(-4, -4);
|
||||
Vector2 b = Vector2(4, 4);
|
||||
CHECK(Geometry2D::get_closest_point_to_segment(Vector2(4.1, 4.1), a, b).is_equal_approx(Vector2(4, 4)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-4.1, -4.1), a, b).is_equal_approx(Vector2(-4, -4)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-1, 1), a, b).is_equal_approx(Vector2(0, 0)));
|
||||
|
||||
Vector2 t[] = { Vector2(1, -2), Vector2(1, -2) };
|
||||
a = Vector2(1, -2);
|
||||
b = Vector2(1, -2);
|
||||
CHECK_MESSAGE(
|
||||
Geometry2D::get_closest_point_to_segment(Vector2(-3, 4), t).is_equal_approx(Vector2(1, -2)),
|
||||
Geometry2D::get_closest_point_to_segment(Vector2(-3, 4), a, b).is_equal_approx(Vector2(1, -2)),
|
||||
"Line segment is only a single point. This point should be the closest.");
|
||||
}
|
||||
|
||||
TEST_CASE("[Geometry2D] Closest point to uncapped segment") {
|
||||
Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) };
|
||||
CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-4, -6), s).is_equal_approx(Vector2(-5, -5)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(4, 6), s).is_equal_approx(Vector2(5, 5)));
|
||||
constexpr Vector2 a = Vector2(-4, -4);
|
||||
constexpr Vector2 b = Vector2(4, 4);
|
||||
CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-1, 1), a, b).is_equal_approx(Vector2(0, 0)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-4, -6), a, b).is_equal_approx(Vector2(-5, -5)));
|
||||
CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(4, 6), a, b).is_equal_approx(Vector2(5, 5)));
|
||||
}
|
||||
|
||||
TEST_CASE("[Geometry2D] Closest points between segments") {
|
||||
|
|
@ -888,5 +890,3 @@ TEST_CASE("[Geometry2D] Bresenham line") {
|
|||
}
|
||||
}
|
||||
} // namespace TestGeometry2D
|
||||
|
||||
#endif // TEST_GEOMETRY_2D_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_GEOMETRY_3D_H
|
||||
#define TEST_GEOMETRY_3D_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/geometry_3d.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -47,7 +46,7 @@ TEST_CASE("[Geometry3D] Closest Distance Between Segments") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Geometry3D] Build Box Planes") {
|
||||
const Vector3 extents = Vector3(5, 5, 20);
|
||||
constexpr Vector3 extents = Vector3(5, 5, 20);
|
||||
Vector<Plane> box = Geometry3D::build_box_planes(extents);
|
||||
CHECK(box.size() == 6);
|
||||
CHECK(extents.x == box[0].d);
|
||||
|
|
@ -130,8 +129,9 @@ TEST_CASE("[Geometry3D] Compute Convex Mesh Points") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Geometry3D] Get Closest Point To Segment") {
|
||||
Vector3 segment[2] = { Vector3(1, 1, 1), Vector3(5, 5, 5) };
|
||||
Vector3 output = Geometry3D::get_closest_point_to_segment(Vector3(2, 1, 4), segment);
|
||||
constexpr Vector3 a = Vector3(1, 1, 1);
|
||||
constexpr Vector3 b = Vector3(5, 5, 5);
|
||||
Vector3 output = Geometry3D::get_closest_point_to_segment(Vector3(2, 1, 4), a, b);
|
||||
CHECK(output.is_equal_approx(Vector3(2.33333, 2.33333, 2.33333)));
|
||||
}
|
||||
|
||||
|
|
@ -183,22 +183,19 @@ TEST_CASE("[Geometry3D] Segment Intersects Triangle") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Geometry3D] Triangle and Box Overlap") {
|
||||
Vector3 good_triangle[3] = { Vector3(3, 2, 3), Vector3(2, 2, 1), Vector3(2, 1, 1) };
|
||||
constexpr Vector3 good_triangle[3] = { Vector3(3, 2, 3), Vector3(2, 2, 1), Vector3(2, 1, 1) };
|
||||
CHECK(Geometry3D::triangle_box_overlap(Vector3(0, 0, 0), Vector3(5, 5, 5), good_triangle) == true);
|
||||
Vector3 bad_triangle[3] = { Vector3(100, 100, 100), Vector3(-100, -100, -100), Vector3(10, 10, 10) };
|
||||
constexpr Vector3 bad_triangle[3] = { Vector3(100, 100, 100), Vector3(-100, -100, -100), Vector3(10, 10, 10) };
|
||||
CHECK(Geometry3D::triangle_box_overlap(Vector3(1000, 1000, 1000), Vector3(1, 1, 1), bad_triangle) == false);
|
||||
}
|
||||
|
||||
TEST_CASE("[Geometry3D] Triangle and Sphere Intersect") {
|
||||
Vector<Vector3> triangle;
|
||||
triangle.push_back(Vector3(3, 0, 0));
|
||||
triangle.push_back(Vector3(-3, 0, 0));
|
||||
triangle.push_back(Vector3(0, 3, 0));
|
||||
constexpr Vector3 triangle_a = Vector3(3, 0, 0);
|
||||
constexpr Vector3 triangle_b = Vector3(-3, 0, 0);
|
||||
constexpr Vector3 triangle_c = Vector3(0, 3, 0);
|
||||
Vector3 triangle_contact, sphere_contact;
|
||||
CHECK(Geometry3D::triangle_sphere_intersection_test(&triangle[0], Vector3(0, -1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true);
|
||||
CHECK(Geometry3D::triangle_sphere_intersection_test(&triangle[0], Vector3(0, 1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true);
|
||||
CHECK(Geometry3D::triangle_sphere_intersection_test(&triangle[0], Vector3(0, 1, 0), Vector3(20, 0, 0), 5, triangle_contact, sphere_contact) == false);
|
||||
CHECK(Geometry3D::triangle_sphere_intersection_test(triangle_a, triangle_b, triangle_c, Vector3(0, -1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true);
|
||||
CHECK(Geometry3D::triangle_sphere_intersection_test(triangle_a, triangle_b, triangle_c, Vector3(0, 1, 0), Vector3(0, 0, 0), 5, triangle_contact, sphere_contact) == true);
|
||||
CHECK(Geometry3D::triangle_sphere_intersection_test(triangle_a, triangle_b, triangle_c, Vector3(0, 1, 0), Vector3(20, 0, 0), 5, triangle_contact, sphere_contact) == false);
|
||||
}
|
||||
} // namespace TestGeometry3D
|
||||
|
||||
#endif // TEST_GEOMETRY_3D_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_MATH_FUNCS_H
|
||||
#define TEST_MATH_FUNCS_H
|
||||
#pragma once
|
||||
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
|
|
@ -47,15 +46,15 @@ TEST_CASE("[Math] C++ macros") {
|
|||
// `max` is lower than `min`.
|
||||
CHECK(CLAMP(620, 600, 50) == 50);
|
||||
|
||||
CHECK(ABS(-5) == 5);
|
||||
CHECK(ABS(0) == 0);
|
||||
CHECK(ABS(5) == 5);
|
||||
CHECK(Math::abs(-5) == 5);
|
||||
CHECK(Math::abs(0) == 0);
|
||||
CHECK(Math::abs(5) == 5);
|
||||
|
||||
CHECK(SIGN(-5) == -1.0);
|
||||
CHECK(SIGN(0) == 0.0);
|
||||
CHECK(SIGN(5) == 1.0);
|
||||
// Check that SIGN(NAN) returns 0.0.
|
||||
CHECK(SIGN(NAN) == 0.0);
|
||||
// Check that SIGN(Math::NaN) returns 0.0.
|
||||
CHECK(SIGN(Math::NaN) == 0.0);
|
||||
}
|
||||
|
||||
TEST_CASE("[Math] Power of two functions") {
|
||||
|
|
@ -190,7 +189,7 @@ TEST_CASE_TEMPLATE("[Math] asin/acos/atan", T, float, double) {
|
|||
CHECK(Math::acos((T)0.5) == doctest::Approx((T)1.0471975512));
|
||||
CHECK(Math::acos((T)1.0) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::acos((T)2.0) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::acos((T)-2.0) == doctest::Approx((T)Math_PI));
|
||||
CHECK(Math::acos((T)-2.0) == doctest::Approx((T)Math::PI));
|
||||
|
||||
CHECK(Math::atan((T)-0.1) == doctest::Approx((T)-0.0996686525));
|
||||
CHECK(Math::atan((T)0.1) == doctest::Approx((T)0.0996686525));
|
||||
|
|
@ -292,10 +291,10 @@ TEST_CASE_TEMPLATE("[Math] pow/log/log2/exp/sqrt", T, float, double) {
|
|||
|
||||
TEST_CASE_TEMPLATE("[Math] is_nan/is_inf", T, float, double) {
|
||||
CHECK(!Math::is_nan((T)0.0));
|
||||
CHECK(Math::is_nan((T)NAN));
|
||||
CHECK(Math::is_nan((T)Math::NaN));
|
||||
|
||||
CHECK(!Math::is_inf((T)0.0));
|
||||
CHECK(Math::is_inf((T)INFINITY));
|
||||
CHECK(Math::is_inf((T)Math::INF));
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] linear_to_db", T, float, double) {
|
||||
|
|
@ -388,15 +387,15 @@ TEST_CASE_TEMPLATE("[Math] remap", T, float, double) {
|
|||
|
||||
TEST_CASE_TEMPLATE("[Math] angle_difference", T, float, double) {
|
||||
// Loops around, should return 0.0.
|
||||
CHECK(Math::angle_difference((T)0.0, (T)Math_TAU) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::angle_difference((T)Math_PI, (T)-Math_PI) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::angle_difference((T)0.0, (T)Math_TAU * (T)4.0) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::angle_difference((T)0.0, (T)Math::TAU) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::angle_difference((T)Math::PI, (T)-Math::PI) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::angle_difference((T)0.0, (T)Math::TAU * (T)4.0) == doctest::Approx((T)0.0));
|
||||
|
||||
// Rotation is clockwise, so it should return -PI.
|
||||
CHECK(Math::angle_difference((T)0.0, (T)Math_PI) == doctest::Approx((T)-Math_PI));
|
||||
CHECK(Math::angle_difference((T)0.0, (T)-Math_PI) == doctest::Approx((T)Math_PI));
|
||||
CHECK(Math::angle_difference((T)Math_PI, (T)0.0) == doctest::Approx((T)Math_PI));
|
||||
CHECK(Math::angle_difference((T)-Math_PI, (T)0.0) == doctest::Approx((T)-Math_PI));
|
||||
CHECK(Math::angle_difference((T)0.0, (T)Math::PI) == doctest::Approx((T)-Math::PI));
|
||||
CHECK(Math::angle_difference((T)0.0, (T)-Math::PI) == doctest::Approx((T)Math::PI));
|
||||
CHECK(Math::angle_difference((T)Math::PI, (T)0.0) == doctest::Approx((T)Math::PI));
|
||||
CHECK(Math::angle_difference((T)-Math::PI, (T)0.0) == doctest::Approx((T)-Math::PI));
|
||||
|
||||
CHECK(Math::angle_difference((T)0.0, (T)3.0) == doctest::Approx((T)3.0));
|
||||
CHECK(Math::angle_difference((T)1.0, (T)-2.0) == doctest::Approx((T)-3.0));
|
||||
|
|
@ -407,23 +406,23 @@ TEST_CASE_TEMPLATE("[Math] angle_difference", T, float, double) {
|
|||
|
||||
TEST_CASE_TEMPLATE("[Math] lerp_angle", T, float, double) {
|
||||
// Counter-clockwise rotation.
|
||||
CHECK(Math::lerp_angle((T)0.24 * Math_TAU, 0.75 * Math_TAU, 0.5) == doctest::Approx((T)-0.005 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)0.24 * Math::TAU, 0.75 * Math::TAU, 0.5) == doctest::Approx((T)-0.005 * Math::TAU));
|
||||
// Counter-clockwise rotation.
|
||||
CHECK(Math::lerp_angle((T)0.25 * Math_TAU, 0.75 * Math_TAU, 0.5) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::lerp_angle((T)0.25 * Math::TAU, 0.75 * Math::TAU, 0.5) == doctest::Approx((T)0.0));
|
||||
// Clockwise rotation.
|
||||
CHECK(Math::lerp_angle((T)0.26 * Math_TAU, 0.75 * Math_TAU, 0.5) == doctest::Approx((T)0.505 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)0.26 * Math::TAU, 0.75 * Math::TAU, 0.5) == doctest::Approx((T)0.505 * Math::TAU));
|
||||
|
||||
CHECK(Math::lerp_angle((T)-0.25 * Math_TAU, 1.25 * Math_TAU, 0.5) == doctest::Approx((T)-0.5 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)0.72 * Math_TAU, 1.44 * Math_TAU, 0.96) == doctest::Approx((T)0.4512 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)0.72 * Math_TAU, 1.44 * Math_TAU, 1.04) == doctest::Approx((T)0.4288 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)-0.25 * Math::TAU, 1.25 * Math::TAU, 0.5) == doctest::Approx((T)-0.5 * Math::TAU));
|
||||
CHECK(Math::lerp_angle((T)0.72 * Math::TAU, 1.44 * Math::TAU, 0.96) == doctest::Approx((T)0.4512 * Math::TAU));
|
||||
CHECK(Math::lerp_angle((T)0.72 * Math::TAU, 1.44 * Math::TAU, 1.04) == doctest::Approx((T)0.4288 * Math::TAU));
|
||||
|
||||
// Initial and final angles are effectively identical, so the value returned
|
||||
// should always be the same regardless of the `weight` parameter.
|
||||
CHECK(Math::lerp_angle((T)-4 * Math_TAU, 4 * Math_TAU, -1.0) == doctest::Approx((T)-4.0 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math_TAU, 4 * Math_TAU, 0.0) == doctest::Approx((T)-4.0 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math_TAU, 4 * Math_TAU, 0.5) == doctest::Approx((T)-4.0 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math_TAU, 4 * Math_TAU, 1.0) == doctest::Approx((T)-4.0 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math_TAU, 4 * Math_TAU, 500.0) == doctest::Approx((T)-4.0 * Math_TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math::TAU, 4 * Math::TAU, -1.0) == doctest::Approx((T)-4.0 * Math::TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math::TAU, 4 * Math::TAU, 0.0) == doctest::Approx((T)-4.0 * Math::TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math::TAU, 4 * Math::TAU, 0.5) == doctest::Approx((T)-4.0 * Math::TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math::TAU, 4 * Math::TAU, 1.0) == doctest::Approx((T)-4.0 * Math::TAU));
|
||||
CHECK(Math::lerp_angle((T)-4 * Math::TAU, 4 * Math::TAU, 500.0) == doctest::Approx((T)-4.0 * Math::TAU));
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] move_toward", T, float, double) {
|
||||
|
|
@ -437,16 +436,16 @@ TEST_CASE_TEMPLATE("[Math] move_toward", T, float, double) {
|
|||
|
||||
TEST_CASE_TEMPLATE("[Math] rotate_toward", T, float, double) {
|
||||
// Rotate toward.
|
||||
CHECK(Math::rotate_toward((T)0.0, (T)Math_PI * (T)0.75, (T)1.5) == doctest::Approx((T)1.5));
|
||||
CHECK(Math::rotate_toward((T)0.0, (T)Math::PI * (T)0.75, (T)1.5) == doctest::Approx((T)1.5));
|
||||
CHECK(Math::rotate_toward((T)-2.0, (T)1.0, (T)2.5) == doctest::Approx((T)0.5));
|
||||
CHECK(Math::rotate_toward((T)-2.0, (T)Math_PI, (T)Math_PI) == doctest::Approx((T)-Math_PI));
|
||||
CHECK(Math::rotate_toward((T)1.0, (T)Math_PI, (T)20.0) == doctest::Approx((T)Math_PI));
|
||||
CHECK(Math::rotate_toward((T)-2.0, (T)Math::PI, (T)Math::PI) == doctest::Approx((T)-Math::PI));
|
||||
CHECK(Math::rotate_toward((T)1.0, (T)Math::PI, (T)20.0) == doctest::Approx((T)Math::PI));
|
||||
|
||||
// Rotate away.
|
||||
CHECK(Math::rotate_toward((T)0.0, (T)0.0, (T)-1.5) == doctest::Approx((T)-1.5));
|
||||
CHECK(Math::rotate_toward((T)0.0, (T)0.0, (T)-Math_PI) == doctest::Approx((T)-Math_PI));
|
||||
CHECK(Math::rotate_toward((T)3.0, (T)Math_PI, (T)-Math_PI) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::rotate_toward((T)2.0, (T)Math_PI, (T)-1.5) == doctest::Approx((T)0.5));
|
||||
CHECK(Math::rotate_toward((T)0.0, (T)0.0, (T)-Math::PI) == doctest::Approx((T)-Math::PI));
|
||||
CHECK(Math::rotate_toward((T)3.0, (T)Math::PI, (T)-Math::PI) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::rotate_toward((T)2.0, (T)Math::PI, (T)-1.5) == doctest::Approx((T)0.5));
|
||||
CHECK(Math::rotate_toward((T)1.0, (T)2.0, (T)-0.5) == doctest::Approx((T)0.5));
|
||||
CHECK(Math::rotate_toward((T)2.5, (T)2.0, (T)-0.5) == doctest::Approx((T)3.0));
|
||||
CHECK(Math::rotate_toward((T)-1.0, (T)1.0, (T)-1.0) == doctest::Approx((T)-2.0));
|
||||
|
|
@ -586,10 +585,10 @@ TEST_CASE_TEMPLATE("[Math] pingpong", T, float, double) {
|
|||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] deg_to_rad/rad_to_deg", T, float, double) {
|
||||
CHECK(Math::deg_to_rad((T)180.0) == doctest::Approx((T)Math_PI));
|
||||
CHECK(Math::deg_to_rad((T)180.0) == doctest::Approx((T)Math::PI));
|
||||
CHECK(Math::deg_to_rad((T)-27.0) == doctest::Approx((T)-0.471239));
|
||||
|
||||
CHECK(Math::rad_to_deg((T)Math_PI) == doctest::Approx((T)180.0));
|
||||
CHECK(Math::rad_to_deg((T)Math::PI) == doctest::Approx((T)180.0));
|
||||
CHECK(Math::rad_to_deg((T)-1.5) == doctest::Approx((T)-85.94366927));
|
||||
}
|
||||
|
||||
|
|
@ -608,11 +607,11 @@ TEST_CASE_TEMPLATE("[Math] cubic_interpolate", T, float, double) {
|
|||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] cubic_interpolate_angle", T, float, double) {
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.0) == doctest::Approx((T)Math_PI * (1.0 / 6.0)));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.25) == doctest::Approx((T)0.973566));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.5) == doctest::Approx((T)Math_PI / 2.0));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.75) == doctest::Approx((T)2.16803));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)1.0) == doctest::Approx((T)Math_PI * (5.0 / 6.0)));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.0) == doctest::Approx((T)Math::PI * (1.0 / 6.0)));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.25) == doctest::Approx((T)0.973566));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.5) == doctest::Approx((T)Math::PI / 2.0));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.75) == doctest::Approx((T)2.16803));
|
||||
CHECK(Math::cubic_interpolate_angle((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)1.0) == doctest::Approx((T)Math::PI * (5.0 / 6.0)));
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] cubic_interpolate_in_time", T, float, double) {
|
||||
|
|
@ -624,11 +623,11 @@ TEST_CASE_TEMPLATE("[Math] cubic_interpolate_in_time", T, float, double) {
|
|||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] cubic_interpolate_angle_in_time", T, float, double) {
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.0, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.25, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)0.494964));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.5, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)1.27627));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)0.75, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)2.07394));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math_PI * (1.0 / 6.0)), (T)(Math_PI * (5.0 / 6.0)), (T)0.0, (T)Math_PI, (T)1.0, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)Math_PI * (5.0 / 6.0)));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.0, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)0.0));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.25, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)0.494964));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.5, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)1.27627));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)0.75, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)2.07394));
|
||||
CHECK(Math::cubic_interpolate_angle_in_time((T)(Math::PI * (1.0 / 6.0)), (T)(Math::PI * (5.0 / 6.0)), (T)0.0, (T)Math::PI, (T)1.0, (T)0.5, (T)0.0, (T)1.0) == doctest::Approx((T)Math::PI * (5.0 / 6.0)));
|
||||
}
|
||||
|
||||
TEST_CASE_TEMPLATE("[Math] bezier_interpolate", T, float, double) {
|
||||
|
|
@ -640,5 +639,3 @@ TEST_CASE_TEMPLATE("[Math] bezier_interpolate", T, float, double) {
|
|||
}
|
||||
|
||||
} // namespace TestMath
|
||||
|
||||
#endif // TEST_MATH_FUNCS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_PLANE_H
|
||||
#define TEST_PLANE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/plane.h"
|
||||
|
||||
|
|
@ -40,22 +39,22 @@ namespace TestPlane {
|
|||
// Plane
|
||||
|
||||
TEST_CASE("[Plane] Constructor methods") {
|
||||
const Plane plane = Plane(32, 22, 16, 3);
|
||||
const Plane plane_vector = Plane(Vector3(32, 22, 16), 3);
|
||||
const Plane plane_copy_plane = Plane(plane);
|
||||
constexpr Plane plane = Plane(32, 22, 16, 3);
|
||||
constexpr Plane plane_vector = Plane(Vector3(32, 22, 16), 3);
|
||||
constexpr Plane plane_copy_plane = Plane(plane);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
plane == plane_vector,
|
||||
"Planes created with same values but different methods should be equal.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
plane == plane_copy_plane,
|
||||
"Planes created with same values but different methods should be equal.");
|
||||
}
|
||||
|
||||
TEST_CASE("[Plane] Basic getters") {
|
||||
const Plane plane = Plane(32, 22, 16, 3);
|
||||
const Plane plane_normalized = Plane(32.0 / 42, 22.0 / 42, 16.0 / 42, 3.0 / 42);
|
||||
constexpr Plane plane = Plane(32, 22, 16, 3);
|
||||
constexpr Plane plane_normalized = Plane(32.0 / 42, 22.0 / 42, 16.0 / 42, 3.0 / 42);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
plane.get_normal().is_equal_approx(Vector3(32, 22, 16)),
|
||||
|
|
@ -83,8 +82,8 @@ TEST_CASE("[Plane] Basic setters") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Plane] Plane-point operations") {
|
||||
const Plane plane = Plane(32, 22, 16, 3);
|
||||
const Plane y_facing_plane = Plane(0, 1, 0, 4);
|
||||
constexpr Plane plane = Plane(32, 22, 16, 3);
|
||||
constexpr Plane y_facing_plane = Plane(0, 1, 0, 4);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
plane.get_center().is_equal_approx(Vector3(32 * 3, 22 * 3, 16 * 3)),
|
||||
|
|
@ -102,16 +101,16 @@ TEST_CASE("[Plane] Plane-point operations") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Plane] Has point") {
|
||||
const Plane x_facing_plane = Plane(1, 0, 0, 0);
|
||||
const Plane y_facing_plane = Plane(0, 1, 0, 0);
|
||||
const Plane z_facing_plane = Plane(0, 0, 1, 0);
|
||||
constexpr Plane x_facing_plane = Plane(1, 0, 0, 0);
|
||||
constexpr Plane y_facing_plane = Plane(0, 1, 0, 0);
|
||||
constexpr Plane z_facing_plane = Plane(0, 0, 1, 0);
|
||||
|
||||
const Vector3 x_axis_point = Vector3(10, 0, 0);
|
||||
const Vector3 y_axis_point = Vector3(0, 10, 0);
|
||||
const Vector3 z_axis_point = Vector3(0, 0, 10);
|
||||
constexpr Vector3 x_axis_point = Vector3(10, 0, 0);
|
||||
constexpr Vector3 y_axis_point = Vector3(0, 10, 0);
|
||||
constexpr Vector3 z_axis_point = Vector3(0, 0, 10);
|
||||
|
||||
const Plane x_facing_plane_with_d_offset = Plane(1, 0, 0, 1);
|
||||
const Vector3 y_axis_point_with_d_offset = Vector3(1, 10, 0);
|
||||
constexpr Plane x_facing_plane_with_d_offset = Plane(1, 0, 0, 1);
|
||||
constexpr Vector3 y_axis_point_with_d_offset = Vector3(1, 10, 0);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
x_facing_plane.has_point(y_axis_point),
|
||||
|
|
@ -140,9 +139,9 @@ TEST_CASE("[Plane] Has point") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Plane] Intersection") {
|
||||
const Plane x_facing_plane = Plane(1, 0, 0, 1);
|
||||
const Plane y_facing_plane = Plane(0, 1, 0, 2);
|
||||
const Plane z_facing_plane = Plane(0, 0, 1, 3);
|
||||
constexpr Plane x_facing_plane = Plane(1, 0, 0, 1);
|
||||
constexpr Plane y_facing_plane = Plane(0, 1, 0, 2);
|
||||
constexpr Plane z_facing_plane = Plane(0, 0, 1, 3);
|
||||
|
||||
Vector3 vec_out;
|
||||
|
||||
|
|
@ -169,10 +168,10 @@ TEST_CASE("[Plane] Intersection") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Plane] Finite number checks") {
|
||||
const Vector3 x(0, 1, 2);
|
||||
const Vector3 infinite_vec(NAN, NAN, NAN);
|
||||
const real_t y = 0;
|
||||
const real_t infinite_y = NAN;
|
||||
constexpr Vector3 x(0, 1, 2);
|
||||
constexpr Vector3 infinite_vec(Math::NaN, Math::NaN, Math::NaN);
|
||||
constexpr real_t y = 0;
|
||||
constexpr real_t infinite_y = Math::NaN;
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Plane(x, y).is_finite(),
|
||||
|
|
@ -191,5 +190,3 @@ TEST_CASE("[Plane] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestPlane
|
||||
|
||||
#endif // TEST_PLANE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_PROJECTION_H
|
||||
#define TEST_PROJECTION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/aabb.h"
|
||||
#include "core/math/plane.h"
|
||||
|
|
@ -183,12 +182,6 @@ TEST_CASE("[Projection] Vector transformation") {
|
|||
Vector4(4, 7, 11, 15),
|
||||
Vector4(4, 8, 12, 16));
|
||||
|
||||
Projection inverse(
|
||||
Vector4(-4.0 / 12, 0, 1, -8.0 / 12),
|
||||
Vector4(8.0 / 12, -1, -1, 16.0 / 12),
|
||||
Vector4(-20.0 / 12, 2, -1, 5.0 / 12),
|
||||
Vector4(1, -1, 1, -0.75));
|
||||
|
||||
Vector4 vec4(1, 2, 3, 4);
|
||||
CHECK(proj.xform(vec4).is_equal_approx(Vector4(33, 70, 112, 152)));
|
||||
CHECK(proj.xform_inv(vec4).is_equal_approx(Vector4(90, 107, 111, 120)));
|
||||
|
|
@ -449,6 +442,78 @@ TEST_CASE("[Projection] Perspective values extraction") {
|
|||
CHECK(zfar == doctest::Approx(50));
|
||||
CHECK(aspect == doctest::Approx(0.5));
|
||||
CHECK(fov == doctest::Approx(90));
|
||||
|
||||
persp.set_perspective(38, 1.3, 0.2, 8, false);
|
||||
|
||||
znear = persp.get_z_near();
|
||||
zfar = persp.get_z_far();
|
||||
aspect = persp.get_aspect();
|
||||
fov = persp.get_fov();
|
||||
|
||||
CHECK(znear == doctest::Approx(0.2));
|
||||
CHECK(zfar == doctest::Approx(8));
|
||||
CHECK(aspect == doctest::Approx(1.3));
|
||||
CHECK(fov == doctest::Approx(Projection::get_fovy(38, 1.3)));
|
||||
|
||||
persp.set_perspective(47, 2.5, 0.9, 14, true);
|
||||
|
||||
znear = persp.get_z_near();
|
||||
zfar = persp.get_z_far();
|
||||
aspect = persp.get_aspect();
|
||||
fov = persp.get_fov();
|
||||
|
||||
CHECK(znear == doctest::Approx(0.9));
|
||||
CHECK(zfar == doctest::Approx(14));
|
||||
CHECK(aspect == doctest::Approx(2.5));
|
||||
CHECK(fov == doctest::Approx(47));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Frustum values extraction") {
|
||||
Projection frustum = Projection::create_frustum_aspect(1.0, 4.0 / 3.0, Vector2(0.5, -0.25), 0.5, 50, true);
|
||||
|
||||
double znear = frustum.get_z_near();
|
||||
double zfar = frustum.get_z_far();
|
||||
double aspect = frustum.get_aspect();
|
||||
double fov = frustum.get_fov();
|
||||
|
||||
CHECK(znear == doctest::Approx(0.5));
|
||||
CHECK(zfar == doctest::Approx(50));
|
||||
CHECK(aspect == doctest::Approx(4.0 / 3.0));
|
||||
CHECK(fov == doctest::Approx(Math::rad_to_deg(Math::atan(2.0))));
|
||||
|
||||
frustum.set_frustum(2.0, 1.5, Vector2(-0.5, 2), 2, 12, false);
|
||||
|
||||
znear = frustum.get_z_near();
|
||||
zfar = frustum.get_z_far();
|
||||
aspect = frustum.get_aspect();
|
||||
fov = frustum.get_fov();
|
||||
|
||||
CHECK(znear == doctest::Approx(2));
|
||||
CHECK(zfar == doctest::Approx(12));
|
||||
CHECK(aspect == doctest::Approx(1.5));
|
||||
CHECK(fov == doctest::Approx(Math::rad_to_deg(Math::atan(1.0) + Math::atan(0.5))));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Orthographic values extraction") {
|
||||
Projection ortho = Projection::create_orthogonal(-2, 3, -0.5, 1.5, 1.2, 15);
|
||||
|
||||
double znear = ortho.get_z_near();
|
||||
double zfar = ortho.get_z_far();
|
||||
double aspect = ortho.get_aspect();
|
||||
|
||||
CHECK(znear == doctest::Approx(1.2));
|
||||
CHECK(zfar == doctest::Approx(15));
|
||||
CHECK(aspect == doctest::Approx(2.5));
|
||||
|
||||
ortho.set_orthogonal(-7, 2, 2.5, 5.5, 0.5, 6);
|
||||
|
||||
znear = ortho.get_z_near();
|
||||
zfar = ortho.get_z_far();
|
||||
aspect = ortho.get_aspect();
|
||||
|
||||
CHECK(znear == doctest::Approx(0.5));
|
||||
CHECK(zfar == doctest::Approx(6));
|
||||
CHECK(aspect == doctest::Approx(3));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Orthographic check") {
|
||||
|
|
@ -487,16 +552,48 @@ TEST_CASE("[Projection] Planes extraction") {
|
|||
CHECK(plane_array[Projection::PLANE_BOTTOM].normalized().is_equal_approx(planes[Projection::PLANE_BOTTOM].normalized()));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Half extents") {
|
||||
TEST_CASE("[Projection] Perspective Half extents") {
|
||||
constexpr real_t sqrt3 = 1.7320508;
|
||||
Projection persp = Projection::create_perspective(90, 1, 1, 40, false);
|
||||
Vector2 ne = persp.get_viewport_half_extents();
|
||||
Vector2 fe = persp.get_far_plane_half_extents();
|
||||
|
||||
CHECK(ne.is_equal_approx(Vector2(1, 1) * 1));
|
||||
CHECK(fe.is_equal_approx(Vector2(1, 1) * 40));
|
||||
|
||||
persp.set_perspective(120, sqrt3, 0.8, 10, true);
|
||||
ne = persp.get_viewport_half_extents();
|
||||
fe = persp.get_far_plane_half_extents();
|
||||
|
||||
CHECK(ne.is_equal_approx(Vector2(sqrt3, 1.0) * 0.8));
|
||||
CHECK(fe.is_equal_approx(Vector2(sqrt3, 1.0) * 10));
|
||||
|
||||
persp.set_perspective(60, 1.2, 0.5, 15, false);
|
||||
ne = persp.get_viewport_half_extents();
|
||||
fe = persp.get_far_plane_half_extents();
|
||||
|
||||
CHECK(ne.is_equal_approx(Vector2(sqrt3 / 3 * 1.2, sqrt3 / 3) * 0.5));
|
||||
CHECK(fe.is_equal_approx(Vector2(sqrt3 / 3 * 1.2, sqrt3 / 3) * 15));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Orthographic Half extents") {
|
||||
Projection ortho = Projection::create_orthogonal(-3, 3, -1.5, 1.5, 1.2, 15);
|
||||
Vector2 ne = ortho.get_viewport_half_extents();
|
||||
Vector2 fe = ortho.get_far_plane_half_extents();
|
||||
|
||||
CHECK(ne.is_equal_approx(Vector2(3, 1.5)));
|
||||
CHECK(fe.is_equal_approx(Vector2(3, 1.5)));
|
||||
|
||||
ortho.set_orthogonal(-7, 7, -2.5, 2.5, 0.5, 6);
|
||||
ne = ortho.get_viewport_half_extents();
|
||||
fe = ortho.get_far_plane_half_extents();
|
||||
|
||||
CHECK(ne.is_equal_approx(Vector2(7, 2.5)));
|
||||
CHECK(fe.is_equal_approx(Vector2(7, 2.5)));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Endpoints") {
|
||||
constexpr real_t sqrt3 = 1.7320508;
|
||||
Projection persp = Projection::create_perspective(90, 1, 1, 40, false);
|
||||
Vector3 ep[8];
|
||||
persp.get_endpoints(Transform3D(), ep);
|
||||
|
|
@ -509,8 +606,89 @@ TEST_CASE("[Projection] Endpoints") {
|
|||
CHECK(ep[5].is_equal_approx(Vector3(-1, -1, -1) * 1));
|
||||
CHECK(ep[6].is_equal_approx(Vector3(1, 1, -1) * 1));
|
||||
CHECK(ep[7].is_equal_approx(Vector3(1, -1, -1) * 1));
|
||||
|
||||
persp.set_perspective(120, sqrt3, 0.8, 10, true);
|
||||
persp.get_endpoints(Transform3D(), ep);
|
||||
|
||||
CHECK(ep[0].is_equal_approx(Vector3(-sqrt3, 1, -1) * 10));
|
||||
CHECK(ep[1].is_equal_approx(Vector3(-sqrt3, -1, -1) * 10));
|
||||
CHECK(ep[2].is_equal_approx(Vector3(sqrt3, 1, -1) * 10));
|
||||
CHECK(ep[3].is_equal_approx(Vector3(sqrt3, -1, -1) * 10));
|
||||
CHECK(ep[4].is_equal_approx(Vector3(-sqrt3, 1, -1) * 0.8));
|
||||
CHECK(ep[5].is_equal_approx(Vector3(-sqrt3, -1, -1) * 0.8));
|
||||
CHECK(ep[6].is_equal_approx(Vector3(sqrt3, 1, -1) * 0.8));
|
||||
CHECK(ep[7].is_equal_approx(Vector3(sqrt3, -1, -1) * 0.8));
|
||||
|
||||
persp.set_perspective(60, 1.2, 0.5, 15, false);
|
||||
persp.get_endpoints(Transform3D(), ep);
|
||||
|
||||
CHECK(ep[0].is_equal_approx(Vector3(-sqrt3 / 3 * 1.2, sqrt3 / 3, -1) * 15));
|
||||
CHECK(ep[1].is_equal_approx(Vector3(-sqrt3 / 3 * 1.2, -sqrt3 / 3, -1) * 15));
|
||||
CHECK(ep[2].is_equal_approx(Vector3(sqrt3 / 3 * 1.2, sqrt3 / 3, -1) * 15));
|
||||
CHECK(ep[3].is_equal_approx(Vector3(sqrt3 / 3 * 1.2, -sqrt3 / 3, -1) * 15));
|
||||
CHECK(ep[4].is_equal_approx(Vector3(-sqrt3 / 3 * 1.2, sqrt3 / 3, -1) * 0.5));
|
||||
CHECK(ep[5].is_equal_approx(Vector3(-sqrt3 / 3 * 1.2, -sqrt3 / 3, -1) * 0.5));
|
||||
CHECK(ep[6].is_equal_approx(Vector3(sqrt3 / 3 * 1.2, sqrt3 / 3, -1) * 0.5));
|
||||
CHECK(ep[7].is_equal_approx(Vector3(sqrt3 / 3 * 1.2, -sqrt3 / 3, -1) * 0.5));
|
||||
}
|
||||
|
||||
} //namespace TestProjection
|
||||
TEST_CASE("[Projection] LOD multiplier") {
|
||||
constexpr real_t sqrt3 = 1.7320508;
|
||||
Projection proj;
|
||||
real_t multiplier;
|
||||
|
||||
#endif // TEST_PROJECTION_H
|
||||
proj.set_perspective(60, 1, 1, 40, false);
|
||||
multiplier = proj.get_lod_multiplier();
|
||||
CHECK(multiplier == doctest::Approx(2 * sqrt3 / 3));
|
||||
|
||||
proj.set_perspective(120, 1.5, 0.5, 20, false);
|
||||
multiplier = proj.get_lod_multiplier();
|
||||
CHECK(multiplier == doctest::Approx(3 * sqrt3));
|
||||
|
||||
proj.set_orthogonal(15, 20, 10, 12, 5, 15);
|
||||
multiplier = proj.get_lod_multiplier();
|
||||
CHECK(multiplier == doctest::Approx(5));
|
||||
|
||||
proj.set_orthogonal(-5, 15, -8, 10, 1.5, 10);
|
||||
multiplier = proj.get_lod_multiplier();
|
||||
CHECK(multiplier == doctest::Approx(20));
|
||||
|
||||
proj.set_frustum(1.0, 4.0 / 3.0, Vector2(0.5, -0.25), 0.5, 50, false);
|
||||
multiplier = proj.get_lod_multiplier();
|
||||
CHECK(multiplier == doctest::Approx(8.0 / 3.0));
|
||||
|
||||
proj.set_frustum(2.0, 1.2, Vector2(-0.1, 0.8), 1, 10, true);
|
||||
multiplier = proj.get_lod_multiplier();
|
||||
CHECK(multiplier == doctest::Approx(2));
|
||||
}
|
||||
|
||||
TEST_CASE("[Projection] Pixels per meter") {
|
||||
constexpr real_t sqrt3 = 1.7320508;
|
||||
Projection proj;
|
||||
int ppm;
|
||||
|
||||
proj.set_perspective(60, 1, 1, 40, false);
|
||||
ppm = proj.get_pixels_per_meter(1024);
|
||||
CHECK(ppm == int(1536.0f / sqrt3));
|
||||
|
||||
proj.set_perspective(120, 1.5, 0.5, 20, false);
|
||||
ppm = proj.get_pixels_per_meter(1200);
|
||||
CHECK(ppm == int(800.0f / sqrt3));
|
||||
|
||||
proj.set_orthogonal(15, 20, 10, 12, 5, 15);
|
||||
ppm = proj.get_pixels_per_meter(500);
|
||||
CHECK(ppm == 100);
|
||||
|
||||
proj.set_orthogonal(-5, 15, -8, 10, 1.5, 10);
|
||||
ppm = proj.get_pixels_per_meter(640);
|
||||
CHECK(ppm == 32);
|
||||
|
||||
proj.set_frustum(1.0, 4.0 / 3.0, Vector2(0.5, -0.25), 0.5, 50, false);
|
||||
ppm = proj.get_pixels_per_meter(2048);
|
||||
CHECK(ppm == 1536);
|
||||
|
||||
proj.set_frustum(2.0, 1.2, Vector2(-0.1, 0.8), 1, 10, true);
|
||||
ppm = proj.get_pixels_per_meter(800);
|
||||
CHECK(ppm == 400);
|
||||
}
|
||||
} //namespace TestProjection
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_QUATERNION_H
|
||||
#define TEST_QUATERNION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
|
|
@ -57,7 +56,7 @@ Quaternion quat_euler_yxz_deg(Vector3 angle) {
|
|||
}
|
||||
|
||||
TEST_CASE("[Quaternion] Default Construct") {
|
||||
Quaternion q;
|
||||
constexpr Quaternion q;
|
||||
|
||||
CHECK(q[0] == 0.0);
|
||||
CHECK(q[1] == 0.0);
|
||||
|
|
@ -67,7 +66,7 @@ TEST_CASE("[Quaternion] Default Construct") {
|
|||
|
||||
TEST_CASE("[Quaternion] Construct x,y,z,w") {
|
||||
// Values are taken from actual use in another project & are valid (except roundoff error).
|
||||
Quaternion q(0.2391, 0.099, 0.3696, 0.8924);
|
||||
constexpr Quaternion q(0.2391, 0.099, 0.3696, 0.8924);
|
||||
|
||||
CHECK(q[0] == doctest::Approx(0.2391));
|
||||
CHECK(q[1] == doctest::Approx(0.099));
|
||||
|
|
@ -108,7 +107,7 @@ TEST_CASE("[Quaternion] Construct AxisAngle 3") {
|
|||
|
||||
TEST_CASE("[Quaternion] Construct AxisAngle 4") {
|
||||
// More complex & hard to visualize, so test w/ data from online calculator.
|
||||
Vector3 axis(1.0, 2.0, 0.5);
|
||||
constexpr Vector3 axis(1.0, 2.0, 0.5);
|
||||
Quaternion q(axis.normalized(), Math::deg_to_rad(35.0));
|
||||
|
||||
CHECK(q[0] == doctest::Approx(0.131239));
|
||||
|
|
@ -118,7 +117,7 @@ TEST_CASE("[Quaternion] Construct AxisAngle 4") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Quaternion] Construct from Quaternion") {
|
||||
Vector3 axis(1.0, 2.0, 0.5);
|
||||
constexpr Vector3 axis(1.0, 2.0, 0.5);
|
||||
Quaternion q_src(axis.normalized(), Math::deg_to_rad(35.0));
|
||||
Quaternion q(q_src);
|
||||
|
||||
|
|
@ -199,17 +198,17 @@ TEST_CASE("[Quaternion] Construct Basis Euler") {
|
|||
|
||||
TEST_CASE("[Quaternion] Construct Basis Axes") {
|
||||
// Arbitrary Euler angles.
|
||||
Vector3 euler_yxz(Math::deg_to_rad(31.41), Math::deg_to_rad(-49.16), Math::deg_to_rad(12.34));
|
||||
const Vector3 euler_yxz(Math::deg_to_rad(31.41), Math::deg_to_rad(-49.16), Math::deg_to_rad(12.34));
|
||||
// Basis vectors from online calculation of rotation matrix.
|
||||
Vector3 i_unit(0.5545787, 0.1823950, 0.8118957);
|
||||
Vector3 j_unit(-0.5249245, 0.8337420, 0.1712555);
|
||||
Vector3 k_unit(-0.6456754, -0.5211586, 0.5581192);
|
||||
constexpr Vector3 i_unit(0.5545787, 0.1823950, 0.8118957);
|
||||
constexpr Vector3 j_unit(-0.5249245, 0.8337420, 0.1712555);
|
||||
constexpr Vector3 k_unit(-0.6456754, -0.5211586, 0.5581192);
|
||||
// Quaternion from online calculation.
|
||||
Quaternion q_calc(0.2016913, -0.4245716, 0.206033, 0.8582598);
|
||||
constexpr Quaternion q_calc(0.2016913, -0.4245716, 0.206033, 0.8582598);
|
||||
// Quaternion from local calculation.
|
||||
Quaternion q_local = quat_euler_yxz_deg(Vector3(31.41, -49.16, 12.34));
|
||||
const Quaternion q_local = quat_euler_yxz_deg(Vector3(31.41, -49.16, 12.34));
|
||||
// Quaternion from Euler angles constructor.
|
||||
Quaternion q_euler = Quaternion::from_euler(euler_yxz);
|
||||
const Quaternion q_euler = Quaternion::from_euler(euler_yxz);
|
||||
CHECK(q_calc.is_equal_approx(q_local));
|
||||
CHECK(q_local.is_equal_approx(q_euler));
|
||||
|
||||
|
|
@ -287,10 +286,10 @@ TEST_CASE("[Quaternion] Get Euler Orders") {
|
|||
|
||||
TEST_CASE("[Quaternion] Product (book)") {
|
||||
// Example from "Quaternions and Rotation Sequences" by Jack Kuipers, p. 108.
|
||||
Quaternion p(1.0, -2.0, 1.0, 3.0);
|
||||
Quaternion q(-1.0, 2.0, 3.0, 2.0);
|
||||
constexpr Quaternion p(1.0, -2.0, 1.0, 3.0);
|
||||
constexpr Quaternion q(-1.0, 2.0, 3.0, 2.0);
|
||||
|
||||
Quaternion pq = p * q;
|
||||
constexpr Quaternion pq = p * q;
|
||||
CHECK(pq[0] == doctest::Approx(-9.0));
|
||||
CHECK(pq[1] == doctest::Approx(-2.0));
|
||||
CHECK(pq[2] == doctest::Approx(11.0));
|
||||
|
|
@ -383,13 +382,13 @@ TEST_CASE("[Quaternion] xform unit vectors") {
|
|||
|
||||
TEST_CASE("[Quaternion] xform vector") {
|
||||
// Arbitrary quaternion rotates an arbitrary vector.
|
||||
Vector3 euler_yzx(Math::deg_to_rad(31.41), Math::deg_to_rad(-49.16), Math::deg_to_rad(12.34));
|
||||
Basis basis_axes = Basis::from_euler(euler_yzx);
|
||||
Quaternion q(basis_axes);
|
||||
const Vector3 euler_yzx(Math::deg_to_rad(31.41), Math::deg_to_rad(-49.16), Math::deg_to_rad(12.34));
|
||||
const Basis basis_axes = Basis::from_euler(euler_yzx);
|
||||
const Quaternion q(basis_axes);
|
||||
|
||||
Vector3 v_arb(3.0, 4.0, 5.0);
|
||||
Vector3 v_rot = q.xform(v_arb);
|
||||
Vector3 v_compare = basis_axes.xform(v_arb);
|
||||
constexpr Vector3 v_arb(3.0, 4.0, 5.0);
|
||||
const Vector3 v_rot = q.xform(v_arb);
|
||||
const Vector3 v_compare = basis_axes.xform(v_arb);
|
||||
|
||||
CHECK(v_rot.length_squared() == doctest::Approx(v_arb.length_squared()));
|
||||
CHECK(v_rot.is_equal_approx(v_compare));
|
||||
|
|
@ -397,11 +396,11 @@ TEST_CASE("[Quaternion] xform vector") {
|
|||
|
||||
// Test vector xform for a single combination of Quaternion and Vector.
|
||||
void test_quat_vec_rotate(Vector3 euler_yzx, Vector3 v_in) {
|
||||
Basis basis_axes = Basis::from_euler(euler_yzx);
|
||||
Quaternion q(basis_axes);
|
||||
const Basis basis_axes = Basis::from_euler(euler_yzx);
|
||||
const Quaternion q(basis_axes);
|
||||
|
||||
Vector3 v_rot = q.xform(v_in);
|
||||
Vector3 v_compare = basis_axes.xform(v_in);
|
||||
const Vector3 v_rot = q.xform(v_in);
|
||||
const Vector3 v_compare = basis_axes.xform(v_in);
|
||||
|
||||
CHECK(v_rot.length_squared() == doctest::Approx(v_in.length_squared()));
|
||||
CHECK(v_rot.is_equal_approx(v_compare));
|
||||
|
|
@ -411,22 +410,22 @@ TEST_CASE("[Stress][Quaternion] Many vector xforms") {
|
|||
// Many arbitrary quaternions rotate many arbitrary vectors.
|
||||
// For each trial, check that rotation by Quaternion yields same result as
|
||||
// rotation by Basis.
|
||||
const int STEPS = 100; // Number of test steps in each dimension
|
||||
const double delta = 2.0 * Math_PI / STEPS; // Angle increment per step
|
||||
const double delta_vec = 20.0 / STEPS; // Vector increment per step
|
||||
constexpr int STEPS = 100; // Number of test steps in each dimension
|
||||
constexpr double delta = 2.0 * Math::PI / STEPS; // Angle increment per step
|
||||
constexpr double delta_vec = 20.0 / STEPS; // Vector increment per step
|
||||
Vector3 vec_arb(1.0, 1.0, 1.0);
|
||||
double x_angle = -Math_PI;
|
||||
double y_angle = -Math_PI;
|
||||
double z_angle = -Math_PI;
|
||||
double x_angle = -Math::PI;
|
||||
double y_angle = -Math::PI;
|
||||
double z_angle = -Math::PI;
|
||||
for (double i = 0; i < STEPS; ++i) {
|
||||
vec_arb[0] = -10.0 + i * delta_vec;
|
||||
x_angle = i * delta - Math_PI;
|
||||
x_angle = i * delta - Math::PI;
|
||||
for (double j = 0; j < STEPS; ++j) {
|
||||
vec_arb[1] = -10.0 + j * delta_vec;
|
||||
y_angle = j * delta - Math_PI;
|
||||
y_angle = j * delta - Math::PI;
|
||||
for (double k = 0; k < STEPS; ++k) {
|
||||
vec_arb[2] = -10.0 + k * delta_vec;
|
||||
z_angle = k * delta - Math_PI;
|
||||
z_angle = k * delta - Math::PI;
|
||||
Vector3 euler_yzx(x_angle, y_angle, z_angle);
|
||||
test_quat_vec_rotate(euler_yzx, vec_arb);
|
||||
}
|
||||
|
|
@ -435,7 +434,7 @@ TEST_CASE("[Stress][Quaternion] Many vector xforms") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Quaternion] Finite number checks") {
|
||||
const real_t x = NAN;
|
||||
constexpr real_t x = Math::NaN;
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Quaternion(0, 1, 2, 3).is_finite(),
|
||||
|
|
@ -492,5 +491,3 @@ TEST_CASE("[Quaternion] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestQuaternion
|
||||
|
||||
#endif // TEST_QUATERNION_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_RANDOM_NUMBER_GENERATOR_H
|
||||
#define TEST_RANDOM_NUMBER_GENERATOR_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/random_number_generator.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -271,5 +270,3 @@ TEST_CASE_MAY_FAIL("[RandomNumberGenerator] randi_range bias check") {
|
|||
}
|
||||
}
|
||||
} // namespace TestRandomNumberGenerator
|
||||
|
||||
#endif // TEST_RANDOM_NUMBER_GENERATOR_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_RECT2_H
|
||||
#define TEST_RECT2_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/rect2.h"
|
||||
#include "core/math/rect2i.h"
|
||||
|
|
@ -38,15 +37,15 @@
|
|||
|
||||
namespace TestRect2 {
|
||||
TEST_CASE("[Rect2] Constructor methods") {
|
||||
const Rect2 rect = Rect2(0, 100, 1280, 720);
|
||||
const Rect2 rect_vector = Rect2(Vector2(0, 100), Vector2(1280, 720));
|
||||
const Rect2 rect_copy_rect = Rect2(rect);
|
||||
constexpr Rect2 rect = Rect2(0, 100, 1280, 720);
|
||||
constexpr Rect2 rect_vector = Rect2(Vector2(0, 100), Vector2(1280, 720));
|
||||
constexpr Rect2 rect_copy_rect = Rect2(rect);
|
||||
const Rect2 rect_copy_recti = Rect2(Rect2i(0, 100, 1280, 720));
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
rect == rect_vector,
|
||||
"Rect2s created with the same dimensions but by different methods should be equal.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
rect == rect_copy_rect,
|
||||
"Rect2s created with the same dimensions but by different methods should be equal.");
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -62,7 +61,7 @@ TEST_CASE("[Rect2] String conversion") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Rect2] Basic getters") {
|
||||
const Rect2 rect = Rect2(0, 100, 1280, 720);
|
||||
constexpr Rect2 rect = Rect2(0, 100, 1280, 720);
|
||||
CHECK_MESSAGE(
|
||||
rect.get_position().is_equal_approx(Vector2(0, 100)),
|
||||
"get_position() should return the expected value.");
|
||||
|
|
@ -181,7 +180,7 @@ TEST_CASE("[Rect2] Expanding") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Rect2] Get support") {
|
||||
const Rect2 rect = Rect2(Vector2(-1.5, 2), Vector2(4, 5));
|
||||
constexpr Rect2 rect = Rect2(Vector2(-1.5, 2), Vector2(4, 5));
|
||||
CHECK_MESSAGE(
|
||||
rect.get_support(Vector2(1, 0)) == Vector2(2.5, 2),
|
||||
"get_support() should return the expected value.");
|
||||
|
|
@ -324,8 +323,8 @@ TEST_CASE("[Rect2] Merging") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Rect2] Finite number checks") {
|
||||
const Vector2 x(0, 1);
|
||||
const Vector2 infinite(NAN, NAN);
|
||||
constexpr Vector2 x(0, 1);
|
||||
constexpr Vector2 infinite(Math::NaN, Math::NaN);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Rect2(x, x).is_finite(),
|
||||
|
|
@ -344,5 +343,3 @@ TEST_CASE("[Rect2] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestRect2
|
||||
|
||||
#endif // TEST_RECT2_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_RECT2I_H
|
||||
#define TEST_RECT2I_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/rect2.h"
|
||||
#include "core/math/rect2i.h"
|
||||
|
|
@ -38,15 +37,15 @@
|
|||
|
||||
namespace TestRect2i {
|
||||
TEST_CASE("[Rect2i] Constructor methods") {
|
||||
Rect2i recti = Rect2i(0, 100, 1280, 720);
|
||||
Rect2i recti_vector = Rect2i(Vector2i(0, 100), Vector2i(1280, 720));
|
||||
Rect2i recti_copy_recti = Rect2i(recti);
|
||||
Rect2i recti_copy_rect = Rect2i(Rect2(0, 100, 1280, 720));
|
||||
constexpr Rect2i recti = Rect2i(0, 100, 1280, 720);
|
||||
constexpr Rect2i recti_vector = Rect2i(Vector2i(0, 100), Vector2i(1280, 720));
|
||||
constexpr Rect2i recti_copy_recti = Rect2i(recti);
|
||||
const Rect2i recti_copy_rect = Rect2i(Rect2(0, 100, 1280, 720));
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
recti == recti_vector,
|
||||
"Rect2is created with the same dimensions but by different methods should be equal.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
recti == recti_copy_recti,
|
||||
"Rect2is created with the same dimensions but by different methods should be equal.");
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -62,7 +61,7 @@ TEST_CASE("[Rect2i] String conversion") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Rect2i] Basic getters") {
|
||||
const Rect2i rect = Rect2i(0, 100, 1280, 720);
|
||||
constexpr Rect2i rect = Rect2i(0, 100, 1280, 720);
|
||||
CHECK_MESSAGE(
|
||||
rect.get_position() == Vector2i(0, 100),
|
||||
"get_position() should return the expected value.");
|
||||
|
|
@ -307,5 +306,3 @@ TEST_CASE("[Rect2i] Merging") {
|
|||
"merge() with non-enclosed Rect2i should return the expected result.");
|
||||
}
|
||||
} // namespace TestRect2i
|
||||
|
||||
#endif // TEST_RECT2I_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_TRANSFORM_2D_H
|
||||
#define TEST_TRANSFORM_2D_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/transform_2d.h"
|
||||
|
||||
|
|
@ -57,8 +56,8 @@ TEST_CASE("[Transform2D] Copy constructor") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform2D] Constructor from angle and position") {
|
||||
constexpr float ROTATION = Math_PI / 4;
|
||||
const Vector2 TRANSLATION = Vector2(20, -20);
|
||||
constexpr float ROTATION = Math::PI / 4;
|
||||
constexpr Vector2 TRANSLATION = Vector2(20, -20);
|
||||
|
||||
const Transform2D test = Transform2D(ROTATION, TRANSLATION);
|
||||
const Transform2D expected = Transform2D().rotated(ROTATION).translated(TRANSLATION);
|
||||
|
|
@ -66,10 +65,10 @@ TEST_CASE("[Transform2D] Constructor from angle and position") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform2D] Constructor from angle, scale, skew and position") {
|
||||
constexpr float ROTATION = Math_PI / 2;
|
||||
const Vector2 SCALE = Vector2(2, 0.5);
|
||||
constexpr float SKEW = Math_PI / 4;
|
||||
const Vector2 TRANSLATION = Vector2(30, 0);
|
||||
constexpr float ROTATION = Math::PI / 2;
|
||||
constexpr Vector2 SCALE = Vector2(2, 0.5);
|
||||
constexpr float SKEW = Math::PI / 4;
|
||||
constexpr Vector2 TRANSLATION = Vector2(30, 0);
|
||||
|
||||
const Transform2D test = Transform2D(ROTATION, SCALE, SKEW, TRANSLATION);
|
||||
Transform2D expected = Transform2D().scaled(SCALE).rotated(ROTATION).translated(TRANSLATION);
|
||||
|
|
@ -79,26 +78,26 @@ TEST_CASE("[Transform2D] Constructor from angle, scale, skew and position") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform2D] Constructor from raw values") {
|
||||
const Transform2D test = Transform2D(1, 2, 3, 4, 5, 6);
|
||||
const Transform2D expected = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||
CHECK(test == expected);
|
||||
constexpr Transform2D test = Transform2D(1, 2, 3, 4, 5, 6);
|
||||
constexpr Transform2D expected = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||
static_assert(test == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[Transform2D] xform") {
|
||||
const Vector2 v = Vector2(2, 3);
|
||||
const Transform2D T = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||
const Vector2 expected = Vector2(1 * 2 + 3 * 3 + 5 * 1, 2 * 2 + 4 * 3 + 6 * 1);
|
||||
constexpr Vector2 v = Vector2(2, 3);
|
||||
constexpr Transform2D T = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||
constexpr Vector2 expected = Vector2(1 * 2 + 3 * 3 + 5 * 1, 2 * 2 + 4 * 3 + 6 * 1);
|
||||
CHECK(T.xform(v) == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("[Transform2D] Basis xform") {
|
||||
const Vector2 v = Vector2(2, 2);
|
||||
const Transform2D T1 = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(0, 0));
|
||||
constexpr Vector2 v = Vector2(2, 2);
|
||||
constexpr Transform2D T1 = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(0, 0));
|
||||
|
||||
// Both versions should be the same when the origin is (0,0).
|
||||
CHECK(T1.basis_xform(v) == T1.xform(v));
|
||||
|
||||
const Transform2D T2 = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||
constexpr Transform2D T2 = Transform2D(Vector2(1, 2), Vector2(3, 4), Vector2(5, 6));
|
||||
|
||||
// Each version should be different when the origin is not (0,0).
|
||||
CHECK_FALSE(T2.basis_xform(v) == T2.xform(v));
|
||||
|
|
@ -130,7 +129,7 @@ TEST_CASE("[Transform2D] Orthonormalized") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform2D] translation") {
|
||||
const Vector2 offset = Vector2(1, 2);
|
||||
constexpr Vector2 offset = Vector2(1, 2);
|
||||
|
||||
// Both versions should give the same result applied to identity.
|
||||
CHECK(identity().translated(offset) == identity().translated_local(offset));
|
||||
|
|
@ -143,7 +142,7 @@ TEST_CASE("[Transform2D] translation") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform2D] scaling") {
|
||||
const Vector2 scaling = Vector2(1, 2);
|
||||
constexpr Vector2 scaling = Vector2(1, 2);
|
||||
|
||||
// Both versions should give the same result applied to identity.
|
||||
CHECK(identity().scaled(scaling) == identity().scaled_local(scaling));
|
||||
|
|
@ -182,8 +181,8 @@ TEST_CASE("[Transform2D] Interpolation") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform2D] Finite number checks") {
|
||||
const Vector2 x = Vector2(0, 1);
|
||||
const Vector2 infinite = Vector2(NAN, NAN);
|
||||
constexpr Vector2 x = Vector2(0, 1);
|
||||
constexpr Vector2 infinite = Vector2(Math::NaN, Math::NaN);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Transform2D(x, x, x).is_finite(),
|
||||
|
|
@ -240,10 +239,8 @@ TEST_CASE("[Transform2D] Is conformal checks") {
|
|||
"Transform2D with non-uniform scale should not be conformal.");
|
||||
|
||||
CHECK_FALSE_MESSAGE(
|
||||
Transform2D(Vector2(Math_SQRT12, Math_SQRT12), Vector2(0, 1), Vector2()).is_conformal(),
|
||||
Transform2D(Vector2(Math::SQRT12, Math::SQRT12), Vector2(0, 1), Vector2()).is_conformal(),
|
||||
"Transform2D with the X axis skewed 45 degrees should not be conformal.");
|
||||
}
|
||||
|
||||
} // namespace TestTransform2D
|
||||
|
||||
#endif // TEST_TRANSFORM_2D_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_TRANSFORM_3D_H
|
||||
#define TEST_TRANSFORM_3D_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/transform_3d.h"
|
||||
|
||||
|
|
@ -46,7 +45,7 @@ Transform3D identity() {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform3D] translation") {
|
||||
Vector3 offset = Vector3(1, 2, 3);
|
||||
constexpr Vector3 offset = Vector3(1, 2, 3);
|
||||
|
||||
// Both versions should give the same result applied to identity.
|
||||
CHECK(identity().translated(offset) == identity().translated_local(offset));
|
||||
|
|
@ -59,7 +58,7 @@ TEST_CASE("[Transform3D] translation") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform3D] scaling") {
|
||||
Vector3 scaling = Vector3(1, 2, 3);
|
||||
constexpr Vector3 scaling = Vector3(1, 2, 3);
|
||||
|
||||
// Both versions should give the same result applied to identity.
|
||||
CHECK(identity().scaled(scaling) == identity().scaled_local(scaling));
|
||||
|
|
@ -72,8 +71,8 @@ TEST_CASE("[Transform3D] scaling") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform3D] rotation") {
|
||||
Vector3 axis = Vector3(1, 2, 3).normalized();
|
||||
real_t phi = 1.0;
|
||||
const Vector3 axis = Vector3(1, 2, 3).normalized();
|
||||
constexpr real_t phi = 1.0;
|
||||
|
||||
// Both versions should give the same result applied to identity.
|
||||
CHECK(identity().rotated(axis, phi) == identity().rotated_local(axis, phi));
|
||||
|
|
@ -86,10 +85,10 @@ TEST_CASE("[Transform3D] rotation") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Transform3D] Finite number checks") {
|
||||
const Vector3 y(0, 1, 2);
|
||||
const Vector3 infinite_vec(NAN, NAN, NAN);
|
||||
const Basis x(y, y, y);
|
||||
const Basis infinite_basis(infinite_vec, infinite_vec, infinite_vec);
|
||||
constexpr Vector3 y(0, 1, 2);
|
||||
constexpr Vector3 infinite_vec(Math::NaN, Math::NaN, Math::NaN);
|
||||
constexpr Basis x(y, y, y);
|
||||
constexpr Basis infinite_basis(infinite_vec, infinite_vec, infinite_vec);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Transform3D(x, y).is_finite(),
|
||||
|
|
@ -118,7 +117,7 @@ TEST_CASE("[Transform3D] Rotate around global origin") {
|
|||
expected.basis[0] = Vector3(-1, 0, 0);
|
||||
expected.basis[2] = Vector3(0, 0, -1);
|
||||
|
||||
const Transform3D rotated_transform = transform.rotated(Vector3(0, 1, 0), Math_PI);
|
||||
const Transform3D rotated_transform = transform.rotated(Vector3(0, 1, 0), Math::PI);
|
||||
CHECK_MESSAGE(rotated_transform.is_equal_approx(expected), "The rotated transform should have a new orientation and basis.");
|
||||
}
|
||||
|
||||
|
|
@ -133,9 +132,7 @@ TEST_CASE("[Transform3D] Rotate in-place (local rotation)") {
|
|||
expected.basis[0] = Vector3(-1, 0, 0);
|
||||
expected.basis[2] = Vector3(0, 0, -1);
|
||||
|
||||
const Transform3D rotated_transform = Transform3D(transform.rotated_local(Vector3(0, 1, 0), Math_PI));
|
||||
const Transform3D rotated_transform = Transform3D(transform.rotated_local(Vector3(0, 1, 0), Math::PI));
|
||||
CHECK_MESSAGE(rotated_transform.is_equal_approx(expected), "The rotated transform should have a new orientation but still be based on the same origin.");
|
||||
}
|
||||
} // namespace TestTransform3D
|
||||
|
||||
#endif // TEST_TRANSFORM_3D_H
|
||||
|
|
|
|||
82
engine/tests/core/math/test_triangle_mesh.h
Normal file
82
engine/tests/core/math/test_triangle_mesh.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/**************************************************************************/
|
||||
/* test_triangle_mesh.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/math/triangle_mesh.h"
|
||||
#include "scene/resources/3d/primitive_meshes.h"
|
||||
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
namespace TestTriangleMesh {
|
||||
|
||||
TEST_CASE("[SceneTree][TriangleMesh] BVH creation and intersection") {
|
||||
Ref<BoxMesh> box_mesh;
|
||||
box_mesh.instantiate();
|
||||
|
||||
const Vector<Face3> faces = box_mesh->get_faces();
|
||||
|
||||
Ref<TriangleMesh> triangle_mesh;
|
||||
triangle_mesh.instantiate();
|
||||
CHECK(triangle_mesh->create_from_faces(Variant(faces)));
|
||||
|
||||
const Vector3 begin = Vector3(0.0, 2.0, 0.0);
|
||||
const Vector3 end = Vector3(0.0, -2.0, 0.0);
|
||||
|
||||
{
|
||||
Vector3 point;
|
||||
Vector3 normal;
|
||||
int32_t *surf_index = nullptr;
|
||||
int32_t face_index = -1;
|
||||
const bool has_result = triangle_mesh->intersect_segment(begin, end, point, normal, surf_index, &face_index);
|
||||
CHECK(has_result);
|
||||
CHECK(point.is_equal_approx(Vector3(0.0, 0.5, 0.0)));
|
||||
CHECK(normal.is_equal_approx(Vector3(0.0, 1.0, 0.0)));
|
||||
CHECK(surf_index == nullptr);
|
||||
REQUIRE(face_index != -1);
|
||||
CHECK(face_index == 8);
|
||||
}
|
||||
|
||||
{
|
||||
Vector3 dir = begin.direction_to(end);
|
||||
Vector3 point;
|
||||
Vector3 normal;
|
||||
int32_t *surf_index = nullptr;
|
||||
int32_t face_index = -1;
|
||||
const bool has_result = triangle_mesh->intersect_ray(begin, dir, point, normal, surf_index, &face_index);
|
||||
CHECK(has_result);
|
||||
CHECK(point.is_equal_approx(Vector3(0.0, 0.5, 0.0)));
|
||||
CHECK(normal.is_equal_approx(Vector3(0.0, 1.0, 0.0)));
|
||||
CHECK(surf_index == nullptr);
|
||||
REQUIRE(face_index != -1);
|
||||
CHECK(face_index == 8);
|
||||
}
|
||||
}
|
||||
} // namespace TestTriangleMesh
|
||||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR2_H
|
||||
#define TEST_VECTOR2_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/vector2.h"
|
||||
#include "core/math/vector2i.h"
|
||||
|
|
@ -38,27 +37,27 @@
|
|||
namespace TestVector2 {
|
||||
|
||||
TEST_CASE("[Vector2] Constructor methods") {
|
||||
const Vector2 vector_empty = Vector2();
|
||||
const Vector2 vector_zero = Vector2(0.0, 0.0);
|
||||
CHECK_MESSAGE(
|
||||
constexpr Vector2 vector_empty = Vector2();
|
||||
constexpr Vector2 vector_zero = Vector2(0.0, 0.0);
|
||||
static_assert(
|
||||
vector_empty == vector_zero,
|
||||
"Vector2 Constructor with no inputs should return a zero Vector2.");
|
||||
}
|
||||
|
||||
TEST_CASE("[Vector2] Angle methods") {
|
||||
const Vector2 vector_x = Vector2(1, 0);
|
||||
const Vector2 vector_y = Vector2(0, 1);
|
||||
constexpr Vector2 vector_x = Vector2(1, 0);
|
||||
constexpr Vector2 vector_y = Vector2(0, 1);
|
||||
CHECK_MESSAGE(
|
||||
vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math_TAU / 4),
|
||||
vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math::TAU / 4),
|
||||
"Vector2 angle_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_y.angle_to(vector_x) == doctest::Approx((real_t)-Math_TAU / 4),
|
||||
vector_y.angle_to(vector_x) == doctest::Approx((real_t)-Math::TAU / 4),
|
||||
"Vector2 angle_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_x.angle_to_point(vector_y) == doctest::Approx((real_t)Math_TAU * 3 / 8),
|
||||
vector_x.angle_to_point(vector_y) == doctest::Approx((real_t)Math::TAU * 3 / 8),
|
||||
"Vector2 angle_to_point should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_y.angle_to_point(vector_x) == doctest::Approx((real_t)-Math_TAU / 8),
|
||||
vector_y.angle_to_point(vector_x) == doctest::Approx((real_t)-Math::TAU / 8),
|
||||
"Vector2 angle_to_point should work as expected.");
|
||||
}
|
||||
|
||||
|
|
@ -80,8 +79,8 @@ TEST_CASE("[Vector2] Axis methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Interpolation methods") {
|
||||
const Vector2 vector1 = Vector2(1, 2);
|
||||
const Vector2 vector2 = Vector2(4, 5);
|
||||
constexpr Vector2 vector1 = Vector2(1, 2);
|
||||
constexpr Vector2 vector2 = Vector2(4, 5);
|
||||
CHECK_MESSAGE(
|
||||
vector1.lerp(vector2, 0.5) == Vector2(2.5, 3.5),
|
||||
"Vector2 lerp should work as expected.");
|
||||
|
|
@ -95,7 +94,7 @@ TEST_CASE("[Vector2] Interpolation methods") {
|
|||
vector1.normalized().slerp(vector2.normalized(), 1.0 / 3.0).is_equal_approx(Vector2(0.508990883827209473, 0.860771894454956055)),
|
||||
"Vector2 slerp should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
Vector2(5, 0).slerp(Vector2(0, 5), 0.5).is_equal_approx(Vector2(5, 5) * Math_SQRT12),
|
||||
Vector2(5, 0).slerp(Vector2(0, 5), 0.5).is_equal_approx(Vector2(5, 5) * Math::SQRT12),
|
||||
"Vector2 slerp with non-normalized values should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
Vector2(1, 1).slerp(Vector2(2, 2), 0.5).is_equal_approx(Vector2(1.5, 1.5)),
|
||||
|
|
@ -130,13 +129,13 @@ TEST_CASE("[Vector2] Interpolation methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Length methods") {
|
||||
const Vector2 vector1 = Vector2(10, 10);
|
||||
const Vector2 vector2 = Vector2(20, 30);
|
||||
constexpr Vector2 vector1 = Vector2(10, 10);
|
||||
constexpr Vector2 vector2 = Vector2(20, 30);
|
||||
CHECK_MESSAGE(
|
||||
vector1.length_squared() == 200,
|
||||
"Vector2 length_squared should work as expected and return exact result.");
|
||||
CHECK_MESSAGE(
|
||||
vector1.length() == doctest::Approx(10 * (real_t)Math_SQRT2),
|
||||
vector1.length() == doctest::Approx(10 * (real_t)Math::SQRT2),
|
||||
"Vector2 length should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector2.length_squared() == 1300,
|
||||
|
|
@ -153,12 +152,12 @@ TEST_CASE("[Vector2] Length methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Limiting methods") {
|
||||
const Vector2 vector = Vector2(10, 10);
|
||||
constexpr Vector2 vector = Vector2(10, 10);
|
||||
CHECK_MESSAGE(
|
||||
vector.limit_length().is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)),
|
||||
vector.limit_length().is_equal_approx(Vector2(Math::SQRT12, Math::SQRT12)),
|
||||
"Vector2 limit_length should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.limit_length(5).is_equal_approx(5 * Vector2(Math_SQRT12, Math_SQRT12)),
|
||||
vector.limit_length(5).is_equal_approx(5 * Vector2(Math::SQRT12, Math::SQRT12)),
|
||||
"Vector2 limit_length should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -180,7 +179,7 @@ TEST_CASE("[Vector2] Normalization methods") {
|
|||
Vector2(1, 0).normalized() == Vector2(1, 0),
|
||||
"Vector2 normalized should return the same vector for a normalized vector.");
|
||||
CHECK_MESSAGE(
|
||||
Vector2(1, 1).normalized().is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)),
|
||||
Vector2(1, 1).normalized().is_equal_approx(Vector2(Math::SQRT12, Math::SQRT12)),
|
||||
"Vector2 normalized should work as expected.");
|
||||
|
||||
Vector2 vector = Vector2(3.2, -5.4);
|
||||
|
|
@ -194,70 +193,70 @@ TEST_CASE("[Vector2] Normalization methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Operators") {
|
||||
const Vector2 decimal1 = Vector2(2.3, 4.9);
|
||||
const Vector2 decimal2 = Vector2(1.2, 3.4);
|
||||
const Vector2 power1 = Vector2(0.75, 1.5);
|
||||
const Vector2 power2 = Vector2(0.5, 0.125);
|
||||
const Vector2 int1 = Vector2(4, 5);
|
||||
const Vector2 int2 = Vector2(1, 2);
|
||||
constexpr Vector2 decimal1 = Vector2(2.3, 4.9);
|
||||
constexpr Vector2 decimal2 = Vector2(1.2, 3.4);
|
||||
constexpr Vector2 power1 = Vector2(0.75, 1.5);
|
||||
constexpr Vector2 power2 = Vector2(0.5, 0.125);
|
||||
constexpr Vector2 int1 = Vector2(4, 5);
|
||||
constexpr Vector2 int2 = Vector2(1, 2);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 + decimal2).is_equal_approx(Vector2(3.5, 8.3)),
|
||||
"Vector2 addition should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 + power2) == Vector2(1.25, 1.625),
|
||||
"Vector2 addition with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 + int2) == Vector2(5, 7),
|
||||
"Vector2 addition with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 - decimal2).is_equal_approx(Vector2(1.1, 1.5)),
|
||||
"Vector2 subtraction should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 - power2) == Vector2(0.25, 1.375),
|
||||
"Vector2 subtraction with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 - int2) == Vector2(3, 3),
|
||||
"Vector2 subtraction with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 * decimal2).is_equal_approx(Vector2(2.76, 16.66)),
|
||||
"Vector2 multiplication should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 * power2) == Vector2(0.375, 0.1875),
|
||||
"Vector2 multiplication with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 * int2) == Vector2(4, 10),
|
||||
"Vector2 multiplication with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 / decimal2).is_equal_approx(Vector2(1.91666666666666666, 1.44117647058823529)),
|
||||
"Vector2 division should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 / power2) == Vector2(1.5, 12.0),
|
||||
"Vector2 division with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 / int2) == Vector2(4, 2.5),
|
||||
"Vector2 division with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 * 2).is_equal_approx(Vector2(4.6, 9.8)),
|
||||
"Vector2 multiplication should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 * 2) == Vector2(1.5, 3),
|
||||
"Vector2 multiplication with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 * 2) == Vector2(8, 10),
|
||||
"Vector2 multiplication with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 / 2).is_equal_approx(Vector2(1.15, 2.45)),
|
||||
"Vector2 division should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 / 2) == Vector2(0.375, 0.75),
|
||||
"Vector2 division with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 / 2) == Vector2(2, 2.5),
|
||||
"Vector2 division with integers should give exact results.");
|
||||
|
||||
|
|
@ -282,17 +281,17 @@ TEST_CASE("[Vector2] Operators") {
|
|||
"Vector2 cast to String should work as expected.");
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
CHECK_MESSAGE(
|
||||
((String)Vector2(Math_PI, Math_TAU)) == "(3.14159265358979, 6.28318530717959)",
|
||||
((String)Vector2(Math::PI, Math::TAU)) == "(3.14159265358979, 6.28318530717959)",
|
||||
"Vector2 cast to String should print the correct amount of digits for real_t = double.");
|
||||
#else
|
||||
CHECK_MESSAGE(
|
||||
((String)Vector2(Math_PI, Math_TAU)) == "(3.141593, 6.283185)",
|
||||
((String)Vector2(Math::PI, Math::TAU)) == "(3.141593, 6.283185)",
|
||||
"Vector2 cast to String should print the correct amount of digits for real_t = float.");
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
}
|
||||
|
||||
TEST_CASE("[Vector2] Other methods") {
|
||||
const Vector2 vector = Vector2(1.2, 3.4);
|
||||
constexpr Vector2 vector = Vector2(1.2, 3.4);
|
||||
CHECK_MESSAGE(
|
||||
vector.aspect() == doctest::Approx((real_t)1.2 / (real_t)3.4),
|
||||
"Vector2 aspect should work as expected.");
|
||||
|
|
@ -301,7 +300,7 @@ TEST_CASE("[Vector2] Other methods") {
|
|||
vector.direction_to(Vector2()).is_equal_approx(-vector.normalized()),
|
||||
"Vector2 direction_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
Vector2(1, 1).direction_to(Vector2(2, 2)).is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)),
|
||||
Vector2(1, 1).direction_to(Vector2(2, 2)).is_equal_approx(Vector2(Math::SQRT12, Math::SQRT12)),
|
||||
"Vector2 direction_to should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -318,16 +317,16 @@ TEST_CASE("[Vector2] Other methods") {
|
|||
"Vector2 posmodv should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Math_TAU).is_equal_approx(Vector2(1.2, 3.4)),
|
||||
vector.rotated(Math::TAU).is_equal_approx(Vector2(1.2, 3.4)),
|
||||
"Vector2 rotated should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Math_TAU / 4).is_equal_approx(Vector2(-3.4, 1.2)),
|
||||
vector.rotated(Math::TAU / 4).is_equal_approx(Vector2(-3.4, 1.2)),
|
||||
"Vector2 rotated should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Math_TAU / 3).is_equal_approx(Vector2(-3.544486372867091398996, -0.660769515458673623883)),
|
||||
vector.rotated(Math::TAU / 3).is_equal_approx(Vector2(-3.544486372867091398996, -0.660769515458673623883)),
|
||||
"Vector2 rotated should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Math_TAU / 2).is_equal_approx(vector.rotated(Math_TAU / -2)),
|
||||
vector.rotated(Math::TAU / 2).is_equal_approx(vector.rotated(Math::TAU / -2)),
|
||||
"Vector2 rotated should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -350,10 +349,10 @@ TEST_CASE("[Vector2] Other methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Plane methods") {
|
||||
const Vector2 vector = Vector2(1.2, 3.4);
|
||||
const Vector2 vector_y = Vector2(0, 1);
|
||||
const Vector2 vector_normal = Vector2(0.95879811270838721622267, 0.2840883296913739899919);
|
||||
const real_t p_d = 99.1;
|
||||
constexpr Vector2 vector = Vector2(1.2, 3.4);
|
||||
constexpr Vector2 vector_y = Vector2(0, 1);
|
||||
constexpr Vector2 vector_normal = Vector2(0.95879811270838721622267, 0.2840883296913739899919);
|
||||
constexpr real_t p_d = 99.1;
|
||||
CHECK_MESSAGE(
|
||||
vector.bounce(vector_y) == Vector2(1.2, -3.4),
|
||||
"Vector2 bounce on a plane with normal of the Y axis should.");
|
||||
|
|
@ -383,7 +382,7 @@ TEST_CASE("[Vector2] Plane methods") {
|
|||
"Vector2 slide with normal should return expected value.");
|
||||
// There's probably a better way to test these ones?
|
||||
#ifdef MATH_CHECKS
|
||||
const Vector2 vector_non_normal = Vector2(5.4, 1.6);
|
||||
constexpr Vector2 vector_non_normal = Vector2(5.4, 1.6);
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_MESSAGE(
|
||||
vector.bounce(vector_non_normal).is_equal_approx(Vector2()),
|
||||
|
|
@ -399,8 +398,8 @@ TEST_CASE("[Vector2] Plane methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Rounding methods") {
|
||||
const Vector2 vector1 = Vector2(1.2, 5.6);
|
||||
const Vector2 vector2 = Vector2(1.2, -5.6);
|
||||
constexpr Vector2 vector1 = Vector2(1.2, 5.6);
|
||||
constexpr Vector2 vector2 = Vector2(1.2, -5.6);
|
||||
CHECK_MESSAGE(
|
||||
vector1.abs() == vector1,
|
||||
"Vector2 abs should work as expected.");
|
||||
|
|
@ -438,10 +437,10 @@ TEST_CASE("[Vector2] Rounding methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Linear algebra methods") {
|
||||
const Vector2 vector_x = Vector2(1, 0);
|
||||
const Vector2 vector_y = Vector2(0, 1);
|
||||
const Vector2 a = Vector2(3.5, 8.5);
|
||||
const Vector2 b = Vector2(5.2, 4.6);
|
||||
constexpr Vector2 vector_x = Vector2(1, 0);
|
||||
constexpr Vector2 vector_y = Vector2(0, 1);
|
||||
constexpr Vector2 a = Vector2(3.5, 8.5);
|
||||
constexpr Vector2 b = Vector2(5.2, 4.6);
|
||||
CHECK_MESSAGE(
|
||||
vector_x.cross(vector_y) == 1,
|
||||
"Vector2 cross product of X and Y should give 1.");
|
||||
|
|
@ -473,7 +472,7 @@ TEST_CASE("[Vector2] Linear algebra methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2] Finite number checks") {
|
||||
const double infinite[] = { NAN, INFINITY, -INFINITY };
|
||||
constexpr double infinite[] = { Math::NaN, Math::INF, -Math::INF };
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Vector2(0, 1).is_finite(),
|
||||
|
|
@ -498,5 +497,3 @@ TEST_CASE("[Vector2] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestVector2
|
||||
|
||||
#endif // TEST_VECTOR2_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR2I_H
|
||||
#define TEST_VECTOR2I_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/vector2.h"
|
||||
#include "core/math/vector2i.h"
|
||||
|
|
@ -38,9 +37,9 @@
|
|||
namespace TestVector2i {
|
||||
|
||||
TEST_CASE("[Vector2i] Constructor methods") {
|
||||
const Vector2i vector_empty = Vector2i();
|
||||
const Vector2i vector_zero = Vector2i(0, 0);
|
||||
CHECK_MESSAGE(
|
||||
constexpr Vector2i vector_empty = Vector2i();
|
||||
constexpr Vector2i vector_zero = Vector2i(0, 0);
|
||||
static_assert(
|
||||
vector_empty == vector_zero,
|
||||
"Vector2i Constructor with no inputs should return a zero Vector2i.");
|
||||
}
|
||||
|
|
@ -63,7 +62,7 @@ TEST_CASE("[Vector2i] Axis methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2i] Clamp method") {
|
||||
const Vector2i vector = Vector2i(10, 10);
|
||||
constexpr Vector2i vector = Vector2i(10, 10);
|
||||
CHECK_MESSAGE(
|
||||
Vector2i(-5, 15).clamp(Vector2i(), vector) == Vector2i(0, 10),
|
||||
"Vector2i clamp should work as expected.");
|
||||
|
|
@ -73,13 +72,13 @@ TEST_CASE("[Vector2i] Clamp method") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2i] Length methods") {
|
||||
const Vector2i vector1 = Vector2i(10, 10);
|
||||
const Vector2i vector2 = Vector2i(20, 30);
|
||||
constexpr Vector2i vector1 = Vector2i(10, 10);
|
||||
constexpr Vector2i vector2 = Vector2i(20, 30);
|
||||
CHECK_MESSAGE(
|
||||
vector1.length_squared() == 200,
|
||||
"Vector2i length_squared should work as expected and return exact result.");
|
||||
CHECK_MESSAGE(
|
||||
vector1.length() == doctest::Approx(10 * Math_SQRT2),
|
||||
vector1.length() == doctest::Approx(10 * Math::SQRT2),
|
||||
"Vector2i length should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector2.length_squared() == 1300,
|
||||
|
|
@ -96,26 +95,26 @@ TEST_CASE("[Vector2i] Length methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2i] Operators") {
|
||||
const Vector2i vector1 = Vector2i(5, 9);
|
||||
const Vector2i vector2 = Vector2i(2, 3);
|
||||
constexpr Vector2i vector1 = Vector2i(5, 9);
|
||||
constexpr Vector2i vector2 = Vector2i(2, 3);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 + vector2) == Vector2i(7, 12),
|
||||
"Vector2i addition with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 - vector2) == Vector2i(3, 6),
|
||||
"Vector2i subtraction with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 * vector2) == Vector2i(10, 27),
|
||||
"Vector2i multiplication with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 / vector2) == Vector2i(2, 3),
|
||||
"Vector2i division with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 * 2) == Vector2i(10, 18),
|
||||
"Vector2i multiplication with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 / 2) == Vector2i(2, 4),
|
||||
"Vector2i division with integers should give exact results.");
|
||||
|
||||
|
|
@ -131,7 +130,7 @@ TEST_CASE("[Vector2i] Operators") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2i] Other methods") {
|
||||
const Vector2i vector = Vector2i(1, 3);
|
||||
constexpr Vector2i vector = Vector2i(1, 3);
|
||||
CHECK_MESSAGE(
|
||||
vector.aspect() == doctest::Approx((real_t)1.0 / (real_t)3.0),
|
||||
"Vector2i aspect should work as expected.");
|
||||
|
|
@ -150,8 +149,8 @@ TEST_CASE("[Vector2i] Other methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector2i] Abs and sign methods") {
|
||||
const Vector2i vector1 = Vector2i(1, 3);
|
||||
const Vector2i vector2 = Vector2i(1, -3);
|
||||
constexpr Vector2i vector1 = Vector2i(1, 3);
|
||||
constexpr Vector2i vector2 = Vector2i(1, -3);
|
||||
CHECK_MESSAGE(
|
||||
vector1.abs() == vector1,
|
||||
"Vector2i abs should work as expected.");
|
||||
|
|
@ -167,5 +166,3 @@ TEST_CASE("[Vector2i] Abs and sign methods") {
|
|||
"Vector2i sign should work as expected.");
|
||||
}
|
||||
} // namespace TestVector2i
|
||||
|
||||
#endif // TEST_VECTOR2I_H
|
||||
|
|
|
|||
|
|
@ -28,50 +28,46 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR3_H
|
||||
#define TEST_VECTOR3_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/vector3.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
#define Math_SQRT13 0.57735026918962576450914878050196
|
||||
#define Math_SQRT3 1.7320508075688772935274463415059
|
||||
|
||||
namespace TestVector3 {
|
||||
|
||||
TEST_CASE("[Vector3] Constructor methods") {
|
||||
const Vector3 vector_empty = Vector3();
|
||||
const Vector3 vector_zero = Vector3(0.0, 0.0, 0.0);
|
||||
CHECK_MESSAGE(
|
||||
constexpr Vector3 vector_empty = Vector3();
|
||||
constexpr Vector3 vector_zero = Vector3(0.0, 0.0, 0.0);
|
||||
static_assert(
|
||||
vector_empty == vector_zero,
|
||||
"Vector3 Constructor with no inputs should return a zero Vector3.");
|
||||
}
|
||||
|
||||
TEST_CASE("[Vector3] Angle methods") {
|
||||
const Vector3 vector_x = Vector3(1, 0, 0);
|
||||
const Vector3 vector_y = Vector3(0, 1, 0);
|
||||
const Vector3 vector_yz = Vector3(0, 1, 1);
|
||||
constexpr Vector3 vector_x = Vector3(1, 0, 0);
|
||||
constexpr Vector3 vector_y = Vector3(0, 1, 0);
|
||||
constexpr Vector3 vector_yz = Vector3(0, 1, 1);
|
||||
CHECK_MESSAGE(
|
||||
vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math_TAU / 4),
|
||||
vector_x.angle_to(vector_y) == doctest::Approx((real_t)Math::TAU / 4),
|
||||
"Vector3 angle_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_x.angle_to(vector_yz) == doctest::Approx((real_t)Math_TAU / 4),
|
||||
vector_x.angle_to(vector_yz) == doctest::Approx((real_t)Math::TAU / 4),
|
||||
"Vector3 angle_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_yz.angle_to(vector_x) == doctest::Approx((real_t)Math_TAU / 4),
|
||||
vector_yz.angle_to(vector_x) == doctest::Approx((real_t)Math::TAU / 4),
|
||||
"Vector3 angle_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_y.angle_to(vector_yz) == doctest::Approx((real_t)Math_TAU / 8),
|
||||
vector_y.angle_to(vector_yz) == doctest::Approx((real_t)Math::TAU / 8),
|
||||
"Vector3 angle_to should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
vector_x.signed_angle_to(vector_y, vector_y) == doctest::Approx((real_t)Math_TAU / 4),
|
||||
vector_x.signed_angle_to(vector_y, vector_y) == doctest::Approx((real_t)Math::TAU / 4),
|
||||
"Vector3 signed_angle_to edge case should be positive.");
|
||||
CHECK_MESSAGE(
|
||||
vector_x.signed_angle_to(vector_yz, vector_y) == doctest::Approx((real_t)Math_TAU / -4),
|
||||
vector_x.signed_angle_to(vector_yz, vector_y) == doctest::Approx((real_t)Math::TAU / -4),
|
||||
"Vector3 signed_angle_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector_yz.signed_angle_to(vector_x, vector_y) == doctest::Approx((real_t)Math_TAU / 4),
|
||||
vector_yz.signed_angle_to(vector_x, vector_y) == doctest::Approx((real_t)Math::TAU / 4),
|
||||
"Vector3 signed_angle_to should work as expected.");
|
||||
}
|
||||
|
||||
|
|
@ -97,8 +93,8 @@ TEST_CASE("[Vector3] Axis methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Interpolation methods") {
|
||||
const Vector3 vector1 = Vector3(1, 2, 3);
|
||||
const Vector3 vector2 = Vector3(4, 5, 6);
|
||||
constexpr Vector3 vector1 = Vector3(1, 2, 3);
|
||||
constexpr Vector3 vector2 = Vector3(4, 5, 6);
|
||||
CHECK_MESSAGE(
|
||||
vector1.lerp(vector2, 0.5) == Vector3(2.5, 3.5, 4.5),
|
||||
"Vector3 lerp should work as expected.");
|
||||
|
|
@ -147,13 +143,13 @@ TEST_CASE("[Vector3] Interpolation methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Length methods") {
|
||||
const Vector3 vector1 = Vector3(10, 10, 10);
|
||||
const Vector3 vector2 = Vector3(20, 30, 40);
|
||||
constexpr Vector3 vector1 = Vector3(10, 10, 10);
|
||||
constexpr Vector3 vector2 = Vector3(20, 30, 40);
|
||||
CHECK_MESSAGE(
|
||||
vector1.length_squared() == 300,
|
||||
"Vector3 length_squared should work as expected and return exact result.");
|
||||
CHECK_MESSAGE(
|
||||
vector1.length() == doctest::Approx(10 * (real_t)Math_SQRT3),
|
||||
vector1.length() == doctest::Approx(10 * (real_t)Math::SQRT3),
|
||||
"Vector3 length should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector2.length_squared() == 2900,
|
||||
|
|
@ -170,12 +166,12 @@ TEST_CASE("[Vector3] Length methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Limiting methods") {
|
||||
const Vector3 vector = Vector3(10, 10, 10);
|
||||
constexpr Vector3 vector = Vector3(10, 10, 10);
|
||||
CHECK_MESSAGE(
|
||||
vector.limit_length().is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)),
|
||||
vector.limit_length().is_equal_approx(Vector3(Math::SQRT13, Math::SQRT13, Math::SQRT13)),
|
||||
"Vector3 limit_length should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.limit_length(5).is_equal_approx(5 * Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)),
|
||||
vector.limit_length(5).is_equal_approx(5 * Vector3(Math::SQRT13, Math::SQRT13, Math::SQRT13)),
|
||||
"Vector3 limit_length should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -197,10 +193,10 @@ TEST_CASE("[Vector3] Normalization methods") {
|
|||
Vector3(1, 0, 0).normalized() == Vector3(1, 0, 0),
|
||||
"Vector3 normalized should return the same vector for a normalized vector.");
|
||||
CHECK_MESSAGE(
|
||||
Vector3(1, 1, 0).normalized().is_equal_approx(Vector3(Math_SQRT12, Math_SQRT12, 0)),
|
||||
Vector3(1, 1, 0).normalized().is_equal_approx(Vector3(Math::SQRT12, Math::SQRT12, 0)),
|
||||
"Vector3 normalized should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
Vector3(1, 1, 1).normalized().is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)),
|
||||
Vector3(1, 1, 1).normalized().is_equal_approx(Vector3(Math::SQRT13, Math::SQRT13, Math::SQRT13)),
|
||||
"Vector3 normalized should work as expected.");
|
||||
|
||||
Vector3 vector = Vector3(3.2, -5.4, 6);
|
||||
|
|
@ -214,70 +210,70 @@ TEST_CASE("[Vector3] Normalization methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Operators") {
|
||||
const Vector3 decimal1 = Vector3(2.3, 4.9, 7.8);
|
||||
const Vector3 decimal2 = Vector3(1.2, 3.4, 5.6);
|
||||
const Vector3 power1 = Vector3(0.75, 1.5, 0.625);
|
||||
const Vector3 power2 = Vector3(0.5, 0.125, 0.25);
|
||||
const Vector3 int1 = Vector3(4, 5, 9);
|
||||
const Vector3 int2 = Vector3(1, 2, 3);
|
||||
constexpr Vector3 decimal1 = Vector3(2.3, 4.9, 7.8);
|
||||
constexpr Vector3 decimal2 = Vector3(1.2, 3.4, 5.6);
|
||||
constexpr Vector3 power1 = Vector3(0.75, 1.5, 0.625);
|
||||
constexpr Vector3 power2 = Vector3(0.5, 0.125, 0.25);
|
||||
constexpr Vector3 int1 = Vector3(4, 5, 9);
|
||||
constexpr Vector3 int2 = Vector3(1, 2, 3);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 + decimal2).is_equal_approx(Vector3(3.5, 8.3, 13.4)),
|
||||
"Vector3 addition should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 + power2) == Vector3(1.25, 1.625, 0.875),
|
||||
"Vector3 addition with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 + int2) == Vector3(5, 7, 12),
|
||||
"Vector3 addition with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 - decimal2).is_equal_approx(Vector3(1.1, 1.5, 2.2)),
|
||||
"Vector3 subtraction should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 - power2) == Vector3(0.25, 1.375, 0.375),
|
||||
"Vector3 subtraction with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 - int2) == Vector3(3, 3, 6),
|
||||
"Vector3 subtraction with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 * decimal2).is_equal_approx(Vector3(2.76, 16.66, 43.68)),
|
||||
"Vector3 multiplication should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 * power2) == Vector3(0.375, 0.1875, 0.15625),
|
||||
"Vector3 multiplication with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 * int2) == Vector3(4, 10, 27),
|
||||
"Vector3 multiplication with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 / decimal2).is_equal_approx(Vector3(1.91666666666666666, 1.44117647058823529, 1.39285714285714286)),
|
||||
"Vector3 division should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 / power2) == Vector3(1.5, 12.0, 2.5),
|
||||
"Vector3 division with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 / int2) == Vector3(4, 2.5, 3),
|
||||
"Vector3 division with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 * 2).is_equal_approx(Vector3(4.6, 9.8, 15.6)),
|
||||
"Vector3 multiplication should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 * 2) == Vector3(1.5, 3, 1.25),
|
||||
"Vector3 multiplication with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 * 2) == Vector3(8, 10, 18),
|
||||
"Vector3 multiplication with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 / 2).is_equal_approx(Vector3(1.15, 2.45, 3.9)),
|
||||
"Vector3 division should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 / 2) == Vector3(0.375, 0.75, 0.3125),
|
||||
"Vector3 division with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 / 2) == Vector3(2, 2.5, 4.5),
|
||||
"Vector3 division with integers should give exact results.");
|
||||
|
||||
|
|
@ -302,22 +298,22 @@ TEST_CASE("[Vector3] Operators") {
|
|||
"Vector3 cast to String should work as expected.");
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
CHECK_MESSAGE(
|
||||
((String)Vector3(Math_E, Math_SQRT2, Math_SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888)",
|
||||
((String)Vector3(Math::E, Math::SQRT2, Math::SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888)",
|
||||
"Vector3 cast to String should print the correct amount of digits for real_t = double.");
|
||||
#else
|
||||
CHECK_MESSAGE(
|
||||
((String)Vector3(Math_E, Math_SQRT2, Math_SQRT3)) == "(2.718282, 1.414214, 1.732051)",
|
||||
((String)Vector3(Math::E, Math::SQRT2, Math::SQRT3)) == "(2.718282, 1.414214, 1.732051)",
|
||||
"Vector3 cast to String should print the correct amount of digits for real_t = float.");
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
}
|
||||
|
||||
TEST_CASE("[Vector3] Other methods") {
|
||||
const Vector3 vector = Vector3(1.2, 3.4, 5.6);
|
||||
constexpr Vector3 vector = Vector3(1.2, 3.4, 5.6);
|
||||
CHECK_MESSAGE(
|
||||
vector.direction_to(Vector3()).is_equal_approx(-vector.normalized()),
|
||||
"Vector3 direction_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
Vector3(1, 1, 1).direction_to(Vector3(2, 2, 2)).is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)),
|
||||
Vector3(1, 1, 1).direction_to(Vector3(2, 2, 2)).is_equal_approx(Vector3(Math::SQRT13, Math::SQRT13, Math::SQRT13)),
|
||||
"Vector3 direction_to should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.inverse().is_equal_approx(Vector3(1 / 1.2, 1 / 3.4, 1 / 5.6)),
|
||||
|
|
@ -336,16 +332,16 @@ TEST_CASE("[Vector3] Other methods") {
|
|||
"Vector3 posmodv should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Vector3(0, 1, 0), Math_TAU).is_equal_approx(vector),
|
||||
vector.rotated(Vector3(0, 1, 0), Math::TAU).is_equal_approx(vector),
|
||||
"Vector3 rotated should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Vector3(0, 1, 0), Math_TAU / 4).is_equal_approx(Vector3(5.6, 3.4, -1.2)),
|
||||
vector.rotated(Vector3(0, 1, 0), Math::TAU / 4).is_equal_approx(Vector3(5.6, 3.4, -1.2)),
|
||||
"Vector3 rotated should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Vector3(1, 0, 0), Math_TAU / 3).is_equal_approx(Vector3(1.2, -6.54974226119285642, 0.1444863728670914)),
|
||||
vector.rotated(Vector3(1, 0, 0), Math::TAU / 3).is_equal_approx(Vector3(1.2, -6.54974226119285642, 0.1444863728670914)),
|
||||
"Vector3 rotated should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector.rotated(Vector3(0, 0, 1), Math_TAU / 2).is_equal_approx(vector.rotated(Vector3(0, 0, 1), Math_TAU / -2)),
|
||||
vector.rotated(Vector3(0, 0, 1), Math::TAU / 2).is_equal_approx(vector.rotated(Vector3(0, 0, 1), Math::TAU / -2)),
|
||||
"Vector3 rotated should work as expected.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
|
|
@ -365,9 +361,9 @@ TEST_CASE("[Vector3] Other methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Plane methods") {
|
||||
const Vector3 vector = Vector3(1.2, 3.4, 5.6);
|
||||
const Vector3 vector_y = Vector3(0, 1, 0);
|
||||
const Vector3 vector_normal = Vector3(0.88763458893247992491, 0.26300284116517923701, 0.37806658417494515320);
|
||||
constexpr Vector3 vector = Vector3(1.2, 3.4, 5.6);
|
||||
constexpr Vector3 vector_y = Vector3(0, 1, 0);
|
||||
constexpr Vector3 vector_normal = Vector3(0.88763458893247992491, 0.26300284116517923701, 0.37806658417494515320);
|
||||
CHECK_MESSAGE(
|
||||
vector.bounce(vector_y) == Vector3(1.2, -3.4, 5.6),
|
||||
"Vector3 bounce on a plane with normal of the Y axis should.");
|
||||
|
|
@ -394,7 +390,7 @@ TEST_CASE("[Vector3] Plane methods") {
|
|||
"Vector3 slide with normal should return expected value.");
|
||||
// There's probably a better way to test these ones?
|
||||
#ifdef MATH_CHECKS
|
||||
const Vector3 vector_non_normal = Vector3(5.4, 1.6, 2.3);
|
||||
constexpr Vector3 vector_non_normal = Vector3(5.4, 1.6, 2.3);
|
||||
ERR_PRINT_OFF;
|
||||
CHECK_MESSAGE(
|
||||
vector.bounce(vector_non_normal).is_equal_approx(Vector3()),
|
||||
|
|
@ -410,8 +406,8 @@ TEST_CASE("[Vector3] Plane methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Rounding methods") {
|
||||
const Vector3 vector1 = Vector3(1.2, 3.4, 5.6);
|
||||
const Vector3 vector2 = Vector3(1.2, -3.4, -5.6);
|
||||
constexpr Vector3 vector1 = Vector3(1.2, 3.4, 5.6);
|
||||
constexpr Vector3 vector2 = Vector3(1.2, -3.4, -5.6);
|
||||
CHECK_MESSAGE(
|
||||
vector1.abs() == vector1,
|
||||
"Vector3 abs should work as expected.");
|
||||
|
|
@ -449,11 +445,11 @@ TEST_CASE("[Vector3] Rounding methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Linear algebra methods") {
|
||||
const Vector3 vector_x = Vector3(1, 0, 0);
|
||||
const Vector3 vector_y = Vector3(0, 1, 0);
|
||||
const Vector3 vector_z = Vector3(0, 0, 1);
|
||||
const Vector3 a = Vector3(3.5, 8.5, 2.3);
|
||||
const Vector3 b = Vector3(5.2, 4.6, 7.8);
|
||||
constexpr Vector3 vector_x = Vector3(1, 0, 0);
|
||||
constexpr Vector3 vector_y = Vector3(0, 1, 0);
|
||||
constexpr Vector3 vector_z = Vector3(0, 0, 1);
|
||||
constexpr Vector3 a = Vector3(3.5, 8.5, 2.3);
|
||||
constexpr Vector3 b = Vector3(5.2, 4.6, 7.8);
|
||||
CHECK_MESSAGE(
|
||||
vector_x.cross(vector_y) == vector_z,
|
||||
"Vector3 cross product of X and Y should give Z.");
|
||||
|
|
@ -491,7 +487,7 @@ TEST_CASE("[Vector3] Linear algebra methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3] Finite number checks") {
|
||||
const double infinite[] = { NAN, INFINITY, -INFINITY };
|
||||
constexpr double infinite[] = { Math::NaN, Math::INF, -Math::INF };
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Vector3(0, 1, 2).is_finite(),
|
||||
|
|
@ -535,5 +531,3 @@ TEST_CASE("[Vector3] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestVector3
|
||||
|
||||
#endif // TEST_VECTOR3_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR3I_H
|
||||
#define TEST_VECTOR3I_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/vector3i.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -37,9 +36,9 @@
|
|||
namespace TestVector3i {
|
||||
|
||||
TEST_CASE("[Vector3i] Constructor methods") {
|
||||
const Vector3i vector_empty = Vector3i();
|
||||
const Vector3i vector_zero = Vector3i(0, 0, 0);
|
||||
CHECK_MESSAGE(
|
||||
constexpr Vector3i vector_empty = Vector3i();
|
||||
constexpr Vector3i vector_zero = Vector3i(0, 0, 0);
|
||||
static_assert(
|
||||
vector_empty == vector_zero,
|
||||
"Vector3i Constructor with no inputs should return a zero Vector3i.");
|
||||
}
|
||||
|
|
@ -66,7 +65,7 @@ TEST_CASE("[Vector3i] Axis methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3i] Clamp method") {
|
||||
const Vector3i vector = Vector3i(10, 10, 10);
|
||||
constexpr Vector3i vector = Vector3i(10, 10, 10);
|
||||
CHECK_MESSAGE(
|
||||
Vector3i(-5, 5, 15).clamp(Vector3i(), vector) == Vector3i(0, 5, 10),
|
||||
"Vector3i clamp should work as expected.");
|
||||
|
|
@ -76,13 +75,13 @@ TEST_CASE("[Vector3i] Clamp method") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3i] Length methods") {
|
||||
const Vector3i vector1 = Vector3i(10, 10, 10);
|
||||
const Vector3i vector2 = Vector3i(20, 30, 40);
|
||||
constexpr Vector3i vector1 = Vector3i(10, 10, 10);
|
||||
constexpr Vector3i vector2 = Vector3i(20, 30, 40);
|
||||
CHECK_MESSAGE(
|
||||
vector1.length_squared() == 300,
|
||||
"Vector3i length_squared should work as expected and return exact result.");
|
||||
CHECK_MESSAGE(
|
||||
vector1.length() == doctest::Approx(10 * Math_SQRT3),
|
||||
vector1.length() == doctest::Approx(10 * Math::SQRT3),
|
||||
"Vector3i length should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
vector2.length_squared() == 2900,
|
||||
|
|
@ -99,26 +98,26 @@ TEST_CASE("[Vector3i] Length methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3i] Operators") {
|
||||
const Vector3i vector1 = Vector3i(4, 5, 9);
|
||||
const Vector3i vector2 = Vector3i(1, 2, 3);
|
||||
constexpr Vector3i vector1 = Vector3i(4, 5, 9);
|
||||
constexpr Vector3i vector2 = Vector3i(1, 2, 3);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 + vector2) == Vector3i(5, 7, 12),
|
||||
"Vector3i addition with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 - vector2) == Vector3i(3, 3, 6),
|
||||
"Vector3i subtraction with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 * vector2) == Vector3i(4, 10, 27),
|
||||
"Vector3i multiplication with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 / vector2) == Vector3i(4, 2, 3),
|
||||
"Vector3i division with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 * 2) == Vector3i(8, 10, 18),
|
||||
"Vector3i multiplication with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 / 2) == Vector3i(2, 2, 4),
|
||||
"Vector3i division with integers should give exact results.");
|
||||
|
||||
|
|
@ -134,7 +133,7 @@ TEST_CASE("[Vector3i] Operators") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3i] Other methods") {
|
||||
const Vector3i vector = Vector3i(1, 3, -7);
|
||||
constexpr Vector3i vector = Vector3i(1, 3, -7);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
vector.min(Vector3i(3, 2, 5)) == Vector3i(1, 2, -7),
|
||||
|
|
@ -149,8 +148,8 @@ TEST_CASE("[Vector3i] Other methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3i] Abs and sign methods") {
|
||||
const Vector3i vector1 = Vector3i(1, 3, 5);
|
||||
const Vector3i vector2 = Vector3i(1, -3, -5);
|
||||
constexpr Vector3i vector1 = Vector3i(1, 3, 5);
|
||||
constexpr Vector3i vector2 = Vector3i(1, -3, -5);
|
||||
CHECK_MESSAGE(
|
||||
vector1.abs() == vector1,
|
||||
"Vector3i abs should work as expected.");
|
||||
|
|
@ -166,5 +165,3 @@ TEST_CASE("[Vector3i] Abs and sign methods") {
|
|||
"Vector3i sign should work as expected.");
|
||||
}
|
||||
} // namespace TestVector3i
|
||||
|
||||
#endif // TEST_VECTOR3I_H
|
||||
|
|
|
|||
|
|
@ -28,20 +28,17 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR4_H
|
||||
#define TEST_VECTOR4_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/vector4.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
#define Math_SQRT3 1.7320508075688772935274463415059
|
||||
|
||||
namespace TestVector4 {
|
||||
|
||||
TEST_CASE("[Vector4] Constructor methods") {
|
||||
const Vector4 vector_empty = Vector4();
|
||||
const Vector4 vector_zero = Vector4(0.0, 0.0, 0.0, 0.0);
|
||||
CHECK_MESSAGE(
|
||||
constexpr Vector4 vector_empty = Vector4();
|
||||
constexpr Vector4 vector_zero = Vector4(0.0, 0.0, 0.0, 0.0);
|
||||
static_assert(
|
||||
vector_empty == vector_zero,
|
||||
"Vector4 Constructor with no inputs should return a zero Vector4.");
|
||||
}
|
||||
|
|
@ -68,8 +65,8 @@ TEST_CASE("[Vector4] Axis methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Interpolation methods") {
|
||||
const Vector4 vector1 = Vector4(1, 2, 3, 4);
|
||||
const Vector4 vector2 = Vector4(4, 5, 6, 7);
|
||||
constexpr Vector4 vector1 = Vector4(1, 2, 3, 4);
|
||||
constexpr Vector4 vector2 = Vector4(4, 5, 6, 7);
|
||||
CHECK_MESSAGE(
|
||||
vector1.lerp(vector2, 0.5) == Vector4(2.5, 3.5, 4.5, 5.5),
|
||||
"Vector4 lerp should work as expected.");
|
||||
|
|
@ -85,8 +82,8 @@ TEST_CASE("[Vector4] Interpolation methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Length methods") {
|
||||
const Vector4 vector1 = Vector4(10, 10, 10, 10);
|
||||
const Vector4 vector2 = Vector4(20, 30, 40, 50);
|
||||
constexpr Vector4 vector1 = Vector4(10, 10, 10, 10);
|
||||
constexpr Vector4 vector2 = Vector4(20, 30, 40, 50);
|
||||
CHECK_MESSAGE(
|
||||
vector1.length_squared() == 400,
|
||||
"Vector4 length_squared should work as expected and return exact result.");
|
||||
|
|
@ -108,7 +105,7 @@ TEST_CASE("[Vector4] Length methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Limiting methods") {
|
||||
const Vector4 vector = Vector4(10, 10, 10, 10);
|
||||
constexpr Vector4 vector = Vector4(10, 10, 10, 10);
|
||||
CHECK_MESSAGE(
|
||||
Vector4(-5, 5, 15, -15).clamp(Vector4(), vector) == Vector4(0, 5, 10, 0),
|
||||
"Vector4 clamp should work as expected.");
|
||||
|
|
@ -128,7 +125,7 @@ TEST_CASE("[Vector4] Normalization methods") {
|
|||
Vector4(1, 0, 0, 0).normalized() == Vector4(1, 0, 0, 0),
|
||||
"Vector4 normalized should return the same vector for a normalized vector.");
|
||||
CHECK_MESSAGE(
|
||||
Vector4(1, 1, 0, 0).normalized().is_equal_approx(Vector4(Math_SQRT12, Math_SQRT12, 0, 0)),
|
||||
Vector4(1, 1, 0, 0).normalized().is_equal_approx(Vector4(Math::SQRT12, Math::SQRT12, 0, 0)),
|
||||
"Vector4 normalized should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
Vector4(1, 1, 1, 1).normalized().is_equal_approx(Vector4(0.5, 0.5, 0.5, 0.5)),
|
||||
|
|
@ -136,73 +133,73 @@ TEST_CASE("[Vector4] Normalization methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Operators") {
|
||||
const Vector4 decimal1 = Vector4(2.3, 4.9, 7.8, 3.2);
|
||||
const Vector4 decimal2 = Vector4(1.2, 3.4, 5.6, 1.7);
|
||||
const Vector4 power1 = Vector4(0.75, 1.5, 0.625, 0.125);
|
||||
const Vector4 power2 = Vector4(0.5, 0.125, 0.25, 0.75);
|
||||
const Vector4 int1 = Vector4(4, 5, 9, 2);
|
||||
const Vector4 int2 = Vector4(1, 2, 3, 1);
|
||||
constexpr Vector4 decimal1 = Vector4(2.3, 4.9, 7.8, 3.2);
|
||||
constexpr Vector4 decimal2 = Vector4(1.2, 3.4, 5.6, 1.7);
|
||||
constexpr Vector4 power1 = Vector4(0.75, 1.5, 0.625, 0.125);
|
||||
constexpr Vector4 power2 = Vector4(0.5, 0.125, 0.25, 0.75);
|
||||
constexpr Vector4 int1 = Vector4(4, 5, 9, 2);
|
||||
constexpr Vector4 int2 = Vector4(1, 2, 3, 1);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
-decimal1 == Vector4(-2.3, -4.9, -7.8, -3.2),
|
||||
"Vector4 change of sign should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 + decimal2).is_equal_approx(Vector4(3.5, 8.3, 13.4, 4.9)),
|
||||
"Vector4 addition should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 + power2) == Vector4(1.25, 1.625, 0.875, 0.875),
|
||||
"Vector4 addition with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 + int2) == Vector4(5, 7, 12, 3),
|
||||
"Vector4 addition with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 - decimal2).is_equal_approx(Vector4(1.1, 1.5, 2.2, 1.5)),
|
||||
"Vector4 subtraction should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 - power2) == Vector4(0.25, 1.375, 0.375, -0.625),
|
||||
"Vector4 subtraction with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 - int2) == Vector4(3, 3, 6, 1),
|
||||
"Vector4 subtraction with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 * decimal2).is_equal_approx(Vector4(2.76, 16.66, 43.68, 5.44)),
|
||||
"Vector4 multiplication should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 * power2) == Vector4(0.375, 0.1875, 0.15625, 0.09375),
|
||||
"Vector4 multiplication with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 * int2) == Vector4(4, 10, 27, 2),
|
||||
"Vector4 multiplication with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 / decimal2).is_equal_approx(Vector4(1.91666666666666666, 1.44117647058823529, 1.39285714285714286, 1.88235294118)),
|
||||
"Vector4 division should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 / power2) == Vector4(1.5, 12.0, 2.5, 1.0 / 6.0),
|
||||
"Vector4 division with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 / int2) == Vector4(4, 2.5, 3, 2),
|
||||
"Vector4 division with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 * 2).is_equal_approx(Vector4(4.6, 9.8, 15.6, 6.4)),
|
||||
"Vector4 multiplication should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 * 2) == Vector4(1.5, 3, 1.25, 0.25),
|
||||
"Vector4 multiplication with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 * 2) == Vector4(8, 10, 18, 4),
|
||||
"Vector4 multiplication with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
(decimal1 / 2).is_equal_approx(Vector4(1.15, 2.45, 3.9, 1.6)),
|
||||
"Vector4 division should behave as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(power1 / 2) == Vector4(0.375, 0.75, 0.3125, 0.0625),
|
||||
"Vector4 division with powers of two should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(int1 / 2) == Vector4(2, 2.5, 4.5, 1),
|
||||
"Vector4 division with integers should give exact results.");
|
||||
|
||||
|
|
@ -217,17 +214,17 @@ TEST_CASE("[Vector4] Operators") {
|
|||
"Vector4 cast to String should work as expected.");
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
CHECK_MESSAGE(
|
||||
((String)Vector4(Math_E, Math_SQRT2, Math_SQRT3, Math_SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888, 1.73205080756888)",
|
||||
((String)Vector4(Math::E, Math::SQRT2, Math::SQRT3, Math::SQRT3)) == "(2.71828182845905, 1.4142135623731, 1.73205080756888, 1.73205080756888)",
|
||||
"Vector4 cast to String should print the correct amount of digits for real_t = double.");
|
||||
#else
|
||||
CHECK_MESSAGE(
|
||||
((String)Vector4(Math_E, Math_SQRT2, Math_SQRT3, Math_SQRT3)) == "(2.718282, 1.414214, 1.732051, 1.732051)",
|
||||
((String)Vector4(Math::E, Math::SQRT2, Math::SQRT3, Math::SQRT3)) == "(2.718282, 1.414214, 1.732051, 1.732051)",
|
||||
"Vector4 cast to String should print the correct amount of digits for real_t = float.");
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
}
|
||||
|
||||
TEST_CASE("[Vector4] Other methods") {
|
||||
const Vector4 vector = Vector4(1.2, 3.4, 5.6, 1.6);
|
||||
constexpr Vector4 vector = Vector4(1.2, 3.4, 5.6, 1.6);
|
||||
CHECK_MESSAGE(
|
||||
vector.direction_to(Vector4()).is_equal_approx(-vector.normalized()),
|
||||
"Vector4 direction_to should work as expected.");
|
||||
|
|
@ -266,8 +263,8 @@ TEST_CASE("[Vector4] Other methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Rounding methods") {
|
||||
const Vector4 vector1 = Vector4(1.2, 3.4, 5.6, 1.6);
|
||||
const Vector4 vector2 = Vector4(1.2, -3.4, -5.6, -1.6);
|
||||
constexpr Vector4 vector1 = Vector4(1.2, 3.4, 5.6, 1.6);
|
||||
constexpr Vector4 vector2 = Vector4(1.2, -3.4, -5.6, -1.6);
|
||||
CHECK_MESSAGE(
|
||||
vector1.abs() == vector1,
|
||||
"Vector4 abs should work as expected.");
|
||||
|
|
@ -304,10 +301,10 @@ TEST_CASE("[Vector4] Rounding methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Linear algebra methods") {
|
||||
const Vector4 vector_x = Vector4(1, 0, 0, 0);
|
||||
const Vector4 vector_y = Vector4(0, 1, 0, 0);
|
||||
const Vector4 vector1 = Vector4(1.7, 2.3, 1, 9.1);
|
||||
const Vector4 vector2 = Vector4(-8.2, -16, 3, 2.4);
|
||||
constexpr Vector4 vector_x = Vector4(1, 0, 0, 0);
|
||||
constexpr Vector4 vector_y = Vector4(0, 1, 0, 0);
|
||||
constexpr Vector4 vector1 = Vector4(1.7, 2.3, 1, 9.1);
|
||||
constexpr Vector4 vector2 = Vector4(-8.2, -16, 3, 2.4);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
vector_x.dot(vector_y) == 0.0,
|
||||
|
|
@ -324,7 +321,7 @@ TEST_CASE("[Vector4] Linear algebra methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4] Finite number checks") {
|
||||
const double infinite[] = { NAN, INFINITY, -INFINITY };
|
||||
constexpr double infinite[] = { Math::NaN, Math::INF, -Math::INF };
|
||||
|
||||
CHECK_MESSAGE(
|
||||
Vector4(0, 1, 2, 3).is_finite(),
|
||||
|
|
@ -401,5 +398,3 @@ TEST_CASE("[Vector4] Finite number checks") {
|
|||
}
|
||||
|
||||
} // namespace TestVector4
|
||||
|
||||
#endif // TEST_VECTOR4_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR4I_H
|
||||
#define TEST_VECTOR4I_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/vector4i.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -37,9 +36,9 @@
|
|||
namespace TestVector4i {
|
||||
|
||||
TEST_CASE("[Vector4i] Constructor methods") {
|
||||
const Vector4i vector_empty = Vector4i();
|
||||
const Vector4i vector_zero = Vector4i(0, 0, 0, 0);
|
||||
CHECK_MESSAGE(
|
||||
constexpr Vector4i vector_empty = Vector4i();
|
||||
constexpr Vector4i vector_zero = Vector4i(0, 0, 0, 0);
|
||||
static_assert(
|
||||
vector_empty == vector_zero,
|
||||
"Vector4i Constructor with no inputs should return a zero Vector4i.");
|
||||
}
|
||||
|
|
@ -66,7 +65,7 @@ TEST_CASE("[Vector4i] Axis methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4i] Clamp method") {
|
||||
const Vector4i vector = Vector4i(10, 10, 10, 10);
|
||||
constexpr Vector4i vector = Vector4i(10, 10, 10, 10);
|
||||
CHECK_MESSAGE(
|
||||
Vector4i(-5, 5, 15, INT_MAX).clamp(Vector4i(), vector) == Vector4i(0, 5, 10, 10),
|
||||
"Vector4i clamp should work as expected.");
|
||||
|
|
@ -76,8 +75,8 @@ TEST_CASE("[Vector4i] Clamp method") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4i] Length methods") {
|
||||
const Vector4i vector1 = Vector4i(10, 10, 10, 10);
|
||||
const Vector4i vector2 = Vector4i(20, 30, 40, 50);
|
||||
constexpr Vector4i vector1 = Vector4i(10, 10, 10, 10);
|
||||
constexpr Vector4i vector2 = Vector4i(20, 30, 40, 50);
|
||||
CHECK_MESSAGE(
|
||||
vector1.length_squared() == 400,
|
||||
"Vector4i length_squared should work as expected and return exact result.");
|
||||
|
|
@ -99,29 +98,29 @@ TEST_CASE("[Vector4i] Length methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4i] Operators") {
|
||||
const Vector4i vector1 = Vector4i(4, 5, 9, 2);
|
||||
const Vector4i vector2 = Vector4i(1, 2, 3, 4);
|
||||
constexpr Vector4i vector1 = Vector4i(4, 5, 9, 2);
|
||||
constexpr Vector4i vector2 = Vector4i(1, 2, 3, 4);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
-vector1 == Vector4i(-4, -5, -9, -2),
|
||||
"Vector4i change of sign should work as expected.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 + vector2) == Vector4i(5, 7, 12, 6),
|
||||
"Vector4i addition with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 - vector2) == Vector4i(3, 3, 6, -2),
|
||||
"Vector4i subtraction with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 * vector2) == Vector4i(4, 10, 27, 8),
|
||||
"Vector4i multiplication with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 / vector2) == Vector4i(4, 2, 3, 0),
|
||||
"Vector4i division with integers should give exact results.");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 * 2) == Vector4i(8, 10, 18, 4),
|
||||
"Vector4i multiplication with integers should give exact results.");
|
||||
CHECK_MESSAGE(
|
||||
static_assert(
|
||||
(vector1 / 2) == Vector4i(2, 2, 4, 1),
|
||||
"Vector4i division with integers should give exact results.");
|
||||
|
||||
|
|
@ -137,7 +136,7 @@ TEST_CASE("[Vector4i] Operators") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector3i] Other methods") {
|
||||
const Vector4i vector = Vector4i(1, 3, -7, 13);
|
||||
constexpr Vector4i vector = Vector4i(1, 3, -7, 13);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
vector.min(Vector4i(3, 2, 5, 8)) == Vector4i(1, 2, -7, 8),
|
||||
|
|
@ -153,8 +152,8 @@ TEST_CASE("[Vector3i] Other methods") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Vector4i] Abs and sign methods") {
|
||||
const Vector4i vector1 = Vector4i(1, 3, 5, 7);
|
||||
const Vector4i vector2 = Vector4i(1, -3, -5, 7);
|
||||
constexpr Vector4i vector1 = Vector4i(1, 3, 5, 7);
|
||||
constexpr Vector4i vector2 = Vector4i(1, -3, -5, 7);
|
||||
CHECK_MESSAGE(
|
||||
vector1.abs() == vector1,
|
||||
"Vector4i abs should work as expected.");
|
||||
|
|
@ -170,5 +169,3 @@ TEST_CASE("[Vector4i] Abs and sign methods") {
|
|||
"Vector4i sign should work as expected.");
|
||||
}
|
||||
} // namespace TestVector4i
|
||||
|
||||
#endif // TEST_VECTOR4I_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_CLASS_DB_H
|
||||
#define TEST_CLASS_DB_H
|
||||
#pragma once
|
||||
|
||||
#include "core/core_bind.h"
|
||||
#include "core/core_constants.h"
|
||||
|
|
@ -415,6 +414,9 @@ void validate_argument(const Context &p_context, const ExposedClass &p_class, co
|
|||
#ifdef DEBUG_METHODS_ENABLED
|
||||
TEST_COND((p_arg.name.is_empty() || p_arg.name.begins_with("_unnamed_arg")),
|
||||
vformat("Unnamed argument in position %d of %s '%s.%s'.", p_arg.position, p_owner_type, p_class.name, p_owner_name));
|
||||
|
||||
TEST_FAIL_COND((p_arg.name != "@varargs@" && !p_arg.name.is_valid_ascii_identifier()),
|
||||
vformat("Invalid argument name '%s' of %s '%s.%s'.", p_arg.name, p_owner_type, p_class.name, p_owner_name));
|
||||
#endif // DEBUG_METHODS_ENABLED
|
||||
|
||||
const ExposedClass *arg_class = p_context.find_exposed_class(p_arg.type);
|
||||
|
|
@ -658,9 +660,8 @@ void add_exposed_classes(Context &r_context) {
|
|||
method.return_type.name = Variant::get_type_name(return_info.type);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = method_info.arguments.begin(); itr != method_info.arguments.end(); ++itr, ++i) {
|
||||
const PropertyInfo &arg_info = *itr;
|
||||
for (int64_t i = 0; i < method_info.arguments.size(); ++i) {
|
||||
const PropertyInfo &arg_info = method_info.arguments[i];
|
||||
|
||||
String orig_arg_name = arg_info.name;
|
||||
|
||||
|
|
@ -732,9 +733,8 @@ void add_exposed_classes(Context &r_context) {
|
|||
TEST_FAIL_COND(!String(signal.name).is_valid_ascii_identifier(),
|
||||
"Signal name is not a valid identifier: '", exposed_class.name, ".", signal.name, "'.");
|
||||
|
||||
int i = 0;
|
||||
for (List<PropertyInfo>::ConstIterator itr = method_info.arguments.begin(); itr != method_info.arguments.end(); ++itr, ++i) {
|
||||
const PropertyInfo &arg_info = *itr;
|
||||
for (int64_t i = 0; i < method_info.arguments.size(); ++i) {
|
||||
const PropertyInfo &arg_info = method_info.arguments[i];
|
||||
|
||||
String orig_arg_name = arg_info.name;
|
||||
|
||||
|
|
@ -900,5 +900,3 @@ TEST_SUITE("[ClassDB]") {
|
|||
}
|
||||
}
|
||||
} // namespace TestClassDB
|
||||
|
||||
#endif // TEST_CLASS_DB_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_METHOD_BIND_H
|
||||
#define TEST_METHOD_BIND_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
|
||||
|
|
@ -56,6 +55,8 @@ public:
|
|||
};
|
||||
|
||||
class ObjectSubclass : public Object {
|
||||
GDSOFTCLASS(ObjectSubclass, Object);
|
||||
|
||||
public:
|
||||
int value = 1;
|
||||
};
|
||||
|
|
@ -171,5 +172,3 @@ TEST_CASE("[MethodBind] check all method binds") {
|
|||
memdelete(mbt);
|
||||
}
|
||||
} // namespace TestMethodBind
|
||||
|
||||
#endif // TEST_METHOD_BIND_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_OBJECT_H
|
||||
#define TEST_OBJECT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/object/object.h"
|
||||
|
|
@ -144,15 +143,6 @@ TEST_CASE("[Object] Core getters") {
|
|||
CHECK_MESSAGE(
|
||||
object.get_save_class() == "Object",
|
||||
"The returned save class should match the expected value.");
|
||||
|
||||
List<String> inheritance_list;
|
||||
object.get_inheritance_list_static(&inheritance_list);
|
||||
CHECK_MESSAGE(
|
||||
inheritance_list.size() == 1,
|
||||
"The inheritance list should consist of Object only");
|
||||
CHECK_MESSAGE(
|
||||
inheritance_list.front()->get() == "Object",
|
||||
"The inheritance list should consist of Object only");
|
||||
}
|
||||
|
||||
TEST_CASE("[Object] Metadata") {
|
||||
|
|
@ -429,8 +419,7 @@ TEST_CASE("[Object] Signals") {
|
|||
}
|
||||
|
||||
SUBCASE("Emitting an existing signal should call the connected method") {
|
||||
Array empty_signal_args;
|
||||
empty_signal_args.push_back(Array());
|
||||
Array empty_signal_args = { {} };
|
||||
|
||||
SIGNAL_WATCH(&object, "my_custom_signal");
|
||||
SIGNAL_CHECK_FALSE("my_custom_signal");
|
||||
|
|
@ -466,72 +455,75 @@ TEST_CASE("[Object] Signals") {
|
|||
}
|
||||
}
|
||||
|
||||
class NotificationObject1 : public Object {
|
||||
GDCLASS(NotificationObject1, Object);
|
||||
class NotificationObjectSuperclass : public Object {
|
||||
GDCLASS(NotificationObjectSuperclass, Object);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case 12345: {
|
||||
order_internal1 = order_global++;
|
||||
} break;
|
||||
}
|
||||
order_superclass = ++order_global;
|
||||
}
|
||||
|
||||
public:
|
||||
static int order_global;
|
||||
int order_internal1 = -1;
|
||||
|
||||
void reset_order() {
|
||||
order_internal1 = -1;
|
||||
order_global = 1;
|
||||
}
|
||||
static inline int order_global = 0;
|
||||
int order_superclass = -1;
|
||||
};
|
||||
|
||||
int NotificationObject1::order_global = 1;
|
||||
|
||||
class NotificationObject2 : public NotificationObject1 {
|
||||
GDCLASS(NotificationObject2, NotificationObject1);
|
||||
class NotificationObjectSubclass : public NotificationObjectSuperclass {
|
||||
GDCLASS(NotificationObjectSubclass, NotificationObjectSuperclass);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case 12345: {
|
||||
order_internal2 = order_global++;
|
||||
} break;
|
||||
}
|
||||
order_subclass = ++order_global;
|
||||
}
|
||||
|
||||
public:
|
||||
int order_internal2 = -1;
|
||||
void reset_order() {
|
||||
NotificationObject1::reset_order();
|
||||
order_internal2 = -1;
|
||||
int order_subclass = -1;
|
||||
};
|
||||
|
||||
class NotificationScriptInstance : public _MockScriptInstance {
|
||||
void notification(int p_notification, bool p_reversed) override {
|
||||
order_script = ++NotificationObjectSuperclass::order_global;
|
||||
}
|
||||
|
||||
public:
|
||||
int order_script = -1;
|
||||
};
|
||||
|
||||
TEST_CASE("[Object] Notification order") { // GH-52325
|
||||
NotificationObject2 *test_notification_object = memnew(NotificationObject2);
|
||||
NotificationObjectSubclass *object = memnew(NotificationObjectSubclass);
|
||||
|
||||
NotificationScriptInstance *script = memnew(NotificationScriptInstance);
|
||||
object->set_script_instance(script);
|
||||
|
||||
SUBCASE("regular order") {
|
||||
test_notification_object->notification(12345, false);
|
||||
NotificationObjectSubclass::order_global = 0;
|
||||
object->order_superclass = -1;
|
||||
object->order_subclass = -1;
|
||||
script->order_script = -1;
|
||||
object->notification(12345, false);
|
||||
|
||||
CHECK_EQ(test_notification_object->order_internal1, 1);
|
||||
CHECK_EQ(test_notification_object->order_internal2, 2);
|
||||
|
||||
test_notification_object->reset_order();
|
||||
CHECK_EQ(object->order_superclass, 1);
|
||||
CHECK_EQ(object->order_subclass, 2);
|
||||
// TODO If an extension is attached, it should come here.
|
||||
CHECK_EQ(script->order_script, 3);
|
||||
CHECK_EQ(NotificationObjectSubclass::order_global, 3);
|
||||
}
|
||||
|
||||
SUBCASE("reverse order") {
|
||||
test_notification_object->notification(12345, true);
|
||||
NotificationObjectSubclass::order_global = 0;
|
||||
object->order_superclass = -1;
|
||||
object->order_subclass = -1;
|
||||
script->order_script = -1;
|
||||
object->notification(12345, true);
|
||||
|
||||
CHECK_EQ(test_notification_object->order_internal1, 2);
|
||||
CHECK_EQ(test_notification_object->order_internal2, 1);
|
||||
|
||||
test_notification_object->reset_order();
|
||||
CHECK_EQ(script->order_script, 1);
|
||||
// TODO If an extension is attached, it should come here.
|
||||
CHECK_EQ(object->order_subclass, 2);
|
||||
CHECK_EQ(object->order_superclass, 3);
|
||||
CHECK_EQ(NotificationObjectSubclass::order_global, 3);
|
||||
}
|
||||
|
||||
memdelete(test_notification_object);
|
||||
memdelete(object);
|
||||
}
|
||||
|
||||
TEST_CASE("[Object] Destruction at the end of the call chain is safe") {
|
||||
|
|
@ -603,5 +595,3 @@ TEST_CASE("[Object] Destruction at the end of the call chain is safe") {
|
|||
}
|
||||
|
||||
} // namespace TestObject
|
||||
|
||||
#endif // TEST_OBJECT_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_UNDO_REDO_H
|
||||
#define TEST_UNDO_REDO_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/undo_redo.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -198,5 +197,3 @@ TEST_CASE("[UndoRedo] Merge Method UndoRedo") {
|
|||
}
|
||||
|
||||
} //namespace TestUndoRedo
|
||||
|
||||
#endif // TEST_UNDO_REDO_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_OS_H
|
||||
#define TEST_OS_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/os.h"
|
||||
|
||||
|
|
@ -202,5 +201,3 @@ TEST_CASE("[OS] Execute") {
|
|||
}
|
||||
|
||||
} // namespace TestOS
|
||||
|
||||
#endif // TEST_OS_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_FUZZY_SEARCH_H
|
||||
#define TEST_FUZZY_SEARCH_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/fuzzy_search.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -79,5 +78,3 @@ TEST_CASE("[FuzzySearch] Test fuzzy search results") {
|
|||
}
|
||||
|
||||
} //namespace TestFuzzySearch
|
||||
|
||||
#endif // TEST_FUZZY_SEARCH_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_NODE_PATH_H
|
||||
#define TEST_NODE_PATH_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/node_path.h"
|
||||
|
||||
|
|
@ -224,5 +223,3 @@ TEST_CASE("[NodePath] Slice") {
|
|||
}
|
||||
|
||||
} // namespace TestNodePath
|
||||
|
||||
#endif // TEST_NODE_PATH_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_STRING_H
|
||||
#define TEST_STRING_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/ustring.h"
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ TEST_CASE("[String] Assign from Latin-1 char string (copycon)") {
|
|||
const String &t1(s);
|
||||
CHECK(u32scmp(t1.get_data(), U"Sheep") == 0);
|
||||
|
||||
String t2 = String("Sheep", 3);
|
||||
String t2 = String::latin1(Span("Sheep", 3));
|
||||
CHECK(u32scmp(t2.get_data(), U"She") == 0);
|
||||
}
|
||||
|
||||
|
|
@ -88,34 +87,38 @@ TEST_CASE("[String] UTF8") {
|
|||
/* how can i embed UTF in here? */
|
||||
static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
|
||||
static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
|
||||
String s = u32str;
|
||||
Error err = s.parse_utf8(s.utf8().get_data());
|
||||
String expected = u32str;
|
||||
String parsed;
|
||||
Error err = parsed.append_utf8(expected.utf8().get_data());
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
CHECK(parsed == u32str);
|
||||
|
||||
err = s.parse_utf8((const char *)u8str);
|
||||
parsed.clear();
|
||||
err = parsed.append_utf8((const char *)u8str);
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
CHECK(parsed == u32str);
|
||||
|
||||
CharString cs = (const char *)u8str;
|
||||
CHECK(String::utf8(cs) == s);
|
||||
CHECK(String::utf8(cs) == parsed);
|
||||
}
|
||||
|
||||
TEST_CASE("[String] UTF16") {
|
||||
/* how can i embed UTF in here? */
|
||||
static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
|
||||
static const char16_t u16str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
|
||||
String s = u32str;
|
||||
Error err = s.parse_utf16(s.utf16().get_data());
|
||||
String expected = u32str;
|
||||
String parsed;
|
||||
Error err = parsed.append_utf16(expected.utf16().get_data());
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
CHECK(parsed == u32str);
|
||||
|
||||
err = s.parse_utf16(u16str);
|
||||
parsed.clear();
|
||||
err = parsed.append_utf16(u16str);
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
CHECK(parsed == u32str);
|
||||
|
||||
Char16String cs = u16str;
|
||||
CHECK(String::utf16(cs) == s);
|
||||
CHECK(String::utf16(cs) == parsed);
|
||||
}
|
||||
|
||||
TEST_CASE("[String] UTF8 with BOM") {
|
||||
|
|
@ -123,7 +126,7 @@ TEST_CASE("[String] UTF8 with BOM") {
|
|||
static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
|
||||
static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
|
||||
String s;
|
||||
Error err = s.parse_utf8((const char *)u8str);
|
||||
Error err = s.append_utf8((const char *)u8str);
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
|
||||
|
|
@ -137,11 +140,12 @@ TEST_CASE("[String] UTF16 with BOM") {
|
|||
static const char16_t u16str[] = { 0xFEFF, 0x0020, 0x0045, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
|
||||
static const char16_t u16str_swap[] = { 0xFFFE, 0x2000, 0x4500, 0x4A30, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 };
|
||||
String s;
|
||||
Error err = s.parse_utf16(u16str);
|
||||
Error err = s.append_utf16(u16str);
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
|
||||
err = s.parse_utf16(u16str_swap);
|
||||
s.clear();
|
||||
err = s.append_utf16(u16str_swap);
|
||||
CHECK(err == OK);
|
||||
CHECK(s == u32str);
|
||||
|
||||
|
|
@ -156,23 +160,23 @@ TEST_CASE("[String] UTF8 with CR") {
|
|||
const String base = U"Hello darkness\r\nMy old friend\nI've come to talk\rWith you again";
|
||||
|
||||
String keep_cr;
|
||||
Error err = keep_cr.parse_utf8(base.utf8().get_data());
|
||||
Error err = keep_cr.append_utf8(base.utf8().get_data());
|
||||
CHECK(err == OK);
|
||||
CHECK(keep_cr == base);
|
||||
|
||||
String no_cr;
|
||||
err = no_cr.parse_utf8(base.utf8().get_data(), -1, true); // Skip CR.
|
||||
err = no_cr.append_utf8(base.utf8().get_data(), -1, true); // Skip CR.
|
||||
CHECK(err == OK);
|
||||
CHECK(no_cr == base.replace("\r", ""));
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Invalid UTF8 (non-standard)") {
|
||||
TEST_CASE("[String] Invalid UTF8 (non shortest form sequence)") {
|
||||
ERR_PRINT_OFF
|
||||
static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 };
|
||||
// + +2 +2 +2 +3 overlong +3 unpaired +2
|
||||
static const char32_t u32str[] = { 0x45, 0x304A, 0x3088, 0x3046, 0x1F3A4, 0x20AC, 0xFFFD, 0 };
|
||||
// Examples from the unicode standard : 3.9 Unicode Encoding Forms - Table 3.8.
|
||||
static const uint8_t u8str[] = { 0xC0, 0xAF, 0xE0, 0x80, 0xBF, 0xF0, 0x81, 0x82, 0x41, 0 };
|
||||
static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0 };
|
||||
String s;
|
||||
Error err = s.parse_utf8((const char *)u8str);
|
||||
Error err = s.append_utf8((const char *)u8str);
|
||||
CHECK(err == ERR_INVALID_DATA);
|
||||
CHECK(s == u32str);
|
||||
|
||||
|
|
@ -181,13 +185,43 @@ TEST_CASE("[String] Invalid UTF8 (non-standard)") {
|
|||
ERR_PRINT_ON
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Invalid UTF8 (unrecoverable)") {
|
||||
TEST_CASE("[String] Invalid UTF8 (ill formed sequences for surrogates)") {
|
||||
ERR_PRINT_OFF
|
||||
static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xC0, 0x80, 0xF0, 0x9F, 0x8E, 0xA4, 0xF0, 0x82, 0x82, 0xAC, 0xED, 0xA0, 0x81, 0 };
|
||||
// + +2 inv +2 inv inv inv +2 +2 ovl NUL +1 +3 overlong +3 unpaired +2
|
||||
static const char32_t u32str[] = { 0x45, 0x304A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x3088, 0x3046, 0xFFFD, 0x1F3A4, 0x20AC, 0xFFFD, 0 };
|
||||
// Examples from the unicode standard : 3.9 Unicode Encoding Forms - Table 3.9.
|
||||
static const uint8_t u8str[] = { 0xED, 0xA0, 0x80, 0xED, 0xBF, 0xBF, 0xED, 0xAF, 0x41, 0 };
|
||||
static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0 };
|
||||
String s;
|
||||
Error err = s.parse_utf8((const char *)u8str);
|
||||
Error err = s.append_utf8((const char *)u8str);
|
||||
CHECK(err == ERR_INVALID_DATA);
|
||||
CHECK(s == u32str);
|
||||
|
||||
CharString cs = (const char *)u8str;
|
||||
CHECK(String::utf8(cs) == s);
|
||||
ERR_PRINT_ON
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Invalid UTF8 (other ill formed sequences)") {
|
||||
ERR_PRINT_OFF
|
||||
// Examples from the unicode standard : 3.9 Unicode Encoding Forms - Table 3.10.
|
||||
static const uint8_t u8str[] = { 0xF4, 0x91, 0x92, 0x93, 0xFF, 0x41, 0x80, 0xBF, 0x42, 0 };
|
||||
static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0xFFFD, 0xFFFD, 0x42, 0 };
|
||||
String s;
|
||||
Error err = s.append_utf8((const char *)u8str);
|
||||
CHECK(err == ERR_INVALID_DATA);
|
||||
CHECK(s == u32str);
|
||||
|
||||
CharString cs = (const char *)u8str;
|
||||
CHECK(String::utf8(cs) == s);
|
||||
ERR_PRINT_ON
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Invalid UTF8 (truncated sequences)") {
|
||||
ERR_PRINT_OFF
|
||||
// Examples from the unicode standard : 3.9 Unicode Encoding Forms - Table 3.11.
|
||||
static const uint8_t u8str[] = { 0xE1, 0x80, 0xE2, 0xF0, 0x91, 0x92, 0xF1, 0xBF, 0x41, 0 };
|
||||
static const char32_t u32str[] = { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x41, 0 };
|
||||
String s;
|
||||
Error err = s.append_utf8((const char *)u8str);
|
||||
CHECK(err == ERR_INVALID_DATA);
|
||||
CHECK(s == u32str);
|
||||
|
||||
|
|
@ -202,7 +236,7 @@ TEST_CASE("[String] Invalid UTF16 (non-standard)") {
|
|||
// + + + + unpaired
|
||||
static const char32_t u32str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 };
|
||||
String s;
|
||||
Error err = s.parse_utf16(u16str);
|
||||
Error err = s.append_utf16(u16str);
|
||||
CHECK(err == ERR_PARSE_ERROR);
|
||||
CHECK(s == u32str);
|
||||
|
||||
|
|
@ -442,6 +476,27 @@ TEST_CASE("[String] Find and replace") {
|
|||
MULTICHECK_STRING_STRING_EQ(s, replacen, "Y", "Y", "HappY BirthdaY, Anna!");
|
||||
}
|
||||
|
||||
TEST_CASE("[String] replace_char") {
|
||||
String s = "Banana";
|
||||
CHECK(s.replace_char('n', 'x') == "Baxaxa");
|
||||
CHECK(s.replace_char('\0', 'x') == "Banana");
|
||||
ERR_PRINT_OFF
|
||||
CHECK(s.replace_char('n', '\0') == "Banana");
|
||||
ERR_PRINT_ON
|
||||
}
|
||||
|
||||
TEST_CASE("[String] replace_chars") {
|
||||
String s = "Banana";
|
||||
CHECK(s.replace_chars(String("Bn"), 'x') == "xaxaxa");
|
||||
CHECK(s.replace_chars("Bn", 'x') == "xaxaxa");
|
||||
CHECK(s.replace_chars(String(), 'x') == "Banana");
|
||||
CHECK(s.replace_chars("", 'x') == "Banana");
|
||||
ERR_PRINT_OFF
|
||||
CHECK(s.replace_chars(String("Bn"), '\0') == "Banana");
|
||||
CHECK(s.replace_chars("Bn", '\0') == "Banana");
|
||||
ERR_PRINT_ON
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Insertion") {
|
||||
String s = "Who is Frederic?";
|
||||
s = s.insert(s.find("?"), " Chopin");
|
||||
|
|
@ -467,6 +522,23 @@ TEST_CASE("[String] Erasing") {
|
|||
CHECK(s == "Josephine is such a girl!");
|
||||
}
|
||||
|
||||
TEST_CASE("[String] remove_char") {
|
||||
String s = "Banana";
|
||||
CHECK(s.remove_char('a') == "Bnn");
|
||||
CHECK(s.remove_char('\0') == "Banana");
|
||||
CHECK(s.remove_char('x') == "Banana");
|
||||
}
|
||||
|
||||
TEST_CASE("[String] remove_chars") {
|
||||
String s = "Banana";
|
||||
CHECK(s.remove_chars("Ba") == "nn");
|
||||
CHECK(s.remove_chars(String("Ba")) == "nn");
|
||||
CHECK(s.remove_chars("") == "Banana");
|
||||
CHECK(s.remove_chars(String()) == "Banana");
|
||||
CHECK(s.remove_chars("xy") == "Banana");
|
||||
CHECK(s.remove_chars(String("xy")) == "Banana");
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Number to string") {
|
||||
CHECK(String::num(0) == "0.0"); // The method takes double, so always add zeros.
|
||||
CHECK(String::num(0.0) == "0.0");
|
||||
|
|
@ -507,12 +579,12 @@ TEST_CASE("[String] Number to string") {
|
|||
#ifdef REAL_T_IS_DOUBLE
|
||||
CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.456789", "Prints the appropriate amount of digits for real_t = double.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.456789", "Prints the appropriate amount of digits for real_t = double.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(Math::PI)) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero.");
|
||||
#else
|
||||
CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.4568", "Prints the appropriate amount of digits for real_t = float.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.4568", "Prints the appropriate amount of digits for real_t = float.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.141593", "Prints the appropriate amount of digits for real_t = float.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(Math::PI)) == "3.141593", "Prints the appropriate amount of digits for real_t = float.");
|
||||
CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float.");
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
|
||||
|
|
@ -603,7 +675,7 @@ TEST_CASE("[String] String to float") {
|
|||
static const double num[12] = { -12348298412.2, 0.05, 2.0002, -0.0001, 0.0, 0.0, 123.0, 0.0, 0.0, 0.007, 234.0, 3.0 };
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
CHECK(!(ABS(String(nums[i]).to_float() - num[i]) > 0.00001));
|
||||
CHECK(!(Math::abs(String(nums[i]).to_float() - num[i]) > 0.00001));
|
||||
}
|
||||
|
||||
// Invalid float strings should return 0.
|
||||
|
|
@ -618,15 +690,15 @@ TEST_CASE("[String] String to float") {
|
|||
CHECK(String("-1e308").to_float() == -1e308);
|
||||
|
||||
// Exponent is so high that value is INFINITY/-INFINITY.
|
||||
CHECK(String("1e309").to_float() == INFINITY);
|
||||
CHECK(String("1e511").to_float() == INFINITY);
|
||||
CHECK(String("-1e309").to_float() == -INFINITY);
|
||||
CHECK(String("-1e511").to_float() == -INFINITY);
|
||||
CHECK(String("1e309").to_float() == Math::INF);
|
||||
CHECK(String("1e511").to_float() == Math::INF);
|
||||
CHECK(String("-1e309").to_float() == -Math::INF);
|
||||
CHECK(String("-1e511").to_float() == -Math::INF);
|
||||
|
||||
// Exponent is so high that a warning message is printed. Value is INFINITY/-INFINITY.
|
||||
ERR_PRINT_OFF
|
||||
CHECK(String("1e512").to_float() == INFINITY);
|
||||
CHECK(String("-1e512").to_float() == -INFINITY);
|
||||
CHECK(String("1e512").to_float() == Math::INF);
|
||||
CHECK(String("-1e512").to_float() == -Math::INF);
|
||||
ERR_PRINT_ON
|
||||
}
|
||||
|
||||
|
|
@ -714,6 +786,14 @@ TEST_CASE("[String] Splitting") {
|
|||
CHECK(l[i] == slices[i]);
|
||||
}
|
||||
}
|
||||
{
|
||||
const String s = "Mars Jupiter Saturn Uranus";
|
||||
const char *slices[2] = { "Mars", "Jupiter Saturn Uranus" };
|
||||
Vector<String> l = s.split_spaces(1);
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
CHECK(l[i] == slices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const String s = "1.2;2.3 4.5";
|
||||
|
|
@ -722,14 +802,14 @@ TEST_CASE("[String] Splitting") {
|
|||
const Vector<double> d_arr = s.split_floats(";");
|
||||
CHECK(d_arr.size() == 2);
|
||||
for (int i = 0; i < d_arr.size(); i++) {
|
||||
CHECK(ABS(d_arr[i] - slices[i]) <= 0.00001);
|
||||
CHECK(Math::abs(d_arr[i] - slices[i]) <= 0.00001);
|
||||
}
|
||||
|
||||
const Vector<String> keys = { ";", " " };
|
||||
const Vector<float> f_arr = s.split_floats_mk(keys);
|
||||
CHECK(f_arr.size() == 3);
|
||||
for (int i = 0; i < f_arr.size(); i++) {
|
||||
CHECK(ABS(f_arr[i] - slices[i]) <= 0.00001);
|
||||
CHECK(Math::abs(f_arr[i] - slices[i]) <= 0.00001);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -740,7 +820,7 @@ TEST_CASE("[String] Splitting") {
|
|||
const Vector<double> arr = s.split_floats(" ");
|
||||
CHECK(arr.size() == 10);
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
CHECK(ABS(arr[i] - slices[i]) <= 0.00001);
|
||||
CHECK(Math::abs(arr[i] - slices[i]) <= 0.00001);
|
||||
}
|
||||
|
||||
const Vector<String> keys = { ";", " " };
|
||||
|
|
@ -923,7 +1003,7 @@ TEST_CASE("[String] sprintf") {
|
|||
// Real (infinity) left-padded
|
||||
format = "fish %11f frog";
|
||||
args.clear();
|
||||
args.push_back(INFINITY);
|
||||
args.push_back(Math::INF);
|
||||
output = format.sprintf(args, &error);
|
||||
REQUIRE(error == false);
|
||||
CHECK(output == String("fish inf frog"));
|
||||
|
|
@ -1047,7 +1127,7 @@ TEST_CASE("[String] sprintf") {
|
|||
// Vector left-padded with inf/nan
|
||||
format = "fish %11v frog";
|
||||
args.clear();
|
||||
args.push_back(Variant(Vector2(INFINITY, NAN)));
|
||||
args.push_back(Variant(Vector2(Math::INF, Math::NaN)));
|
||||
output = format.sprintf(args, &error);
|
||||
REQUIRE(error == false);
|
||||
CHECK(output == String("fish ( inf, nan) frog"));
|
||||
|
|
@ -1371,6 +1451,14 @@ TEST_CASE("[String] Capitalize against many strings") {
|
|||
output = "Snake Snake Case";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
||||
input = "kebab-case";
|
||||
output = "Kebab Case";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
||||
input = "kebab-kebab-case";
|
||||
output = "Kebab Kebab Case";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
||||
input = "sha256sum";
|
||||
output = "Sha 256 Sum";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
|
@ -1391,6 +1479,14 @@ TEST_CASE("[String] Capitalize against many strings") {
|
|||
output = "Snake Case Function( Snake Case Arg )";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
||||
input = "kebab-case-function( kebab-case-arg )";
|
||||
output = "Kebab Case Function( Kebab Case Arg )";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
||||
input = "kebab_case_function( kebab_case_arg )";
|
||||
output = "Kebab Case Function( Kebab Case Arg )";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
||||
input = U"словоСлово_слово слово";
|
||||
output = U"Слово Слово Слово Слово";
|
||||
CHECK(input.capitalize() == output);
|
||||
|
|
@ -1409,35 +1505,37 @@ struct StringCasesTestCase {
|
|||
const char32_t *camel_case;
|
||||
const char32_t *pascal_case;
|
||||
const char32_t *snake_case;
|
||||
const char32_t *kebab_case;
|
||||
};
|
||||
|
||||
TEST_CASE("[String] Checking case conversion methods") {
|
||||
StringCasesTestCase test_cases[] = {
|
||||
/* clang-format off */
|
||||
{ U"2D", U"2d", U"2d", U"2d" },
|
||||
{ U"2d", U"2d", U"2d", U"2d" },
|
||||
{ U"2db", U"2Db", U"2Db", U"2_db" },
|
||||
{ U"Vector3", U"vector3", U"Vector3", U"vector_3" },
|
||||
{ U"sha256", U"sha256", U"Sha256", U"sha_256" },
|
||||
{ U"Node2D", U"node2d", U"Node2d", U"node_2d" },
|
||||
{ U"RichTextLabel", U"richTextLabel", U"RichTextLabel", U"rich_text_label" },
|
||||
{ U"HTML5", U"html5", U"Html5", U"html_5" },
|
||||
{ U"Node2DPosition", U"node2dPosition", U"Node2dPosition", U"node_2d_position" },
|
||||
{ U"Number2Digits", U"number2Digits", U"Number2Digits", U"number_2_digits" },
|
||||
{ U"get_property_list", U"getPropertyList", U"GetPropertyList", U"get_property_list" },
|
||||
{ U"get_camera_2d", U"getCamera2d", U"GetCamera2d", U"get_camera_2d" },
|
||||
{ U"_physics_process", U"physicsProcess", U"PhysicsProcess", U"_physics_process" },
|
||||
{ U"bytes2var", U"bytes2Var", U"Bytes2Var", U"bytes_2_var" },
|
||||
{ U"linear2db", U"linear2Db", U"Linear2Db", U"linear_2_db" },
|
||||
{ U"sha256sum", U"sha256Sum", U"Sha256Sum", U"sha_256_sum" },
|
||||
{ U"camelCase", U"camelCase", U"CamelCase", U"camel_case" },
|
||||
{ U"PascalCase", U"pascalCase", U"PascalCase", U"pascal_case" },
|
||||
{ U"snake_case", U"snakeCase", U"SnakeCase", U"snake_case" },
|
||||
{ U"Test TEST test", U"testTestTest", U"TestTestTest", U"test_test_test" },
|
||||
{ U"словоСлово_слово слово", U"словоСловоСловоСлово", U"СловоСловоСловоСлово", U"слово_слово_слово_слово" },
|
||||
{ U"λέξηΛέξη_λέξη λέξη", U"λέξηΛέξηΛέξηΛέξη", U"ΛέξηΛέξηΛέξηΛέξη", U"λέξη_λέξη_λέξη_λέξη" },
|
||||
{ U"բառԲառ_բառ բառ", U"բառԲառԲառԲառ", U"ԲառԲառԲառԲառ", U"բառ_բառ_բառ_բառ" },
|
||||
{ nullptr, nullptr, nullptr, nullptr },
|
||||
{ U"2D", U"2d", U"2d", U"2d", U"2d" },
|
||||
{ U"2d", U"2d", U"2d", U"2d", U"2d" },
|
||||
{ U"2db", U"2Db", U"2Db", U"2_db", U"2-db" },
|
||||
{ U"Vector3", U"vector3", U"Vector3", U"vector_3", U"vector-3" },
|
||||
{ U"sha256", U"sha256", U"Sha256", U"sha_256", U"sha-256" },
|
||||
{ U"Node2D", U"node2d", U"Node2d", U"node_2d", U"node-2d" },
|
||||
{ U"RichTextLabel", U"richTextLabel", U"RichTextLabel", U"rich_text_label", U"rich-text-label" },
|
||||
{ U"HTML5", U"html5", U"Html5", U"html_5", U"html-5" },
|
||||
{ U"Node2DPosition", U"node2dPosition", U"Node2dPosition", U"node_2d_position", U"node-2d-position" },
|
||||
{ U"Number2Digits", U"number2Digits", U"Number2Digits", U"number_2_digits", U"number-2-digits" },
|
||||
{ U"get_property_list", U"getPropertyList", U"GetPropertyList", U"get_property_list", U"get-property-list" },
|
||||
{ U"get_camera_2d", U"getCamera2d", U"GetCamera2d", U"get_camera_2d", U"get-camera-2d" },
|
||||
{ U"_physics_process", U"physicsProcess", U"PhysicsProcess", U"_physics_process", U"-physics-process" },
|
||||
{ U"bytes2var", U"bytes2Var", U"Bytes2Var", U"bytes_2_var", U"bytes-2-var" },
|
||||
{ U"linear2db", U"linear2Db", U"Linear2Db", U"linear_2_db", U"linear-2-db" },
|
||||
{ U"sha256sum", U"sha256Sum", U"Sha256Sum", U"sha_256_sum", U"sha-256-sum" },
|
||||
{ U"camelCase", U"camelCase", U"CamelCase", U"camel_case", U"camel-case" },
|
||||
{ U"PascalCase", U"pascalCase", U"PascalCase", U"pascal_case", U"pascal-case" },
|
||||
{ U"snake_case", U"snakeCase", U"SnakeCase", U"snake_case", U"snake-case" },
|
||||
{ U"kebab-case", U"kebabCase", U"KebabCase", U"kebab_case", U"kebab-case" },
|
||||
{ U"Test TEST test", U"testTestTest", U"TestTestTest", U"test_test_test", U"test-test-test" },
|
||||
{ U"словоСлово_слово слово", U"словоСловоСловоСлово", U"СловоСловоСловоСлово", U"слово_слово_слово_слово", U"слово-слово-слово-слово" },
|
||||
{ U"λέξηΛέξη_λέξη λέξη", U"λέξηΛέξηΛέξηΛέξη", U"ΛέξηΛέξηΛέξηΛέξη", U"λέξη_λέξη_λέξη_λέξη", U"λέξη-λέξη-λέξη-λέξη" },
|
||||
{ U"բառԲառ_բառ բառ", U"բառԲառԲառԲառ", U"ԲառԲառԲառԲառ", U"բառ_բառ_բառ_բառ", U"բառ-բառ-բառ-բառ" },
|
||||
{ nullptr, nullptr, nullptr, nullptr, nullptr },
|
||||
/* clang-format on */
|
||||
};
|
||||
|
||||
|
|
@ -1447,6 +1545,7 @@ TEST_CASE("[String] Checking case conversion methods") {
|
|||
CHECK(input.to_camel_case() == test_cases[idx].camel_case);
|
||||
CHECK(input.to_pascal_case() == test_cases[idx].pascal_case);
|
||||
CHECK(input.to_snake_case() == test_cases[idx].snake_case);
|
||||
CHECK(input.to_kebab_case() == test_cases[idx].kebab_case);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1550,9 +1649,9 @@ TEST_CASE("[String] lstrip and rstrip") {
|
|||
#undef STRIP_TEST
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Ensuring empty string into parse_utf8 passes empty string") {
|
||||
TEST_CASE("[String] Ensuring empty string into extend_utf8 passes empty string") {
|
||||
String empty;
|
||||
CHECK(empty.parse_utf8(nullptr, -1) == ERR_INVALID_DATA);
|
||||
CHECK(empty.append_utf8(nullptr, -1) == ERR_INVALID_DATA);
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Cyrillic to_lower()") {
|
||||
|
|
@ -1715,6 +1814,7 @@ TEST_CASE("[String] uri_encode/unescape") {
|
|||
static const uint8_t u8str[] = { 0x54, 0xC4, 0x93, 0xC5, 0xA1, 0x74, 0x00 };
|
||||
String x2 = String::utf8((const char *)u8str);
|
||||
String x3 = U"Tēšt";
|
||||
String x4 = U"file+name";
|
||||
|
||||
CHECK(x1.uri_decode() == x2);
|
||||
CHECK(x1.uri_decode() == x3);
|
||||
|
|
@ -1724,6 +1824,8 @@ TEST_CASE("[String] uri_encode/unescape") {
|
|||
|
||||
CHECK(s.uri_encode() == t);
|
||||
CHECK(t.uri_decode() == s);
|
||||
CHECK(x4.uri_file_decode() == x4);
|
||||
CHECK(x4.uri_decode() == U"file name");
|
||||
}
|
||||
|
||||
TEST_CASE("[String] xml_escape/unescape") {
|
||||
|
|
@ -1896,7 +1998,7 @@ TEST_CASE("[String] Is_*") {
|
|||
static bool isflt[] = { true, true, true, false, true, true, false, false, false, false, false, false, false, true, true };
|
||||
static bool isaid[] = { false, false, false, false, false, false, false, false, true, true, false, false, false, false, false };
|
||||
static bool isuid[] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, false };
|
||||
for (unsigned int i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
|
||||
for (unsigned int i = 0; i < std::size(data); i++) {
|
||||
String s = String::utf8(data[i]);
|
||||
CHECK(s.is_numeric() == isnum[i]);
|
||||
CHECK(s.is_valid_int() == isint[i]);
|
||||
|
|
@ -2103,5 +2205,3 @@ TEST_CASE("[Stress][String] Empty via `is_empty()`") {
|
|||
}
|
||||
}
|
||||
} // namespace TestString
|
||||
|
||||
#endif // TEST_STRING_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_TRANSLATION_H
|
||||
#define TEST_TRANSLATION_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/optimized_translation.h"
|
||||
#include "core/string/translation.h"
|
||||
|
|
@ -201,5 +200,3 @@ TEST_CASE("[TranslationCSV] CSV import") {
|
|||
#endif // TOOLS_ENABLED
|
||||
|
||||
} // namespace TestTranslation
|
||||
|
||||
#endif // TEST_TRANSLATION_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_TRANSLATION_SERVER_H
|
||||
#define TEST_TRANSLATION_SERVER_H
|
||||
#pragma once
|
||||
|
||||
#include "core/string/translation_server.h"
|
||||
|
||||
|
|
@ -222,5 +221,3 @@ TEST_CASE("[TranslationServer] Comparing locales") {
|
|||
CHECK(res == 10);
|
||||
}
|
||||
} // namespace TestTranslationServer
|
||||
|
||||
#endif // TEST_TRANSLATION_SERVER_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_A_HASH_MAP_H
|
||||
#define TEST_A_HASH_MAP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/a_hash_map.h"
|
||||
|
||||
|
|
@ -235,9 +234,13 @@ TEST_CASE("[AHashMap] Insert, iterate and remove many elements") {
|
|||
TEST_CASE("[AHashMap] Insert, iterate and remove many strings") {
|
||||
const int elem_max = 432;
|
||||
AHashMap<String, String> map;
|
||||
|
||||
// To not print WARNING: Excessive collision count (NN), is the right hash function being used?
|
||||
ERR_PRINT_OFF;
|
||||
for (int i = 0; i < elem_max; i++) {
|
||||
map.insert(itos(i), itos(i));
|
||||
}
|
||||
ERR_PRINT_ON;
|
||||
|
||||
//insert order should have been kept
|
||||
int idx = 0;
|
||||
|
|
@ -309,5 +312,3 @@ TEST_CASE("[AHashMap] Array methods") {
|
|||
}
|
||||
|
||||
} // namespace TestAHashMap
|
||||
|
||||
#endif // TEST_A_HASH_MAP_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_COMMAND_QUEUE_H
|
||||
#define TEST_COMMAND_QUEUE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/math/random_number_generator.h"
|
||||
|
|
@ -562,5 +561,3 @@ TEST_CASE("[CommandQueue] Test Parameter Passing Semantics") {
|
|||
sts.destroy_threads();
|
||||
}
|
||||
} // namespace TestCommandQueue
|
||||
|
||||
#endif // TEST_COMMAND_QUEUE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_HASH_MAP_H
|
||||
#define TEST_HASH_MAP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/hash_map.h"
|
||||
|
||||
|
|
@ -147,5 +146,3 @@ TEST_CASE("[HashMap] Const iteration") {
|
|||
}
|
||||
}
|
||||
} // namespace TestHashMap
|
||||
|
||||
#endif // TEST_HASH_MAP_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_HASH_SET_H
|
||||
#define TEST_HASH_SET_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/hash_set.h"
|
||||
|
||||
|
|
@ -240,5 +239,3 @@ TEST_CASE("[HashSet] Copy") {
|
|||
}
|
||||
|
||||
} // namespace TestHashSet
|
||||
|
||||
#endif // TEST_HASH_SET_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_LIST_H
|
||||
#define TEST_LIST_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/list.h"
|
||||
|
||||
|
|
@ -555,5 +554,3 @@ TEST_CASE("[Stress][List] Swap random 10 elements, 1000 iterations.") {
|
|||
swap_random(list, n, 10, 1000);
|
||||
}
|
||||
} // namespace TestList
|
||||
|
||||
#endif // TEST_LIST_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_LOCAL_VECTOR_H
|
||||
#define TEST_LOCAL_VECTOR_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/local_vector.h"
|
||||
|
||||
|
|
@ -179,6 +178,23 @@ TEST_CASE("[LocalVector] Remove Unordered.") {
|
|||
CHECK(vector.size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("[LocalVector] Erase Unordered.") {
|
||||
LocalVector<int> vector;
|
||||
vector.push_back(1);
|
||||
vector.push_back(3);
|
||||
vector.push_back(0);
|
||||
vector.push_back(2);
|
||||
vector.push_back(4);
|
||||
|
||||
CHECK(vector.find(1) == 0);
|
||||
|
||||
vector.erase_unordered(1);
|
||||
|
||||
CHECK(vector.find(1) == -1);
|
||||
CHECK(vector.size() == 4);
|
||||
CHECK(vector[0] == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("[LocalVector] Erase.") {
|
||||
LocalVector<int> vector;
|
||||
vector.push_back(1);
|
||||
|
|
@ -245,5 +261,3 @@ TEST_CASE("[LocalVector] Size / Resize / Reserve.") {
|
|||
CHECK(vector.get_capacity() >= 4);
|
||||
}
|
||||
} // namespace TestLocalVector
|
||||
|
||||
#endif // TEST_LOCAL_VECTOR_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_LRU_H
|
||||
#define TEST_LRU_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/lru.h"
|
||||
|
||||
|
|
@ -95,5 +94,3 @@ TEST_CASE("[LRU] Resize and clear") {
|
|||
CHECK(!lru.has(4));
|
||||
}
|
||||
} // namespace TestLRU
|
||||
|
||||
#endif // TEST_LRU_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_OA_HASH_MAP_H
|
||||
#define TEST_OA_HASH_MAP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/oa_hash_map.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
|
@ -247,5 +246,3 @@ TEST_CASE("[OAHashMap] Non-trivial types") {
|
|||
}
|
||||
|
||||
} // namespace TestOAHashMap
|
||||
|
||||
#endif // TEST_OA_HASH_MAP_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_PAGED_ARRAY_H
|
||||
#define TEST_PAGED_ARRAY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/paged_array.h"
|
||||
|
||||
|
|
@ -200,5 +199,3 @@ TEST_CASE("[PagedArray] Extensive merge_unordered() test") {
|
|||
}
|
||||
|
||||
} // namespace TestPagedArray
|
||||
|
||||
#endif // TEST_PAGED_ARRAY_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_RID_H
|
||||
#define TEST_RID_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/thread.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
|
|
@ -38,6 +37,7 @@
|
|||
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
#ifdef THREADS_ENABLED
|
||||
#ifdef SANITIZERS_ENABLED
|
||||
#ifdef __has_feature
|
||||
#if __has_feature(thread_sanitizer)
|
||||
|
|
@ -46,7 +46,8 @@
|
|||
#elif defined(__SANITIZE_THREAD__)
|
||||
#define TSAN_ENABLED
|
||||
#endif
|
||||
#endif
|
||||
#endif // SANITIZERS_ENABLED
|
||||
#endif // THREADS_ENABLED
|
||||
|
||||
#ifdef TSAN_ENABLED
|
||||
#include <sanitizer/tsan_interface.h>
|
||||
|
|
@ -114,6 +115,7 @@ TEST_CASE("[RID] 'get_local_index'") {
|
|||
CHECK(RID::from_uint64(4'294'967'297).get_local_index() == 1);
|
||||
}
|
||||
|
||||
#ifdef THREADS_ENABLED
|
||||
// This case would let sanitizers realize data races.
|
||||
// Additionally, on purely weakly ordered architectures, it would detect synchronization issues
|
||||
// if RID_Alloc failed to impose proper memory ordering and the test's threads are distributed
|
||||
|
|
@ -141,7 +143,7 @@ TEST_CASE("[RID_Owner] Thread safety") {
|
|||
uint32_t target = (p_step / 2 + 1) * threads.size();
|
||||
sync[buf_idx].fetch_add(1, std::memory_order_relaxed);
|
||||
do {
|
||||
std::this_thread::yield();
|
||||
Thread::yield();
|
||||
} while (sync[buf_idx].load(std::memory_order_relaxed) != target);
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +251,6 @@ TEST_CASE("[RID_Owner] Thread safety") {
|
|||
tester.test();
|
||||
}
|
||||
}
|
||||
} // namespace TestRID
|
||||
#endif // THREADS_ENABLED
|
||||
|
||||
#endif // TEST_RID_H
|
||||
} // namespace TestRID
|
||||
|
|
|
|||
70
engine/tests/core/templates/test_span.h
Normal file
70
engine/tests/core/templates/test_span.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/**************************************************************************/
|
||||
/* test_span.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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/span.h"
|
||||
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
namespace TestSpan {
|
||||
|
||||
TEST_CASE("[Span] Constexpr Validators") {
|
||||
constexpr Span<uint16_t> span_empty;
|
||||
static_assert(span_empty.ptr() == nullptr);
|
||||
static_assert(span_empty.size() == 0);
|
||||
static_assert(span_empty.is_empty());
|
||||
|
||||
constexpr static uint16_t value = 5;
|
||||
constexpr Span<uint16_t> span_value(&value, 1);
|
||||
static_assert(span_value.ptr() == &value);
|
||||
static_assert(span_value.size() == 1);
|
||||
static_assert(!span_value.is_empty());
|
||||
|
||||
static constexpr int ints[] = { 0, 1, 2, 3, 4, 5 };
|
||||
constexpr Span<int> span_array = ints;
|
||||
static_assert(span_array.size() == 6);
|
||||
static_assert(!span_array.is_empty());
|
||||
static_assert(span_array[0] == 0);
|
||||
static_assert(span_array[span_array.size() - 1] == 5);
|
||||
|
||||
constexpr Span<char32_t> span_string = U"122345";
|
||||
static_assert(span_string.size() == 6);
|
||||
static_assert(!span_string.is_empty());
|
||||
static_assert(span_string[0] == U'1');
|
||||
static_assert(span_string[span_string.size() - 1] == U'5');
|
||||
|
||||
int idx = 0;
|
||||
for (const char32_t &chr : span_string) {
|
||||
CHECK_EQ(chr, span_string[idx++]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TestSpan
|
||||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VECTOR_H
|
||||
#define TEST_VECTOR_H
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/vector.h"
|
||||
|
||||
|
|
@ -706,5 +705,3 @@ TEST_CASE("[Vector] Cyclic Reference") {
|
|||
}
|
||||
|
||||
} // namespace TestVector
|
||||
|
||||
#endif // TEST_VECTOR_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_CRYPTO_H
|
||||
#define TEST_CRYPTO_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/crypto.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -60,8 +59,8 @@ PackedByteArray raw_to_pba(const uint8_t *arr, size_t len) {
|
|||
TEST_CASE("[Crypto] PackedByteArray constant time compare") {
|
||||
const uint8_t hm1[] = { 144, 140, 176, 38, 88, 113, 101, 45, 71, 105, 10, 91, 248, 16, 117, 244, 189, 30, 238, 29, 219, 134, 82, 130, 212, 114, 161, 166, 188, 169, 200, 106 };
|
||||
const uint8_t hm2[] = { 80, 30, 144, 228, 108, 38, 188, 125, 150, 64, 165, 127, 221, 118, 144, 232, 45, 100, 15, 248, 193, 244, 245, 34, 116, 147, 132, 200, 110, 27, 38, 75 };
|
||||
PackedByteArray p1 = raw_to_pba(hm1, sizeof(hm1) / sizeof(hm1[0]));
|
||||
PackedByteArray p2 = raw_to_pba(hm2, sizeof(hm2) / sizeof(hm2[0]));
|
||||
PackedByteArray p1 = raw_to_pba(hm1, std::size(hm1));
|
||||
PackedByteArray p2 = raw_to_pba(hm2, std::size(hm2));
|
||||
_MockCrypto crypto;
|
||||
bool equal = crypto.constant_time_compare(p1, p1);
|
||||
CHECK(equal);
|
||||
|
|
@ -69,5 +68,3 @@ TEST_CASE("[Crypto] PackedByteArray constant time compare") {
|
|||
CHECK(!equal);
|
||||
}
|
||||
} // namespace TestCrypto
|
||||
|
||||
#endif // TEST_CRYPTO_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_HASHING_CONTEXT_H
|
||||
#define TEST_HASHING_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/crypto/hashing_context.h"
|
||||
|
||||
|
|
@ -161,5 +160,3 @@ TEST_CASE("[HashingContext] Invalid use of finish") {
|
|||
ERR_PRINT_ON;
|
||||
}
|
||||
} // namespace TestHashingContext
|
||||
|
||||
#endif // TEST_HASHING_CONTEXT_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_TIME_H
|
||||
#define TEST_TIME_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/time.h"
|
||||
|
||||
|
|
@ -144,5 +143,3 @@ TEST_CASE("[Time] System time methods") {
|
|||
}
|
||||
|
||||
} // namespace TestTime
|
||||
|
||||
#endif // TEST_TIME_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_WORKER_THREAD_POOL_H
|
||||
#define TEST_WORKER_THREAD_POOL_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/worker_thread_pool.h"
|
||||
|
||||
|
|
@ -174,5 +173,3 @@ TEST_CASE("[WorkerThreadPool] Run a yielding daemon as the only hope for other t
|
|||
}
|
||||
|
||||
} // namespace TestWorkerThreadPool
|
||||
|
||||
#endif // TEST_WORKER_THREAD_POOL_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_ARRAY_H
|
||||
#define TEST_ARRAY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/variant/array.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -56,6 +55,26 @@ static inline Dictionary build_dictionary(Variant key, Variant item, Targs... Fa
|
|||
return d;
|
||||
}
|
||||
|
||||
TEST_CASE("[Array] initializer list") {
|
||||
Array arr = { 0, 1, "test", true, { 0.0, 1.0 } };
|
||||
CHECK(arr.size() == 5);
|
||||
CHECK(arr[0] == Variant(0));
|
||||
CHECK(arr[1] == Variant(1));
|
||||
CHECK(arr[2] == Variant("test"));
|
||||
CHECK(arr[3] == Variant(true));
|
||||
CHECK(arr[4] == Variant({ 0.0, 1.0 }));
|
||||
|
||||
arr = { "reassign" };
|
||||
CHECK(arr.size() == 1);
|
||||
CHECK(arr[0] == Variant("reassign"));
|
||||
|
||||
TypedArray<int> typed_arr = { 0, 1, 2 };
|
||||
CHECK(typed_arr.size() == 3);
|
||||
CHECK(typed_arr[0] == Variant(0));
|
||||
CHECK(typed_arr[1] == Variant(1));
|
||||
CHECK(typed_arr[2] == Variant(2));
|
||||
}
|
||||
|
||||
TEST_CASE("[Array] size(), clear(), and is_empty()") {
|
||||
Array arr;
|
||||
CHECK(arr.size() == 0);
|
||||
|
|
@ -107,6 +126,12 @@ TEST_CASE("[Array] resize(), insert(), and erase()") {
|
|||
CHECK(int(arr[0]) == 2);
|
||||
arr.erase(2);
|
||||
CHECK(int(arr[0]) == 1);
|
||||
|
||||
// Negative index on insert.
|
||||
CHECK(arr.size() == 3);
|
||||
arr.insert(-1, 3);
|
||||
CHECK(int(arr[2]) == 3);
|
||||
CHECK(arr.size() == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("[Array] front() and back()") {
|
||||
|
|
@ -120,9 +145,7 @@ TEST_CASE("[Array] front() and back()") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Array] has() and count()") {
|
||||
Array arr;
|
||||
arr.push_back(1);
|
||||
arr.push_back(1);
|
||||
Array arr = { 1, 1 };
|
||||
CHECK(arr.has(1));
|
||||
CHECK(!arr.has(2));
|
||||
CHECK(arr.count(1) == 2);
|
||||
|
|
@ -130,15 +153,22 @@ TEST_CASE("[Array] has() and count()") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Array] remove_at()") {
|
||||
Array arr;
|
||||
arr.push_back(1);
|
||||
arr.push_back(2);
|
||||
Array arr = { 1, 2 };
|
||||
arr.remove_at(0);
|
||||
CHECK(arr.size() == 1);
|
||||
CHECK(int(arr[0]) == 2);
|
||||
arr.remove_at(0);
|
||||
CHECK(arr.size() == 0);
|
||||
|
||||
// Negative index.
|
||||
arr.push_back(3);
|
||||
arr.push_back(4);
|
||||
arr.remove_at(-1);
|
||||
CHECK(arr.size() == 1);
|
||||
CHECK(int(arr[0]) == 3);
|
||||
arr.remove_at(-1);
|
||||
CHECK(arr.size() == 0);
|
||||
|
||||
// The array is now empty; try to use `remove_at()` again.
|
||||
// Normally, this prints an error message so we silence it.
|
||||
ERR_PRINT_OFF;
|
||||
|
|
@ -149,18 +179,12 @@ TEST_CASE("[Array] remove_at()") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Array] get()") {
|
||||
Array arr;
|
||||
arr.push_back(1);
|
||||
Array arr = { 1 };
|
||||
CHECK(int(arr.get(0)) == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("[Array] sort()") {
|
||||
Array arr;
|
||||
|
||||
arr.push_back(3);
|
||||
arr.push_back(4);
|
||||
arr.push_back(2);
|
||||
arr.push_back(1);
|
||||
Array arr = { 3, 4, 2, 1 };
|
||||
arr.sort();
|
||||
int val = 1;
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
|
|
@ -187,12 +211,7 @@ TEST_CASE("[Array] push_front(), pop_front(), pop_back()") {
|
|||
TEST_CASE("[Array] pop_at()") {
|
||||
ErrorDetector ed;
|
||||
|
||||
Array arr;
|
||||
arr.push_back(2);
|
||||
arr.push_back(4);
|
||||
arr.push_back(6);
|
||||
arr.push_back(8);
|
||||
arr.push_back(10);
|
||||
Array arr = { 2, 4, 6, 8, 10 };
|
||||
|
||||
REQUIRE(int(arr.pop_at(2)) == 6);
|
||||
REQUIRE(arr.size() == 4);
|
||||
|
|
@ -247,13 +266,7 @@ TEST_CASE("[Array] max() and min()") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Array] slice()") {
|
||||
Array array;
|
||||
array.push_back(0);
|
||||
array.push_back(1);
|
||||
array.push_back(2);
|
||||
array.push_back(3);
|
||||
array.push_back(4);
|
||||
array.push_back(5);
|
||||
Array array = { 0, 1, 2, 3, 4, 5 };
|
||||
|
||||
Array slice0 = array.slice(0, 0);
|
||||
CHECK(slice0.size() == 0);
|
||||
|
|
@ -598,11 +611,8 @@ TEST_CASE("[Array] Iteration and modification") {
|
|||
}
|
||||
|
||||
TEST_CASE("[Array] Typed copying") {
|
||||
TypedArray<int> a1;
|
||||
a1.push_back(1);
|
||||
|
||||
TypedArray<double> a2;
|
||||
a2.push_back(1.0);
|
||||
TypedArray<int> a1 = { 1 };
|
||||
TypedArray<double> a2 = { 1.0 };
|
||||
|
||||
Array a3 = a1;
|
||||
TypedArray<int> a4 = a3;
|
||||
|
|
@ -653,5 +663,3 @@ TEST_CASE("[Array] Test rfind_custom") {
|
|||
}
|
||||
|
||||
} // namespace TestArray
|
||||
|
||||
#endif // TEST_ARRAY_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_CALLABLE_H
|
||||
#define TEST_CALLABLE_H
|
||||
#pragma once
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/object/object.h"
|
||||
|
|
@ -155,11 +154,7 @@ public:
|
|||
}
|
||||
|
||||
static String get_output(const Callable &p_callable) {
|
||||
Array effective_args;
|
||||
effective_args.push_back(7);
|
||||
effective_args.push_back(8);
|
||||
effective_args.push_back(9);
|
||||
|
||||
Array effective_args = { 7, 8, 9 };
|
||||
effective_args.resize(3 - p_callable.get_unbound_arguments_count());
|
||||
effective_args.append_array(p_callable.get_bound_arguments());
|
||||
|
||||
|
|
@ -200,5 +195,3 @@ TEST_CASE("[Callable] Bound and unbound argument count") {
|
|||
}
|
||||
|
||||
} // namespace TestCallable
|
||||
|
||||
#endif // TEST_CALLABLE_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_DICTIONARY_H
|
||||
#define TEST_DICTIONARY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/variant/typed_dictionary.h"
|
||||
#include "tests/test_macros.h"
|
||||
|
|
@ -116,19 +115,18 @@ TEST_CASE("[Dictionary] List init") {
|
|||
CHECK_EQ(tdict[5.0], Variant(2.0));
|
||||
}
|
||||
|
||||
TEST_CASE("[Dictionary] get_key_lists()") {
|
||||
TEST_CASE("[Dictionary] get_key_list()") {
|
||||
Dictionary map;
|
||||
List<Variant> keys;
|
||||
List<Variant> *ptr = &keys;
|
||||
map.get_key_list(ptr);
|
||||
LocalVector<Variant> keys;
|
||||
keys = map.get_key_list();
|
||||
CHECK(keys.is_empty());
|
||||
map[1] = 3;
|
||||
map.get_key_list(ptr);
|
||||
keys = map.get_key_list();
|
||||
CHECK(keys.size() == 1);
|
||||
CHECK(int(keys.front()->get()) == 1);
|
||||
CHECK(int(keys[0]) == 1);
|
||||
map[2] = 4;
|
||||
map.get_key_list(ptr);
|
||||
CHECK(keys.size() == 3);
|
||||
keys = map.get_key_list();
|
||||
CHECK(keys.size() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("[Dictionary] get_key_at_index()") {
|
||||
|
|
@ -546,11 +544,7 @@ TEST_CASE("[Dictionary] Order and find") {
|
|||
d[12] = "twelve";
|
||||
d["4"] = "four";
|
||||
|
||||
Array keys;
|
||||
keys.append(4);
|
||||
keys.append(8);
|
||||
keys.append(12);
|
||||
keys.append("4");
|
||||
Array keys = { 4, 8, 12, "4" };
|
||||
|
||||
CHECK_EQ(d.keys(), keys);
|
||||
CHECK_EQ(d.find_key("four"), Variant(4));
|
||||
|
|
@ -594,6 +588,45 @@ TEST_CASE("[Dictionary] Typed copying") {
|
|||
d6.clear();
|
||||
}
|
||||
|
||||
} // namespace TestDictionary
|
||||
TEST_CASE("[Dictionary] Iteration") {
|
||||
Dictionary a1 = build_dictionary(1, 2, 3, 4, 5, 6);
|
||||
Dictionary a2 = build_dictionary(1, 2, 3, 4, 5, 6);
|
||||
|
||||
#endif // TEST_DICTIONARY_H
|
||||
int idx = 0;
|
||||
|
||||
for (const KeyValue<Variant, Variant> &kv : (const Dictionary &)a1) {
|
||||
CHECK_EQ(int(a2[kv.key]), int(kv.value));
|
||||
idx++;
|
||||
}
|
||||
|
||||
CHECK_EQ(idx, a1.size());
|
||||
|
||||
a1.clear();
|
||||
a2.clear();
|
||||
}
|
||||
|
||||
TEST_CASE("[Dictionary] Object value init") {
|
||||
Object *a = memnew(Object);
|
||||
Object *b = memnew(Object);
|
||||
TypedDictionary<double, Object *> tdict = {
|
||||
{ 0.0, a },
|
||||
{ 5.0, b },
|
||||
};
|
||||
CHECK_EQ(tdict[0.0], Variant(a));
|
||||
CHECK_EQ(tdict[5.0], Variant(b));
|
||||
memdelete(a);
|
||||
memdelete(b);
|
||||
}
|
||||
|
||||
TEST_CASE("[Dictionary] RefCounted value init") {
|
||||
Ref<RefCounted> a = memnew(RefCounted);
|
||||
Ref<RefCounted> b = memnew(RefCounted);
|
||||
TypedDictionary<double, Ref<RefCounted>> tdict = {
|
||||
{ 0.0, a },
|
||||
{ 5.0, b },
|
||||
};
|
||||
CHECK_EQ(tdict[0.0], Variant(a));
|
||||
CHECK_EQ(tdict[5.0], Variant(b));
|
||||
}
|
||||
|
||||
} // namespace TestDictionary
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VARIANT_H
|
||||
#define TEST_VARIANT_H
|
||||
#pragma once
|
||||
|
||||
#include "core/variant/variant.h"
|
||||
#include "core/variant/variant_parser.h"
|
||||
|
|
@ -1737,6 +1736,24 @@ TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,V
|
|||
CHECK(object_v.get_type() == Variant::COLOR);
|
||||
}
|
||||
|
||||
TEST_CASE("[Variant] array initializer list") {
|
||||
Variant arr_v = { 0, 1, "test", true, { 0.0, 1.0 } };
|
||||
CHECK(arr_v.get_type() == Variant::ARRAY);
|
||||
Array arr = (Array)arr_v;
|
||||
CHECK(arr.size() == 5);
|
||||
CHECK(arr[0] == Variant(0));
|
||||
CHECK(arr[1] == Variant(1));
|
||||
CHECK(arr[2] == Variant("test"));
|
||||
CHECK(arr[3] == Variant(true));
|
||||
CHECK(arr[4] == Variant({ 0.0, 1.0 }));
|
||||
|
||||
PackedInt32Array packed_arr = { 2, 1, 0 };
|
||||
CHECK(packed_arr.size() == 3);
|
||||
CHECK(packed_arr[0] == 2);
|
||||
CHECK(packed_arr[1] == 1);
|
||||
CHECK(packed_arr[2] == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("[Variant] Writer and parser array") {
|
||||
Array a = build_array(1, String("hello"), build_array(Variant()));
|
||||
String a_str;
|
||||
|
|
@ -2217,5 +2234,3 @@ TEST_CASE("[Variant] Operator NOT") {
|
|||
}
|
||||
|
||||
} // namespace TestVariant
|
||||
|
||||
#endif // TEST_VARIANT_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_VARIANT_UTILITY_H
|
||||
#define TEST_VARIANT_UTILITY_H
|
||||
#pragma once
|
||||
|
||||
#include "core/variant/variant_utility.h"
|
||||
|
||||
|
|
@ -93,15 +92,8 @@ TEST_CASE("[VariantUtility] Type conversion") {
|
|||
}
|
||||
|
||||
{
|
||||
Array arr;
|
||||
arr.push_back(1.2);
|
||||
arr.push_back(3.4);
|
||||
arr.push_back(5.6);
|
||||
|
||||
PackedFloat64Array packed;
|
||||
packed.push_back(1.2);
|
||||
packed.push_back(3.4);
|
||||
packed.push_back(5.6);
|
||||
Array arr = { 1.2, 3.4, 5.6 };
|
||||
PackedFloat64Array packed = { 1.2, 3.4, 5.6 };
|
||||
|
||||
converted = VariantUtilityFunctions::type_convert(arr, Variant::Type::PACKED_FLOAT64_ARRAY);
|
||||
CHECK(converted.get_type() == Variant::Type::PACKED_FLOAT64_ARRAY);
|
||||
|
|
@ -137,5 +129,3 @@ TEST_CASE("[VariantUtility] Type conversion") {
|
|||
}
|
||||
|
||||
} // namespace TestVariantUtility
|
||||
|
||||
#endif // TEST_VARIANT_UTILITY_H
|
||||
|
|
|
|||
|
|
@ -78,8 +78,7 @@ def main():
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_{name_upper_snake_case}_H
|
||||
#define TEST_{name_upper_snake_case}_H
|
||||
#pragma once
|
||||
|
||||
#include "tests/test_macros.h"
|
||||
|
||||
|
|
@ -90,14 +89,11 @@ TEST_CASE("[{name_pascal_case}] Example test case") {{
|
|||
}}
|
||||
|
||||
}} // namespace Test{name_pascal_case}
|
||||
|
||||
#endif // TEST_{name_upper_snake_case}_H
|
||||
""".format(
|
||||
name_snake_case=name_snake_case,
|
||||
# Capitalize the first letter but keep capitalization for the rest of the string.
|
||||
# This is done in case the user passes a camelCase string instead of PascalCase.
|
||||
name_pascal_case=args.name[0].upper() + args.name[1:],
|
||||
name_upper_snake_case=name_snake_case.upper(),
|
||||
# The padding length depends on the test name length.
|
||||
padding=" " * (61 - len(name_snake_case)),
|
||||
)
|
||||
|
|
|
|||
BIN
engine/tests/data/exactly_4096_bytes_fastlz.bin
Normal file
BIN
engine/tests/data/exactly_4096_bytes_fastlz.bin
Normal file
Binary file not shown.
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DISPLAY_SERVER_MOCK_H
|
||||
#define DISPLAY_SERVER_MOCK_H
|
||||
#pragma once
|
||||
|
||||
#include "servers/display_server_headless.h"
|
||||
|
||||
|
|
@ -38,6 +37,8 @@
|
|||
// Specialized DisplayServer for unittests based on DisplayServerHeadless, that
|
||||
// additionally supports things like mouse enter/exit events and clipboard.
|
||||
class DisplayServerMock : public DisplayServerHeadless {
|
||||
GDSOFTCLASS(DisplayServerMock, DisplayServerHeadless);
|
||||
|
||||
private:
|
||||
friend class DisplayServer;
|
||||
|
||||
|
|
@ -146,5 +147,3 @@ public:
|
|||
register_create_function("mock", create_func, get_rendering_drivers_func);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DISPLAY_SERVER_MOCK_H
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
ROOT = CWD.parent.parent
|
||||
# append directory with build files to sys.path to import them
|
||||
sys.path.append(str(ROOT))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def shader_files(request):
|
||||
shader_path = request.param
|
||||
|
||||
res = {
|
||||
"path_input": str(CWD / "fixtures" / f"{shader_path}.glsl"),
|
||||
"path_output": str(CWD / "fixtures" / f"{shader_path}.glsl.gen.h"),
|
||||
"path_expected_full": str(CWD / "fixtures" / f"{shader_path}_expected_full.glsl"),
|
||||
"path_expected_parts": str(CWD / "fixtures" / f"{shader_path}_expected_parts.json"),
|
||||
}
|
||||
yield res
|
||||
|
||||
if not os.getenv("PYTEST_KEEP_GENERATED_FILES"):
|
||||
os.remove(res["path_output"])
|
||||
64
engine/tests/python_build/fixtures/gles3/vertex_fragment.out
Normal file
64
engine/tests/python_build/fixtures/gles3/vertex_fragment.out
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "drivers/gles3/shader_gles3.h"
|
||||
|
||||
class VertexFragmentShaderGLES3 : public ShaderGLES3 {
|
||||
public:
|
||||
enum ShaderVariant {
|
||||
MODE_NINEPATCH,
|
||||
};
|
||||
|
||||
enum Specializations {
|
||||
DISABLE_LIGHTING = 1,
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ bool version_bind_shader(RID p_version, ShaderVariant p_variant, uint64_t p_specialization = 0) {
|
||||
return _version_bind_shader(p_version, p_variant, p_specialization);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void _init() override {
|
||||
static const char **_uniform_strings = nullptr;
|
||||
static const char *_variant_defines[] = {
|
||||
"#define USE_NINEPATCH",
|
||||
};
|
||||
static TexUnitPair *_texunit_pairs = nullptr;
|
||||
static UBOPair *_ubo_pairs = nullptr;
|
||||
static Specialization _spec_pairs[] = {
|
||||
{ "DISABLE_LIGHTING", false },
|
||||
};
|
||||
static const Feedback *_feedbacks = nullptr;
|
||||
static const char _vertex_code[] = {
|
||||
R"<!>(
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
layout(location = 0) in highp vec3 vertex;
|
||||
|
||||
out highp vec4 position_interp;
|
||||
|
||||
void main() {
|
||||
position_interp = vec4(vertex.x,1,0,1);
|
||||
}
|
||||
|
||||
)<!>"
|
||||
};
|
||||
|
||||
static const char _fragment_code[] = {
|
||||
R"<!>(
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
in highp vec4 position_interp;
|
||||
|
||||
void main() {
|
||||
highp float depth = ((position_interp.z / position_interp.w) + 1.0);
|
||||
frag_color = vec4(depth);
|
||||
}
|
||||
)<!>"
|
||||
};
|
||||
|
||||
_setup(_vertex_code, _fragment_code, "VertexFragmentShaderGLES3",
|
||||
0, _uniform_strings, 0, _ubo_pairs,
|
||||
0, _feedbacks, 0, _texunit_pairs,
|
||||
1, _spec_pairs, 1, _variant_defines);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
|
||||
#ifndef VERTEX_FRAGMENT_GLSL_GEN_HGLES3_GLES3
|
||||
#define VERTEX_FRAGMENT_GLSL_GEN_HGLES3_GLES3
|
||||
|
||||
|
||||
#include "drivers/gles3/shader_gles3.h"
|
||||
|
||||
|
||||
class VertexFragmentShaderGLES3 : public ShaderGLES3 {
|
||||
|
||||
public:
|
||||
|
||||
enum ShaderVariant {
|
||||
MODE_NINEPATCH,
|
||||
};
|
||||
|
||||
enum Specializations {
|
||||
DISABLE_LIGHTING=1,
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ bool version_bind_shader(RID p_version,ShaderVariant p_variant,uint64_t p_specialization=0) { return _version_bind_shader(p_version,p_variant,p_specialization); }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void _init() override {
|
||||
|
||||
static const char **_uniform_strings=nullptr;
|
||||
static const char* _variant_defines[]={
|
||||
"#define USE_NINEPATCH",
|
||||
};
|
||||
|
||||
static TexUnitPair *_texunit_pairs=nullptr;
|
||||
static UBOPair *_ubo_pairs=nullptr;
|
||||
static Specialization _spec_pairs[]={
|
||||
{"DISABLE_LIGHTING",false},
|
||||
};
|
||||
|
||||
static const Feedback* _feedbacks=nullptr;
|
||||
static const char _vertex_code[]={
|
||||
R"<!>(
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
layout(location = 0) in highp vec3 vertex;
|
||||
|
||||
out highp vec4 position_interp;
|
||||
|
||||
void main() {
|
||||
position_interp = vec4(vertex.x,1,0,1);
|
||||
}
|
||||
|
||||
)<!>"
|
||||
};
|
||||
|
||||
static const char _fragment_code[]={
|
||||
R"<!>(
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
in highp vec4 position_interp;
|
||||
|
||||
void main() {
|
||||
highp float depth = ((position_interp.z / position_interp.w) + 1.0);
|
||||
frag_color = vec4(depth);
|
||||
}
|
||||
)<!>"
|
||||
};
|
||||
|
||||
_setup(_vertex_code,_fragment_code,"VertexFragmentShaderGLES3",0,_uniform_strings,0,_ubo_pairs,0,_feedbacks,0,_texunit_pairs,1,_spec_pairs,1,_variant_defines);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
{
|
||||
"vertex_lines": [
|
||||
"",
|
||||
"precision highp float;",
|
||||
"precision highp int;",
|
||||
"",
|
||||
"layout(location = 0) in highp vec3 vertex;",
|
||||
"",
|
||||
"out highp vec4 position_interp;",
|
||||
"",
|
||||
"void main() {",
|
||||
"\tposition_interp = vec4(vertex.x,1,0,1);",
|
||||
"}",
|
||||
""
|
||||
],
|
||||
"fragment_lines": [
|
||||
"",
|
||||
"precision highp float;",
|
||||
"precision highp int;",
|
||||
"",
|
||||
"in highp vec4 position_interp;",
|
||||
"",
|
||||
"void main() {",
|
||||
"\thighp float depth = ((position_interp.z / position_interp.w) + 1.0);",
|
||||
"\tfrag_color = vec4(depth);",
|
||||
"}"
|
||||
],
|
||||
"uniforms": [],
|
||||
"fbos": [],
|
||||
"texunits": [],
|
||||
"texunit_names": [],
|
||||
"ubos": [],
|
||||
"ubo_names": [],
|
||||
"feedbacks": [],
|
||||
"vertex_included_files": [],
|
||||
"fragment_included_files": [],
|
||||
"reading": "fragment",
|
||||
"line_offset": 33,
|
||||
"vertex_offset": 10,
|
||||
"fragment_offset": 23,
|
||||
"variant_defines": [
|
||||
"#define USE_NINEPATCH"
|
||||
],
|
||||
"variant_names": [
|
||||
"MODE_NINEPATCH"
|
||||
],
|
||||
"specialization_names": [
|
||||
"DISABLE_LIGHTING"
|
||||
],
|
||||
"specialization_values": [
|
||||
" false\n"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
|
||||
#ifndef COMPUTE_SHADER_GLSL_RAW_H
|
||||
#define COMPUTE_SHADER_GLSL_RAW_H
|
||||
|
||||
static const char compute_shader_glsl[] = {
|
||||
R"<!>(#[compute]
|
||||
|
||||
|
|
@ -17,4 +13,3 @@ void main() {
|
|||
}
|
||||
)<!>"
|
||||
};
|
||||
#endif
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"code": "#[compute]\n\n#version 450\n\n#VERSION_DEFINES\n\n\n#define M_PI 3.14159265359\n\nvoid main() {\n\tvec3 static_light = vec3(0, 1, 0);\n}\n"
|
||||
}
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
|
||||
#ifndef VERTEX_FRAGMENT_SHADER_GLSL_RAW_H
|
||||
#define VERTEX_FRAGMENT_SHADER_GLSL_RAW_H
|
||||
|
||||
static const char vertex_fragment_shader_glsl[] = {
|
||||
R"<!>(#[versions]
|
||||
|
||||
|
|
@ -37,4 +33,3 @@ void main() {
|
|||
}
|
||||
)<!>"
|
||||
};
|
||||
#endif
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"code": "#[versions]\n\nlines = \"#define MODE_LINES\";\n\n#[vertex]\n\n#version 450\n\n#VERSION_DEFINES\n\nlayout(location = 0) out vec3 uv_interp;\n\nvoid main() {\n\n#ifdef MODE_LINES\n\tuv_interp = vec3(0,0,1);\n#endif\n}\n\n#[fragment]\n\n#version 450\n\n#VERSION_DEFINES\n\n#define M_PI 3.14159265359\n\nlayout(location = 0) out vec4 dst_color;\n\nvoid main() {\n\tdst_color = vec4(1,1,0,0);\n}\n"
|
||||
}
|
||||
|
|
@ -1,15 +1,10 @@
|
|||
/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
|
||||
#ifndef COMPUTE_GLSL_GEN_H_RD
|
||||
#define COMPUTE_GLSL_GEN_H_RD
|
||||
|
||||
#include "servers/rendering/renderer_rd/shader_rd.h"
|
||||
|
||||
class ComputeShaderRD : public ShaderRD {
|
||||
|
||||
public:
|
||||
|
||||
ComputeShaderRD() {
|
||||
|
||||
static const char *_vertex_code = nullptr;
|
||||
static const char *_fragment_code = nullptr;
|
||||
static const char _compute_code[] = {
|
||||
R"<!>(
|
||||
#version 450
|
||||
|
|
@ -25,8 +20,6 @@ void main() {
|
|||
}
|
||||
)<!>"
|
||||
};
|
||||
setup(nullptr, nullptr, _compute_code, "ComputeShaderRD");
|
||||
setup(_vertex_code, _fragment_code, _compute_code, "ComputeShaderRD");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"vertex_lines": [],
|
||||
"fragment_lines": [],
|
||||
"compute_lines": [
|
||||
"",
|
||||
"#version 450",
|
||||
"",
|
||||
"#VERSION_DEFINES",
|
||||
"",
|
||||
"#define BLOCK_SIZE 8",
|
||||
"",
|
||||
"#define M_PI 3.14159265359",
|
||||
"",
|
||||
"void main() {",
|
||||
"\tuint t = BLOCK_SIZE + 1;",
|
||||
"}"
|
||||
],
|
||||
"vertex_included_files": [],
|
||||
"fragment_included_files": [],
|
||||
"compute_included_files": [
|
||||
"tests/python_build/fixtures/rd_glsl/_included.glsl"
|
||||
],
|
||||
"reading": "compute",
|
||||
"line_offset": 13,
|
||||
"vertex_offset": 0,
|
||||
"fragment_offset": 0,
|
||||
"compute_offset": 1
|
||||
}
|
||||
|
|
@ -1,15 +1,8 @@
|
|||
/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
|
||||
#ifndef VERTEX_FRAGMENT_GLSL_GEN_H_RD
|
||||
#define VERTEX_FRAGMENT_GLSL_GEN_H_RD
|
||||
|
||||
#include "servers/rendering/renderer_rd/shader_rd.h"
|
||||
|
||||
class VertexFragmentShaderRD : public ShaderRD {
|
||||
|
||||
public:
|
||||
|
||||
VertexFragmentShaderRD() {
|
||||
|
||||
static const char _vertex_code[] = {
|
||||
R"<!>(
|
||||
#version 450
|
||||
|
|
@ -39,8 +32,7 @@ void main() {
|
|||
}
|
||||
)<!>"
|
||||
};
|
||||
setup(_vertex_code, _fragment_code, nullptr, "VertexFragmentShaderRD");
|
||||
static const char *_compute_code = nullptr;
|
||||
setup(_vertex_code, _fragment_code, _compute_code, "VertexFragmentShaderRD");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
"vertex_lines": [
|
||||
"",
|
||||
"#version 450",
|
||||
"",
|
||||
"#VERSION_DEFINES",
|
||||
"",
|
||||
"#define M_PI 3.14159265359",
|
||||
"",
|
||||
"layout(location = 0) out vec2 uv_interp;",
|
||||
"",
|
||||
"void main() {",
|
||||
"\tuv_interp = vec2(0, 1);",
|
||||
"}",
|
||||
""
|
||||
],
|
||||
"fragment_lines": [
|
||||
"",
|
||||
"#version 450",
|
||||
"",
|
||||
"#VERSION_DEFINES",
|
||||
"",
|
||||
"layout(location = 0) in vec2 uv_interp;",
|
||||
"",
|
||||
"void main() {",
|
||||
"\tuv_interp = vec2(1, 0);",
|
||||
"}"
|
||||
],
|
||||
"compute_lines": [],
|
||||
"vertex_included_files": [
|
||||
"tests/python_build/fixtures/rd_glsl/_included.glsl"
|
||||
],
|
||||
"fragment_included_files": [],
|
||||
"compute_included_files": [],
|
||||
"reading": "fragment",
|
||||
"line_offset": 25,
|
||||
"vertex_offset": 1,
|
||||
"fragment_offset": 15,
|
||||
"compute_offset": 0
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from gles3_builders import GLES3HeaderStruct, build_gles3_header
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
["shader_files", "builder", "header_struct"],
|
||||
[
|
||||
("gles3/vertex_fragment", build_gles3_header, GLES3HeaderStruct),
|
||||
],
|
||||
indirect=["shader_files"],
|
||||
)
|
||||
def test_gles3_builder(shader_files, builder, header_struct):
|
||||
header = header_struct()
|
||||
|
||||
builder(shader_files["path_input"], "drivers/gles3/shader_gles3.h", "GLES3", header_data=header)
|
||||
|
||||
with open(shader_files["path_expected_parts"], "r", encoding="utf-8") as f:
|
||||
expected_parts = json.load(f)
|
||||
assert expected_parts == header.__dict__
|
||||
|
||||
with open(shader_files["path_output"], "r", encoding="utf-8") as f:
|
||||
actual_output = f.read()
|
||||
assert actual_output
|
||||
|
||||
with open(shader_files["path_expected_full"], "r", encoding="utf-8") as f:
|
||||
expected_output = f.read()
|
||||
|
||||
assert actual_output == expected_output
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from glsl_builders import RAWHeaderStruct, RDHeaderStruct, build_raw_header, build_rd_header
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
[
|
||||
"shader_files",
|
||||
"builder",
|
||||
"header_struct",
|
||||
],
|
||||
[
|
||||
("glsl/vertex_fragment", build_raw_header, RAWHeaderStruct),
|
||||
("glsl/compute", build_raw_header, RAWHeaderStruct),
|
||||
("rd_glsl/vertex_fragment", build_rd_header, RDHeaderStruct),
|
||||
("rd_glsl/compute", build_rd_header, RDHeaderStruct),
|
||||
],
|
||||
indirect=["shader_files"],
|
||||
)
|
||||
def test_glsl_builder(shader_files, builder, header_struct):
|
||||
header = header_struct()
|
||||
builder(shader_files["path_input"], header_data=header)
|
||||
|
||||
with open(shader_files["path_expected_parts"], "r", encoding="utf-8") as f:
|
||||
expected_parts = json.load(f)
|
||||
assert expected_parts == header.__dict__
|
||||
|
||||
with open(shader_files["path_output"], "r", encoding="utf-8") as f:
|
||||
actual_output = f.read()
|
||||
assert actual_output
|
||||
|
||||
with open(shader_files["path_expected_full"], "r", encoding="utf-8") as f:
|
||||
expected_output = f.read()
|
||||
|
||||
assert actual_output == expected_output
|
||||
63
engine/tests/python_build/validate_builders.py
Normal file
63
engine/tests/python_build/validate_builders.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
if __name__ != "__main__":
|
||||
raise ImportError(f"{__name__} should not be used as a module.")
|
||||
|
||||
import os
|
||||
import sys
|
||||
from typing import Any, Callable
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../"))
|
||||
|
||||
from gles3_builders import build_gles3_header
|
||||
from glsl_builders import build_raw_header, build_rd_header
|
||||
|
||||
FUNC_PATH_KWARGS: list[tuple[Callable[..., None], str, dict[str, Any]]] = [
|
||||
(
|
||||
build_gles3_header,
|
||||
"tests/python_build/fixtures/gles3/vertex_fragment.out",
|
||||
{"shader": "tests/python_build/fixtures/gles3/vertex_fragment.glsl"},
|
||||
),
|
||||
(
|
||||
build_raw_header,
|
||||
"tests/python_build/fixtures/glsl/compute.out",
|
||||
{"shader": "tests/python_build/fixtures/glsl/compute.glsl"},
|
||||
),
|
||||
(
|
||||
build_raw_header,
|
||||
"tests/python_build/fixtures/glsl/vertex_fragment.out",
|
||||
{"shader": "tests/python_build/fixtures/glsl/vertex_fragment.glsl"},
|
||||
),
|
||||
(
|
||||
build_rd_header,
|
||||
"tests/python_build/fixtures/rd_glsl/compute.out",
|
||||
{"shader": "tests/python_build/fixtures/rd_glsl/compute.glsl"},
|
||||
),
|
||||
(
|
||||
build_rd_header,
|
||||
"tests/python_build/fixtures/rd_glsl/vertex_fragment.out",
|
||||
{"shader": "tests/python_build/fixtures/rd_glsl/vertex_fragment.glsl"},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ret = 0
|
||||
|
||||
for func, path, kwargs in FUNC_PATH_KWARGS:
|
||||
if os.path.exists(out_path := os.path.abspath(path)):
|
||||
with open(out_path, "rb") as file:
|
||||
raw = file.read()
|
||||
func(path, **kwargs)
|
||||
with open(out_path, "rb") as file:
|
||||
if raw != file.read():
|
||||
ret += 1
|
||||
else:
|
||||
func(path, **kwargs)
|
||||
ret += 1
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
sys.exit(main())
|
||||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_ANIMATION_H
|
||||
#define TEST_ANIMATION_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/resources/animation.h"
|
||||
|
||||
|
|
@ -310,5 +309,3 @@ TEST_CASE("[Animation] Create Bezier track") {
|
|||
}
|
||||
|
||||
} // namespace TestAnimation
|
||||
|
||||
#endif // TEST_ANIMATION_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_ARRAYMESH_H
|
||||
#define TEST_ARRAYMESH_H
|
||||
#pragma once
|
||||
|
||||
#include "scene/resources/3d/primitive_meshes.h"
|
||||
#include "scene/resources/mesh.h"
|
||||
|
|
@ -149,9 +148,7 @@ TEST_CASE("[SceneTree][ArrayMesh] Adding and modifying blendshapes.") {
|
|||
blend_shape[Mesh::ARRAY_VERTEX] = cylinder_array[Mesh::ARRAY_VERTEX];
|
||||
blend_shape[Mesh::ARRAY_NORMAL] = cylinder_array[Mesh::ARRAY_NORMAL];
|
||||
blend_shape[Mesh::ARRAY_TANGENT] = cylinder_array[Mesh::ARRAY_TANGENT];
|
||||
Array blend_shapes;
|
||||
blend_shapes.push_back(blend_shape);
|
||||
blend_shapes.push_back(blend_shape);
|
||||
Array blend_shapes = { blend_shape, blend_shape };
|
||||
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, cylinder_array, blend_shapes);
|
||||
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, cylinder_array, blend_shapes);
|
||||
|
||||
|
|
@ -189,9 +186,7 @@ TEST_CASE("[SceneTree][ArrayMesh] Adding and modifying blendshapes.") {
|
|||
blend_shape[Mesh::ARRAY_VERTEX] = cylinder_array[Mesh::ARRAY_VERTEX];
|
||||
blend_shape[Mesh::ARRAY_NORMAL] = cylinder_array[Mesh::ARRAY_NORMAL];
|
||||
blend_shape[Mesh::ARRAY_TANGENT] = cylinder_array[Mesh::ARRAY_TANGENT];
|
||||
Array blend_shapes;
|
||||
blend_shapes.push_back(blend_shape);
|
||||
blend_shapes.push_back(blend_shape);
|
||||
Array blend_shapes = { blend_shape, blend_shape };
|
||||
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, cylinder_array, blend_shapes);
|
||||
|
||||
ERR_PRINT_OFF
|
||||
|
|
@ -449,5 +444,3 @@ TEST_CASE("[SceneTree][ArrayMesh] Get/Set mesh metadata and actions") {
|
|||
}
|
||||
|
||||
} // namespace TestArrayMesh
|
||||
|
||||
#endif // TEST_ARRAYMESH_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_AUDIO_STREAM_WAV_H
|
||||
#define TEST_AUDIO_STREAM_WAV_H
|
||||
#pragma once
|
||||
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
|
|
@ -47,7 +46,7 @@ constexpr int WAV_COUNT = WAV_RATE;
|
|||
|
||||
float gen_wav(float frequency, float wav_rate, int wav_number) {
|
||||
// formula for generating a sin wave with given frequency.
|
||||
return Math::sin((Math_TAU * frequency / wav_rate) * wav_number);
|
||||
return Math::sin((Math::TAU * frequency / wav_rate) * wav_number);
|
||||
}
|
||||
|
||||
/* Generates a 440Hz sin wave in channel 0 (mono channel or left stereo channel)
|
||||
|
|
@ -218,5 +217,3 @@ TEST_CASE("[Audio][AudioStreamWAV] Saving IMA ADPCM is not supported") {
|
|||
}
|
||||
|
||||
} // namespace TestAudioStreamWAV
|
||||
|
||||
#endif // TEST_AUDIO_STREAM_WAV_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TEST_BIT_MAP_H
|
||||
#define TEST_BIT_MAP_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/memory.h"
|
||||
#include "scene/resources/bit_map.h"
|
||||
|
|
@ -501,5 +500,3 @@ TEST_CASE("[BitMap] Clip to polygon") {
|
|||
}
|
||||
|
||||
} // namespace TestBitmap
|
||||
|
||||
#endif // TEST_BIT_MAP_H
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue