-
-
Notifications
You must be signed in to change notification settings - Fork 21k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port GDScript test/debugging tools #41355
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,6 @@ env.tests_sources = [] | |
|
||
env_tests = env.Clone() | ||
|
||
# Enable test framework and inform it of configuration method. | ||
env_tests.Append(CPPDEFINES=["DOCTEST_CONFIG_IMPLEMENT"]) | ||
|
||
Comment on lines
-9
to
-11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed this and define |
||
# We must disable the THREAD_LOCAL entirely in doctest to prevent crashes on debugging | ||
# Since we link with /MT thread_local is always expired when the header is used | ||
# So the debugger crashes the engine and it causes weird errors | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/*************************************************************************/ | ||
/* test_macros.cpp */ | ||
/*************************************************************************/ | ||
/* This file is part of: */ | ||
/* GODOT ENGINE */ | ||
/* https://godotengine.org */ | ||
/*************************************************************************/ | ||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ | ||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ | ||
/* */ | ||
/* Permission is hereby granted, free of charge, to any person obtaining */ | ||
/* a copy of this software and associated documentation files (the */ | ||
/* "Software"), to deal in the Software without restriction, including */ | ||
/* without limitation the rights to use, copy, modify, merge, publish, */ | ||
/* distribute, sublicense, and/or sell copies of the Software, and to */ | ||
/* permit persons to whom the Software is furnished to do so, subject to */ | ||
/* the following conditions: */ | ||
/* */ | ||
/* The above copyright notice and this permission notice shall be */ | ||
/* included in all copies or substantial portions of the Software. */ | ||
/* */ | ||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ | ||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ | ||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | ||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ | ||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ | ||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ | ||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
/*************************************************************************/ | ||
|
||
#define DOCTEST_CONFIG_IMPLEMENT | ||
#include "test_macros.h" | ||
|
||
Map<String, TestFunc> *test_commands = nullptr; | ||
|
||
int register_test_command(String p_command, TestFunc p_function) { | ||
if (!test_commands) { | ||
test_commands = new Map<String, TestFunc>; | ||
} | ||
test_commands->insert(p_command, p_function); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,7 +37,6 @@ | |
#include "test_class_db.h" | ||
#include "test_color.h" | ||
#include "test_expression.h" | ||
#include "test_gdscript.h" | ||
#include "test_gradient.h" | ||
#include "test_gui.h" | ||
#include "test_math.h" | ||
|
@@ -56,40 +55,63 @@ | |
#include "tests/test_macros.h" | ||
|
||
int test_main(int argc, char *argv[]) { | ||
bool run_tests = true; | ||
|
||
// Convert arguments to Godot's command-line. | ||
List<String> args; | ||
|
||
for (int i = 0; i < argc; i++) { | ||
args.push_back(String::utf8(argv[i])); | ||
} | ||
OS::get_singleton()->set_cmdline("", args); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first argument is empty because there's no way to know the executable name with the existing testing interface, but I'm not sure whether that's essential in the first place. |
||
|
||
// Run custom test tools. | ||
if (test_commands) { | ||
for (Map<String, TestFunc>::Element *E = test_commands->front(); E; E = E->next()) { | ||
if (args.find(E->key())) { | ||
const TestFunc &test_func = E->get(); | ||
test_func(); | ||
run_tests = false; | ||
break; | ||
} | ||
} | ||
if (!run_tests) { | ||
delete test_commands; | ||
return 0; | ||
} | ||
} | ||
// Doctest runner. | ||
doctest::Context test_context; | ||
List<String> valid_arguments; | ||
List<String> test_args; | ||
|
||
// Clean arguments of "--test" from the args. | ||
int argument_count = 0; | ||
for (int x = 0; x < argc; x++) { | ||
if (strncmp(argv[x], "--test", 6) != 0) { | ||
valid_arguments.push_back(String(argv[x])); | ||
argument_count++; | ||
test_args.push_back(String(argv[x])); | ||
} | ||
} | ||
// Convert Godot command line arguments back to standard arguments. | ||
char **args = new char *[valid_arguments.size()]; | ||
for (int x = 0; x < valid_arguments.size(); x++) { | ||
char **doctest_args = new char *[test_args.size()]; | ||
for (int x = 0; x < test_args.size(); x++) { | ||
// Operation to convert Godot string to non wchar string. | ||
CharString cs = valid_arguments[x].utf8(); | ||
CharString cs = test_args[x].utf8(); | ||
const char *str = cs.get_data(); | ||
// Allocate the string copy. | ||
args[x] = new char[strlen(str) + 1]; | ||
doctest_args[x] = new char[strlen(str) + 1]; | ||
// Copy this into memory. | ||
std::memcpy(args[x], str, strlen(str) + 1); | ||
memcpy(doctest_args[x], str, strlen(str) + 1); | ||
} | ||
|
||
test_context.applyCommandLine(valid_arguments.size(), args); | ||
test_context.applyCommandLine(test_args.size(), doctest_args); | ||
|
||
test_context.setOption("order-by", "name"); | ||
test_context.setOption("abort-after", 5); | ||
test_context.setOption("no-breaks", true); | ||
|
||
for (int x = 0; x < valid_arguments.size(); x++) { | ||
delete[] args[x]; | ||
for (int x = 0; x < test_args.size(); x++) { | ||
delete[] doctest_args[x]; | ||
} | ||
delete[] args; | ||
delete[] doctest_args; | ||
|
||
return test_context.run(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? It should already be inherited from the main
env
which was cloned forenv_gdscript
no?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because we're actually outside of the
main/
env here. Recall #40726, this is what I meant when saying that some modules may eventually need this. DefiningTESTS_ENABLED
for all modules is also an option, but GDScript may be just an exception.Technically, those are more like debug tools the way I see it, but they still qualify as something which facilitate manual testing process.