diff options
Diffstat (limited to 'modules/gdscript/tests')
65 files changed, 742 insertions, 150 deletions
diff --git a/modules/gdscript/tests/README.md b/modules/gdscript/tests/README.md index 361d586d32..72b5316532 100644 --- a/modules/gdscript/tests/README.md +++ b/modules/gdscript/tests/README.md @@ -6,3 +6,44 @@ and output files. See the [Integration tests for GDScript documentation](https://docs.godotengine.org/en/latest/contributing/development/core_and_modules/unit_testing.html#integration-tests-for-gdscript) for information about creating and running GDScript integration tests. + +# GDScript Autocompletion tests + +The `script/completion` folder contains test for the GDScript autocompletion. + +Each test case consists of at least one `.gd` file, which contains the code, and one `.cfg` file, which contains expected results and configuration. Inside of the GDScript file the character `➡` represents the cursor position, at which autocompletion is invoked. + +The config file contains two section: + +`[input]` contains keys that configure the test environment. The following keys are possible: + +- `cs: boolean = false`: If `true`, the test will be skipped when running a non C# build. +- `use_single_quotes: boolean = false`: Configures the corresponding editor setting for the test. +- `scene: String`: Allows to specify a scene which is opened while autocompletion is performed. If this is not set the test runner will search for a `.tscn` file with the same basename as the GDScript file. If that isn't found either, autocompletion will behave as if no scene was opened. + +`[output]` specifies the expected results for the test. The following key are supported: + +- `include: Array`: An unordered list of suggestions that should be in the result. Each entry is one dictionary with the following keys: `display`, `insert_text`, `kind`, `location`, which correspond to the suggestion struct which is used in the code. The runner only tests against specified keys, so in most cases `display` will suffice. +- `exclude: Array`: An array of suggestions which should not be in the result. The entries take the same form as for `include`. +- `call_hint: String`: The expected call hint returned by autocompletion. +- `forced: boolean`: Whether autocompletion is expected to force opening a completion window. + +Tests will only test against entries in `[output]` that were specified. + +## Writing autocompletion tests + +To avoid failing edge cases a certain behavior needs to be tested multiple times. Some things that tests should account for: + +- All possible types: Test with all possible types that apply to the tested behavior. (For the last points testing against `SCRIPT` and `CLASS` should suffice. `CLASS` can be obtained through C#, `SCRIPT` through GDScript. Relying on autoloads to be of type `SCRIPT` is not good, since this might change in the future.) + + - `BUILTIN` + - `NATIVE` + - GDScripts (with `class_name` as well as `preload`ed) + - C# (as standin for all other language bindings) (with `class_name` as well as `preload`ed) + - Autoloads + +- Possible contexts: the completion might be placed in different places of the program. e.g: + - initializers of class members + - directly inside a suite + - assignments inside a suite + - as parameter to a call diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index f91dc83f2c..a0329eb8d2 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -34,6 +34,7 @@ #include "../gdscript_analyzer.h" #include "../gdscript_compiler.h" #include "../gdscript_parser.h" +#include "../gdscript_tokenizer_buffer.h" #include "core/config/project_settings.h" #include "core/core_globals.h" @@ -78,31 +79,30 @@ void init_autoloads() { scn.instantiate(); scn->set_path(info.path); scn->reload_from_file(); - ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Can't autoload: %s.", info.path)); + ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Failed to instantiate an autoload, can't load from path: %s.", info.path)); if (scn.is_valid()) { n = scn->instantiate(); } } else { Ref<Resource> res = ResourceLoader::load(info.path); - ERR_CONTINUE_MSG(res.is_null(), vformat("Can't autoload: %s.", info.path)); + ERR_CONTINUE_MSG(res.is_null(), vformat("Failed to instantiate an autoload, can't load from path: %s.", info.path)); Ref<Script> scr = res; if (scr.is_valid()) { StringName ibt = scr->get_instance_base_type(); bool valid_type = ClassDB::is_parent_class(ibt, "Node"); - ERR_CONTINUE_MSG(!valid_type, vformat("Script does not inherit from Node: %s.", info.path)); + ERR_CONTINUE_MSG(!valid_type, vformat("Failed to instantiate an autoload, script '%s' does not inherit from 'Node'.", info.path)); Object *obj = ClassDB::instantiate(ibt); - - ERR_CONTINUE_MSG(!obj, vformat("Cannot instance script for Autoload, expected 'Node' inheritance, got: %s.", ibt)); + ERR_CONTINUE_MSG(!obj, vformat("Failed to instantiate an autoload, cannot instantiate '%s'.", ibt)); n = Object::cast_to<Node>(obj); n->set_script(scr); } } - ERR_CONTINUE_MSG(!n, vformat("Path in autoload not a node or script: %s.", info.path)); + ERR_CONTINUE_MSG(!n, vformat("Failed to instantiate an autoload, path is not pointing to a scene or a script: %s.", info.path)); n->set_name(info.name); for (int i = 0; i < ScriptServer::get_language_count(); i++) { @@ -132,10 +132,11 @@ void finish_language() { StringName GDScriptTestRunner::test_function_name; -GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_language, bool p_print_filenames) { +GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_language, bool p_print_filenames, bool p_use_binary_tokens) { test_function_name = StaticCString::create("test"); do_init_languages = p_init_language; print_filenames = p_print_filenames; + binary_tokens = p_use_binary_tokens; source_dir = p_source_dir; if (!source_dir.ends_with("/")) { @@ -267,7 +268,7 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) { while (!next.is_empty()) { if (dir->current_is_dir()) { - if (next == "." || next == "..") { + if (next == "." || next == ".." || next == "completion" || next == "lsp") { next = dir->get_next(); continue; } @@ -278,6 +279,9 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) { if (next.ends_with(".notest.gd")) { next = dir->get_next(); continue; + } else if (binary_tokens && next.ends_with(".textonly.gd")) { + next = dir->get_next(); + continue; } else if (next.get_extension().to_lower() == "gd") { #ifndef DEBUG_ENABLED // On release builds, skip tests marked as debug only. @@ -300,6 +304,9 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) { ERR_FAIL_V_MSG(false, "Could not find output file for " + next); } GDScriptTest test(current_dir.path_join(next), current_dir.path_join(out_file), source_dir); + if (binary_tokens) { + test.set_tokenizer_mode(GDScriptTest::TOKENIZER_BUFFER); + } tests.push_back(test); } } @@ -322,24 +329,65 @@ bool GDScriptTestRunner::make_tests() { return make_tests_for_dir(dir->get_current_dir()); } -bool GDScriptTestRunner::generate_class_index() { +static bool generate_class_index_recursive(const String &p_dir) { + Error err = OK; + Ref<DirAccess> dir(DirAccess::open(p_dir, &err)); + + if (err != OK) { + return false; + } + + String current_dir = dir->get_current_dir(); + + dir->list_dir_begin(); + String next = dir->get_next(); + StringName gdscript_name = GDScriptLanguage::get_singleton()->get_name(); - for (int i = 0; i < tests.size(); i++) { - GDScriptTest test = tests[i]; - String base_type; + while (!next.is_empty()) { + if (dir->current_is_dir()) { + if (next == "." || next == ".." || next == "completion" || next == "lsp") { + next = dir->get_next(); + continue; + } + if (!generate_class_index_recursive(current_dir.path_join(next))) { + return false; + } + } else { + if (!next.ends_with(".gd")) { + next = dir->get_next(); + continue; + } + String base_type; + String source_file = current_dir.path_join(next); + String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(source_file, &base_type); + if (class_name.is_empty()) { + next = dir->get_next(); + continue; + } + ERR_FAIL_COND_V_MSG(ScriptServer::is_global_class(class_name), false, + "Class name '" + class_name + "' from " + source_file + " is already used in " + ScriptServer::get_global_class_path(class_name)); - String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(test.get_source_file(), &base_type); - if (class_name.is_empty()) { - continue; + ScriptServer::add_global_class(class_name, base_type, gdscript_name, source_file); } - ERR_FAIL_COND_V_MSG(ScriptServer::is_global_class(class_name), false, - "Class name '" + class_name + "' from " + test.get_source_file() + " is already used in " + ScriptServer::get_global_class_path(class_name)); - ScriptServer::add_global_class(class_name, base_type, gdscript_name, test.get_source_file()); + next = dir->get_next(); } + + dir->list_dir_end(); + return true; } +bool GDScriptTestRunner::generate_class_index() { + Error err = OK; + Ref<DirAccess> dir(DirAccess::open(source_dir, &err)); + + ERR_FAIL_COND_V_MSG(err != OK, false, "Could not open specified test directory."); + + source_dir = dir->get_current_dir() + "/"; // Make it absolute path. + return generate_class_index_recursive(dir->get_current_dir()); +} + GDScriptTest::GDScriptTest(const String &p_source_path, const String &p_output_path, const String &p_base_dir) { source_file = p_source_path; output_file = p_output_path; @@ -485,7 +533,15 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { Ref<GDScript> script; script.instantiate(); script->set_path(source_file); - err = script->load_source_code(source_file); + if (tokenizer_mode == TOKENIZER_TEXT) { + err = script->load_source_code(source_file); + } else { + String code = FileAccess::get_file_as_string(source_file, &err); + if (!err) { + Vector<uint8_t> buffer = GDScriptTokenizerBuffer::parse_code_string(code, GDScriptTokenizerBuffer::COMPRESS_ZSTD); + script->set_binary_tokens_source(buffer); + } + } if (err != OK) { enable_stdout(); result.status = GDTEST_LOAD_ERROR; @@ -495,7 +551,11 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { // Test parsing. GDScriptParser parser; - err = parser.parse(script->get_source_code(), source_file, false); + if (tokenizer_mode == TOKENIZER_TEXT) { + err = parser.parse(script->get_source_code(), source_file, false); + } else { + err = parser.parse_binary(script->get_binary_tokens_source(), source_file); + } if (err != OK) { enable_stdout(); result.status = GDTEST_PARSER_ERROR; @@ -584,7 +644,14 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) { add_print_handler(&_print_handler); add_error_handler(&_error_handler); - script->reload(); + err = script->reload(); + if (err) { + enable_stdout(); + result.status = GDTEST_LOAD_ERROR; + result.output = ""; + result.passed = false; + ERR_FAIL_V_MSG(result, "\nCould not reload script: '" + source_file + "'"); + } // Create object instance for test. Object *obj = ClassDB::instantiate(script->get_native()->get_name()); diff --git a/modules/gdscript/tests/gdscript_test_runner.h b/modules/gdscript/tests/gdscript_test_runner.h index b1190604ad..57e3ac86f9 100644 --- a/modules/gdscript/tests/gdscript_test_runner.h +++ b/modules/gdscript/tests/gdscript_test_runner.h @@ -62,6 +62,11 @@ public: bool passed; }; + enum TokenizerMode { + TOKENIZER_TEXT, + TOKENIZER_BUFFER, + }; + private: struct ErrorHandlerData { TestResult *result = nullptr; @@ -79,6 +84,8 @@ private: PrintHandlerList _print_handler; ErrorHandlerList _error_handler; + TokenizerMode tokenizer_mode = TOKENIZER_TEXT; + void enable_stdout(); void disable_stdout(); bool check_output(const String &p_output) const; @@ -96,6 +103,9 @@ public: const String get_source_relative_filepath() const { return source_file.trim_prefix(base_dir); } const String &get_output_file() const { return output_file; } + void set_tokenizer_mode(TokenizerMode p_tokenizer_mode) { tokenizer_mode = p_tokenizer_mode; } + TokenizerMode get_tokenizer_mode() const { return tokenizer_mode; } + GDScriptTest(const String &p_source_path, const String &p_output_path, const String &p_base_dir); GDScriptTest() : GDScriptTest(String(), String(), String()) {} // Needed to use in Vector. @@ -108,6 +118,7 @@ class GDScriptTestRunner { bool is_generating = false; bool do_init_languages = false; bool print_filenames; // Whether filenames should be printed when generated/running tests + bool binary_tokens; // Test with buffer tokenizer. bool make_tests(); bool make_tests_for_dir(const String &p_dir); @@ -120,7 +131,7 @@ public: int run_tests(); bool generate_outputs(); - GDScriptTestRunner(const String &p_source_dir, bool p_init_language, bool p_print_filenames = false); + GDScriptTestRunner(const String &p_source_dir, bool p_init_language, bool p_print_filenames = false, bool p_use_binary_tokens = false); ~GDScriptTestRunner(); }; diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h index 5fd7d942d2..b2289ef9cc 100644 --- a/modules/gdscript/tests/gdscript_test_runner_suite.h +++ b/modules/gdscript/tests/gdscript_test_runner_suite.h @@ -37,13 +37,13 @@ namespace GDScriptTests { +// TODO: Handle some cases failing on release builds. See: https://github.com/godotengine/godot/pull/88452 +#ifdef TOOLS_ENABLED TEST_SUITE("[Modules][GDScript]") { - // GDScript 2.0 is still under heavy construction. - // Allow the tests to fail, but do not ignore errors during development. - // Update the scripts and expected output as needed. TEST_CASE("Script compilation and runtime") { bool print_filenames = OS::get_singleton()->get_cmdline_args().find("--print-filenames") != nullptr; - GDScriptTestRunner runner("modules/gdscript/tests/scripts", true, print_filenames); + bool use_binary_tokens = OS::get_singleton()->get_cmdline_args().find("--use-binary-tokens") != nullptr; + GDScriptTestRunner runner("modules/gdscript/tests/scripts", true, print_filenames, use_binary_tokens); int fail_count = runner.run_tests(); INFO("Make sure `*.out` files have expected results."); REQUIRE_MESSAGE(fail_count == 0, "All GDScript tests should pass."); @@ -70,6 +70,7 @@ func _init(): ref_counted->set_script(gdscript); CHECK_MESSAGE(int(ref_counted->get_meta("result")) == 42, "The script should assign object metadata successfully."); } +#endif // TOOLS_ENABLED TEST_CASE("[Modules][GDScript] Validate built-in API") { GDScriptLanguage *lang = GDScriptLanguage::get_singleton(); diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out index 73a54d7820..a6a3973255 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants.out @@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR >> on function: test() >> analyzer/errors/outer_class_constants.gd >> 8 ->> Invalid get index 'OUTER_CONST' (on base: 'GDScript'). +>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'GDScript'. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out index 92e7b9316e..70fdc5b62c 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_constants_as_variant.out @@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR >> on function: test() >> analyzer/errors/outer_class_constants_as_variant.gd >> 9 ->> Invalid get index 'OUTER_CONST' (on base: 'GDScript'). +>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'GDScript'. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out index 892f8e2c3f..6632f056bd 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants.out @@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR >> on function: test() >> analyzer/errors/outer_class_instance_constants.gd >> 8 ->> Invalid get index 'OUTER_CONST' (on base: 'RefCounted (Inner)'). +>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'RefCounted (Inner)'. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out index 8257e74f57..0459b756d1 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/outer_class_instance_constants_as_variant.out @@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR >> on function: test() >> analyzer/errors/outer_class_instance_constants_as_variant.gd >> 9 ->> Invalid get index 'OUTER_CONST' (on base: 'RefCounted (Inner)'). +>> Invalid access to property or key 'OUTER_CONST' on a base object of type 'RefCounted (Inner)'. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda.gd b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda.gd new file mode 100644 index 0000000000..a98f69f3ac --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda.gd @@ -0,0 +1,14 @@ +# GH-83468 + +func non_static_func(): + pass + +static func static_func(): + var f := func (): + var g := func (): + non_static_func() + g.call() + f.call() + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda.out b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda.out new file mode 100644 index 0000000000..b78f131345 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot call non-static function "non_static_func()" from static function "static_func()". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda_param.gd b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda_param.gd new file mode 100644 index 0000000000..7af9ff274c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda_param.gd @@ -0,0 +1,15 @@ +# GH-83468 + +func non_static_func(): + pass + +static func static_func( + f := func (): + var g := func (): + non_static_func() + g.call() +): + f.call() + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda_param.out b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda_param.out new file mode 100644 index 0000000000..b78f131345 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_func_call_non_static_in_lambda_param.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot call non-static function "non_static_func()" from static function "static_func()". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda.gd b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda.gd new file mode 100644 index 0000000000..5130973bd2 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda.gd @@ -0,0 +1,14 @@ +# GH-83468 + +func non_static_func(): + pass + +static var static_var = func (): + var f := func (): + var g := func (): + non_static_func() + g.call() + f.call() + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda.out b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda.out new file mode 100644 index 0000000000..c0308c81f3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot call non-static function "non_static_func()" from a static variable initializer. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda_setter.gd b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda_setter.gd new file mode 100644 index 0000000000..2d15b4e3e5 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda_setter.gd @@ -0,0 +1,15 @@ +# GH-83468 + +func non_static_func(): + pass + +static var static_var: + set(_value): + var f := func (): + var g := func (): + non_static_func() + g.call() + f.call() + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda_setter.out b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda_setter.out new file mode 100644 index 0000000000..cdf3ab2aeb --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_call_non_static_in_lambda_setter.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot call non-static function "non_static_func()" from static function "@static_var_setter()". diff --git a/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_non_static_call.out b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_non_static_call.out index f1e9ec34f2..81554ec707 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_non_static_call.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/static_var_init_non_static_call.out @@ -1,2 +1,2 @@ GDTEST_ANALYZER_ERROR -Cannot call non-static function "non_static()" for static variable initializer. +Cannot call non-static function "non_static()" from a static variable initializer. diff --git a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd index dafd2ec0c8..39f490c4b3 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.gd @@ -4,14 +4,13 @@ enum MyEnum {A, B, C} const Utils = preload("../../utils.notest.gd") -@export var x1 = MyEnum -@export var x2 = MyEnum.A -@export var x3 := MyEnum -@export var x4 := MyEnum.A -@export var x5: MyEnum +@export var test_1 = MyEnum +@export var test_2 = MyEnum.A +@export var test_3 := MyEnum +@export var test_4 := MyEnum.A +@export var test_5: MyEnum func test(): for property in get_property_list(): - if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE: - print(Utils.get_property_signature(property)) - print(" ", Utils.get_property_additional_info(property)) + if str(property.name).begins_with("test_"): + Utils.print_property_extended_info(property) diff --git a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out index f1a13f1045..505af5f1f3 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out +++ b/modules/gdscript/tests/scripts/analyzer/features/export_enum_as_dictionary.out @@ -1,11 +1,11 @@ GDTEST_OK -@export var x1: Dictionary +var test_1: Dictionary hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE -@export var x2: TestExportEnumAsDictionary.MyEnum +var test_2: TestExportEnumAsDictionary.MyEnum hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM -@export var x3: Dictionary +var test_3: Dictionary hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE -@export var x4: TestExportEnumAsDictionary.MyEnum +var test_4: TestExportEnumAsDictionary.MyEnum hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM -@export var x5: TestExportEnumAsDictionary.MyEnum +var test_5: TestExportEnumAsDictionary.MyEnum hint=ENUM hint_string="A:0,B:1,C:2" usage=DEFAULT|SCRIPT_VARIABLE|CLASS_IS_ENUM diff --git a/modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.cfg b/modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.cfg new file mode 100644 index 0000000000..27e695d245 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "autoplay"}, +] diff --git a/modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.gd b/modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.gd new file mode 100644 index 0000000000..d41bbb970c --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/get_node/get_node_member_annotated.gd @@ -0,0 +1,6 @@ +extends Node + +var test: AnimationPlayer = $AnimationPlayer + +func _ready(): + test.➡ diff --git a/modules/gdscript/tests/scripts/lsp/class.notest.gd b/modules/gdscript/tests/scripts/lsp/class.gd index 53d0b14d72..53d0b14d72 100644 --- a/modules/gdscript/tests/scripts/lsp/class.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/class.gd diff --git a/modules/gdscript/tests/scripts/lsp/enums.notest.gd b/modules/gdscript/tests/scripts/lsp/enums.gd index 38b9ec110a..38b9ec110a 100644 --- a/modules/gdscript/tests/scripts/lsp/enums.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/enums.gd diff --git a/modules/gdscript/tests/scripts/lsp/indentation.notest.gd b/modules/gdscript/tests/scripts/lsp/indentation.gd index c25d73a719..c25d73a719 100644 --- a/modules/gdscript/tests/scripts/lsp/indentation.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/indentation.gd diff --git a/modules/gdscript/tests/scripts/lsp/lambdas.notest.gd b/modules/gdscript/tests/scripts/lsp/lambdas.gd index 6f5d468eea..6f5d468eea 100644 --- a/modules/gdscript/tests/scripts/lsp/lambdas.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/lambdas.gd diff --git a/modules/gdscript/tests/scripts/lsp/local_variables.notest.gd b/modules/gdscript/tests/scripts/lsp/local_variables.gd index b6cc46f7da..b6cc46f7da 100644 --- a/modules/gdscript/tests/scripts/lsp/local_variables.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/local_variables.gd diff --git a/modules/gdscript/tests/scripts/lsp/properties.notest.gd b/modules/gdscript/tests/scripts/lsp/properties.gd index 8dfaee2e5b..8dfaee2e5b 100644 --- a/modules/gdscript/tests/scripts/lsp/properties.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/properties.gd diff --git a/modules/gdscript/tests/scripts/lsp/scopes.notest.gd b/modules/gdscript/tests/scripts/lsp/scopes.gd index 20b8fb9bd7..20b8fb9bd7 100644 --- a/modules/gdscript/tests/scripts/lsp/scopes.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/scopes.gd diff --git a/modules/gdscript/tests/scripts/lsp/shadowing_initializer.notest.gd b/modules/gdscript/tests/scripts/lsp/shadowing_initializer.gd index 338000fa0e..338000fa0e 100644 --- a/modules/gdscript/tests/scripts/lsp/shadowing_initializer.notest.gd +++ b/modules/gdscript/tests/scripts/lsp/shadowing_initializer.gd diff --git a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.gd b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.textonly.gd index 9ad77f1432..9ad77f1432 100644 --- a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.gd +++ b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.textonly.gd diff --git a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.textonly.out index 31bed2dbc7..31bed2dbc7 100644 --- a/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.out +++ b/modules/gdscript/tests/scripts/parser/errors/mixing_tabs_spaces.textonly.out diff --git a/modules/gdscript/tests/scripts/parser/features/annotations.gd b/modules/gdscript/tests/scripts/parser/features/annotations.gd index 13c89a0a09..7a7d6d953e 100644 --- a/modules/gdscript/tests/scripts/parser/features/annotations.gd +++ b/modules/gdscript/tests/scripts/parser/features/annotations.gd @@ -1,48 +1,49 @@ extends Node -@export_enum("A", "B", "C") var a0 -@export_enum("A", "B", "C",) var a1 +const Utils = preload("../../utils.notest.gd") + +@export_enum("A", "B", "C") var test_1 +@export_enum("A", "B", "C",) var test_2 @export_enum( "A", "B", "C" -) var a2 +) var test_3 @export_enum( "A", "B", "C", -) var a3 +) var test_4 @export -var a4: int +var test_5: int @export() -var a5: int +var test_6: int -@export() var a6: int -@warning_ignore("onready_with_export") @onready @export var a7: int -@warning_ignore("onready_with_export") @onready() @export() var a8: int +@export() var test_7: int = 42 +@warning_ignore("onready_with_export") @onready @export var test_8: int = 42 +@warning_ignore("onready_with_export") @onready() @export() var test_9: int = 42 @warning_ignore("onready_with_export") @onready @export -var a9: int +var test_10: int = 42 @warning_ignore("onready_with_export") @onready() @export() -var a10: int +var test_11: int = 42 @warning_ignore("onready_with_export") @onready() @export() -var a11: int - +var test_12: int = 42 func test(): for property in get_property_list(): - if property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE: - print(property) + if str(property.name).begins_with("test_"): + Utils.print_property_extended_info(property, self) diff --git a/modules/gdscript/tests/scripts/parser/features/annotations.out b/modules/gdscript/tests/scripts/parser/features/annotations.out index 3af0436c53..2ba9dd7496 100644 --- a/modules/gdscript/tests/scripts/parser/features/annotations.out +++ b/modules/gdscript/tests/scripts/parser/features/annotations.out @@ -1,13 +1,25 @@ GDTEST_OK -{ "name": "a0", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 } -{ "name": "a1", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 } -{ "name": "a2", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 } -{ "name": "a3", "class_name": &"", "type": 2, "hint": 2, "hint_string": "A,B,C", "usage": 4102 } -{ "name": "a4", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a5", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a6", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a7", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a8", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a9", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a10", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "a11", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } +var test_1: int = null + hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE +var test_2: int = null + hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE +var test_3: int = null + hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE +var test_4: int = null + hint=ENUM hint_string="A,B,C" usage=DEFAULT|SCRIPT_VARIABLE +var test_5: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_6: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_7: int = 42 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_8: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_9: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_10: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_11: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_12: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE diff --git a/modules/gdscript/tests/scripts/parser/features/export_enum.gd b/modules/gdscript/tests/scripts/parser/features/export_enum.gd index 9b2c22dea1..4f2a43f4fe 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_enum.gd +++ b/modules/gdscript/tests/scripts/parser/features/export_enum.gd @@ -1,15 +1,16 @@ -@export_enum("Red", "Green", "Blue") var untyped +const Utils = preload("../../utils.notest.gd") -@export_enum("Red", "Green", "Blue") var weak_int = 0 -@export_enum("Red", "Green", "Blue") var weak_string = "" +@export_enum("Red", "Green", "Blue") var test_untyped -@export_enum("Red", "Green", "Blue") var hard_int: int -@export_enum("Red", "Green", "Blue") var hard_string: String +@export_enum("Red", "Green", "Blue") var test_weak_int = 0 +@export_enum("Red", "Green", "Blue") var test_weak_string = "" -@export_enum("Red:10", "Green:20", "Blue:30") var with_values +@export_enum("Red", "Green", "Blue") var test_hard_int: int +@export_enum("Red", "Green", "Blue") var test_hard_string: String + +@export_enum("Red:10", "Green:20", "Blue:30") var test_with_values func test(): for property in get_property_list(): - if property.name in ["untyped", "weak_int", "weak_string", "hard_int", - "hard_string", "with_values"]: - prints(property.name, property.type, property.hint_string) + if str(property.name).begins_with("test_"): + Utils.print_property_extended_info(property, self) diff --git a/modules/gdscript/tests/scripts/parser/features/export_enum.out b/modules/gdscript/tests/scripts/parser/features/export_enum.out index 330b7eaf01..43f5e197ad 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_enum.out +++ b/modules/gdscript/tests/scripts/parser/features/export_enum.out @@ -1,7 +1,13 @@ GDTEST_OK -untyped 2 Red,Green,Blue -weak_int 2 Red,Green,Blue -weak_string 4 Red,Green,Blue -hard_int 2 Red,Green,Blue -hard_string 4 Red,Green,Blue -with_values 2 Red:10,Green:20,Blue:30 +var test_untyped: int = null + hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE +var test_weak_int: int = 0 + hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE +var test_weak_string: String = "" + hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE +var test_hard_int: int = 0 + hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE +var test_hard_string: String = "" + hint=ENUM hint_string="Red,Green,Blue" usage=DEFAULT|SCRIPT_VARIABLE +var test_with_values: int = null + hint=ENUM hint_string="Red:10,Green:20,Blue:30" usage=DEFAULT|SCRIPT_VARIABLE diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.gd index c9d05a7e68..2a218774de 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.gd +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.gd @@ -1,23 +1,22 @@ extends Node -@export var example = 99 -@export_range(0, 100) var example_range = 100 -@export_range(0, 100, 1) var example_range_step = 101 -@export_range(0, 100, 1, "or_greater") var example_range_step_or_greater = 102 +const Utils = preload("../../utils.notest.gd") -@export var color: Color -@export_color_no_alpha var color_no_alpha: Color -@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var nodepath := ^"hello" -@export var node: Node -@export var node_array: Array[Node] +@export var test_weak_int = 1 +@export var test_hard_int: int = 2 +@export_storage var test_storage_untyped +@export_storage var test_storage_weak_int = 3 # Property info still `Variant`, unlike `@export`. +@export_storage var test_storage_hard_int: int = 4 +@export_range(0, 100) var test_range = 100 +@export_range(0, 100, 1) var test_range_step = 101 +@export_range(0, 100, 1, "or_greater") var test_range_step_or_greater = 102 +@export var test_color: Color +@export_color_no_alpha var test_color_no_alpha: Color +@export_node_path("Sprite2D", "Sprite3D", "Control", "Node") var test_node_path := ^"hello" +@export var test_node: Node +@export var test_node_array: Array[Node] func test(): - print(example) - print(example_range) - print(example_range_step) - print(example_range_step_or_greater) - print(color) - print(color_no_alpha) - print(nodepath) - print(node) - print(var_to_str(node_array)) + for property in get_property_list(): + if str(property.name).begins_with("test_"): + Utils.print_property_extended_info(property, self) diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out index 5430c975f4..baadcd4ee8 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.out +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out @@ -1,10 +1,27 @@ GDTEST_OK -99 -100 -101 -102 -(0, 0, 0, 1) -(0, 0, 0, 1) -hello -<null> -Array[Node]([]) +var test_weak_int: int = 1 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_hard_int: int = 2 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +var test_storage_untyped: Variant = null + hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT +var test_storage_weak_int: Variant = 3 + hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE|NIL_IS_VARIANT +var test_storage_hard_int: int = 4 + hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE +var test_range: int = 100 + hint=RANGE hint_string="0,100" usage=DEFAULT|SCRIPT_VARIABLE +var test_range_step: int = 101 + hint=RANGE hint_string="0,100,1" usage=DEFAULT|SCRIPT_VARIABLE +var test_range_step_or_greater: int = 102 + hint=RANGE hint_string="0,100,1,or_greater" usage=DEFAULT|SCRIPT_VARIABLE +var test_color: Color = Color(0, 0, 0, 1) + hint=NONE hint_string="Color" usage=DEFAULT|SCRIPT_VARIABLE +var test_color_no_alpha: Color = Color(0, 0, 0, 1) + hint=COLOR_NO_ALPHA hint_string="" usage=DEFAULT|SCRIPT_VARIABLE +var test_node_path: NodePath = NodePath("hello") + hint=NODE_PATH_VALID_TYPES hint_string="Sprite2D,Sprite3D,Control,Node" usage=DEFAULT|SCRIPT_VARIABLE +var test_node: Node = null + hint=NODE_TYPE hint_string="Node" usage=DEFAULT|SCRIPT_VARIABLE +var test_node_array: Array = Array[Node]([]) + hint=TYPE_STRING hint_string="24/34:Node" usage=DEFAULT|SCRIPT_VARIABLE diff --git a/modules/gdscript/tests/scripts/parser/features/is_not_operator.gd b/modules/gdscript/tests/scripts/parser/features/is_not_operator.gd new file mode 100644 index 0000000000..b744e6170b --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/is_not_operator.gd @@ -0,0 +1,11 @@ +func test(): + var i: Variant = 123 + var s: Variant = "str" + prints(i is int, i is not int) + prints(s is int, s is not int) + + var a: Variant = false + var b: Variant = true + prints(a == b is int, a == b is not int) + prints(a == (b is int), a == (b is not int)) + prints((a == b) is int, (a == b) is not int) diff --git a/modules/gdscript/tests/scripts/parser/features/is_not_operator.out b/modules/gdscript/tests/scripts/parser/features/is_not_operator.out new file mode 100644 index 0000000000..f0535f9c83 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/is_not_operator.out @@ -0,0 +1,6 @@ +GDTEST_OK +true false +false true +true false +true false +false true diff --git a/modules/gdscript/tests/scripts/parser/features/multiline_if.gd b/modules/gdscript/tests/scripts/parser/features/multiline_if.gd index 86152f4543..7b82d9b1da 100644 --- a/modules/gdscript/tests/scripts/parser/features/multiline_if.gd +++ b/modules/gdscript/tests/scripts/parser/features/multiline_if.gd @@ -9,6 +9,7 @@ func test(): # Alternatively, backslashes can be used. if 1 == 1 \ + \ and 2 == 2 and \ 3 == 3: pass diff --git a/modules/gdscript/tests/scripts/parser/features/property_setter_getter.gd b/modules/gdscript/tests/scripts/parser/features/property_setter_getter.gd index 9e4b360fb2..82616ee3cf 100644 --- a/modules/gdscript/tests/scripts/parser/features/property_setter_getter.gd +++ b/modules/gdscript/tests/scripts/parser/features/property_setter_getter.gd @@ -6,6 +6,9 @@ var property: set(value): _backing = value - 1000 +var property_2: + get(): # Allow parentheses. + return 123 func test(): print("Not using self:") @@ -35,3 +38,5 @@ func test(): self.property = 5000 print(self.property) print(self._backing) + + print(property_2) diff --git a/modules/gdscript/tests/scripts/parser/features/property_setter_getter.out b/modules/gdscript/tests/scripts/parser/features/property_setter_getter.out index 560e0c3bd7..23f98f44ab 100644 --- a/modules/gdscript/tests/scripts/parser/features/property_setter_getter.out +++ b/modules/gdscript/tests/scripts/parser/features/property_setter_getter.out @@ -17,3 +17,4 @@ Using self: -50 5000 4000 +123 diff --git a/modules/gdscript/tests/scripts/project.godot b/modules/gdscript/tests/scripts/project.godot index 25b49c0abd..c500ef443d 100644 --- a/modules/gdscript/tests/scripts/project.godot +++ b/modules/gdscript/tests/scripts/project.godot @@ -3,7 +3,7 @@ ; It also helps for opening Godot to edit the scripts, but please don't ; let the editor changes be saved. -config_version=4 +config_version=5 [application] diff --git a/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out b/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out index 2a97eaea44..c524a1ae6b 100644 --- a/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out +++ b/modules/gdscript/tests/scripts/runtime/errors/constant_array_is_deep.out @@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR >> on function: test() >> runtime/errors/constant_array_is_deep.gd >> 6 ->> Invalid set index '0' (on base: 'Dictionary') with value of type 'int' +>> Invalid assignment of property or key '0' with value of type 'int' on a base object of type 'Dictionary'. diff --git a/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out b/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out index c807db6b0c..cf51b0262d 100644 --- a/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out +++ b/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.out @@ -3,4 +3,4 @@ GDTEST_RUNTIME_ERROR >> on function: test() >> runtime/errors/constant_dictionary_is_deep.gd >> 6 ->> Invalid set index '0' (on base: 'Array') with value of type 'int' +>> Invalid assignment of index '0' (on base: 'Array') with value of type 'int'. diff --git a/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.gd b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.gd new file mode 100644 index 0000000000..cb5ea827f6 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.gd @@ -0,0 +1,13 @@ +func test(): + var array: Array = [1, 2, 3] + print(array) + var array_clear: Callable = array.clear + array_clear.call() + print(array) + + var dictionary: Dictionary = {1: 2, 3: 4} + print(dictionary) + # `dictionary.clear` is treated as a key. + var dictionary_clear := Callable.create(dictionary, &"clear") + dictionary_clear.call() + print(dictionary) diff --git a/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.out b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.out new file mode 100644 index 0000000000..c12984ca37 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.out @@ -0,0 +1,5 @@ +GDTEST_OK +[1, 2, 3] +[] +{ 1: 2, 3: 4 } +{ } diff --git a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd index e46f24cc5f..0133d7fcfc 100644 --- a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd +++ b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.gd @@ -1,17 +1,17 @@ -extends RefCounted # TODO: Fix standalone annotations parsing. +const Utils = preload("../../utils.notest.gd") # GH-73843 @export_group("Resource") # GH-78252 -@export var prop_1: int -@export_category("prop_1") -@export var prop_2: int +@export var test_1: int +@export_category("test_1") +@export var test_2: int func test(): var resource := Resource.new() prints("Not shadowed:", resource.get_class()) for property in get_property_list(): - if property.name in ["prop_1", "prop_2"]: - print(property) + if str(property.name).begins_with("test_"): + Utils.print_property_extended_info(property, self) diff --git a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out index 96ae84e986..9387ec50d7 100644 --- a/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out +++ b/modules/gdscript/tests/scripts/runtime/features/export_group_no_name_conflict_with_properties.out @@ -1,5 +1,8 @@ GDTEST_OK Not shadowed: Resource -{ "name": "prop_1", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } -{ "name": "prop_1", "class_name": &"", "type": 0, "hint": 0, "hint_string": "", "usage": 128 } -{ "name": "prop_2", "class_name": &"", "type": 2, "hint": 0, "hint_string": "int", "usage": 4102 } +var test_1: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE +@export_category("test_1") + hint=NONE hint_string="" usage=CATEGORY +var test_2: int = 0 + hint=NONE hint_string="int" usage=DEFAULT|SCRIPT_VARIABLE diff --git a/modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd new file mode 100644 index 0000000000..b9746a8207 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.gd @@ -0,0 +1,10 @@ +func test(): + var node := Node.new() + var callable: Callable = node.free + callable.call() + print(node) + + node = Node.new() + callable = node["free"] + callable.call() + print(node) diff --git a/modules/gdscript/tests/scripts/runtime/features/free_is_callable.out b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.out new file mode 100644 index 0000000000..97bfc46d96 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/free_is_callable.out @@ -0,0 +1,3 @@ +GDTEST_OK +<Freed Object> +<Freed Object> diff --git a/modules/gdscript/tests/scripts/runtime/features/match_test_null.gd b/modules/gdscript/tests/scripts/runtime/features/match_test_null.gd new file mode 100644 index 0000000000..9bb57b68ee --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/match_test_null.gd @@ -0,0 +1,6 @@ +func test(): + match null: + null: + print('null matched') + _: + pass diff --git a/modules/gdscript/tests/scripts/runtime/features/match_test_null.out b/modules/gdscript/tests/scripts/runtime/features/match_test_null.out new file mode 100644 index 0000000000..7640cf42ab --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/match_test_null.out @@ -0,0 +1,2 @@ +GDTEST_OK +null matched diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info.gd b/modules/gdscript/tests/scripts/runtime/features/member_info.gd index 805ea42455..6fe9647b4d 100644 --- a/modules/gdscript/tests/scripts/runtime/features/member_info.gd +++ b/modules/gdscript/tests/scripts/runtime/features/member_info.gd @@ -60,7 +60,7 @@ func test(): var script: Script = get_script() for property in script.get_property_list(): if str(property.name).begins_with("test_"): - print(Utils.get_property_signature(property, true)) + print(Utils.get_property_signature(property, null, true)) for property in get_property_list(): if str(property.name).begins_with("test_"): print(Utils.get_property_signature(property)) diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info.out b/modules/gdscript/tests/scripts/runtime/features/member_info.out index 3a91507da9..7c826ac05a 100644 --- a/modules/gdscript/tests/scripts/runtime/features/member_info.out +++ b/modules/gdscript/tests/scripts/runtime/features/member_info.out @@ -6,13 +6,13 @@ static var test_static_var_hard_int: int var test_var_untyped: Variant var test_var_weak_null: Variant var test_var_weak_int: Variant -@export var test_var_weak_int_exported: int +var test_var_weak_int_exported: int var test_var_weak_variant_type: Variant -@export var test_var_weak_variant_type_exported: Variant.Type +var test_var_weak_variant_type_exported: Variant.Type var test_var_hard_variant: Variant var test_var_hard_int: int var test_var_hard_variant_type: Variant.Type -@export var test_var_hard_variant_type_exported: Variant.Type +var test_var_hard_variant_type_exported: Variant.Type var test_var_hard_node_process_mode: Node.ProcessMode var test_var_hard_my_enum: TestMemberInfo.MyEnum var test_var_hard_array: Array diff --git a/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd b/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd index d0cbeeab85..563c6ce569 100644 --- a/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd +++ b/modules/gdscript/tests/scripts/runtime/features/member_info_inheritance.gd @@ -30,7 +30,7 @@ func test(): var b := B.new() for property in (B as GDScript).get_property_list(): if str(property.name).begins_with("test_"): - print(Utils.get_property_signature(property, true)) + print(Utils.get_property_signature(property, null, true)) print("---") for property in b.get_property_list(): if str(property.name).begins_with("test_"): diff --git a/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.gd b/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.gd index f6aa58737f..97e9da3b26 100644 --- a/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.gd +++ b/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.gd @@ -1,12 +1,18 @@ -# GH-79521 +# GH-79521, GH-86032 class_name TestStaticMethodAsCallable static func static_func() -> String: return "Test" +static func another_static_func(): + prints("another_static_func:", static_func.call(), static_func.is_valid()) + func test(): var a: Callable = TestStaticMethodAsCallable.static_func var b: Callable = static_func prints(a.call(), a.is_valid()) prints(b.call(), b.is_valid()) + @warning_ignore("static_called_on_instance") + another_static_func() + TestStaticMethodAsCallable.another_static_func() diff --git a/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.out b/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.out index e6d461b8f9..2b773ce8ee 100644 --- a/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.out +++ b/modules/gdscript/tests/scripts/runtime/features/static_method_as_callable.out @@ -1,3 +1,5 @@ GDTEST_OK Test true Test true +another_static_func: Test true +another_static_func: Test true diff --git a/modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.gd b/modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.gd new file mode 100644 index 0000000000..11f064bb83 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.gd @@ -0,0 +1,10 @@ +func test(): + print(print) + print(len) + + prints.callv([1, 2, 3]) + print(mini.call(1, 2)) + print(len.bind("abc").call()) + + const ABSF = absf + print(ABSF.call(-1.2)) diff --git a/modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.out b/modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.out new file mode 100644 index 0000000000..91549b9345 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/utility_func_as_callable.out @@ -0,0 +1,7 @@ +GDTEST_OK +@GlobalScope::print (Callable) +@GDScript::len (Callable) +1 2 3 +1 +3 +1.2 diff --git a/modules/gdscript/tests/scripts/utils.notest.gd b/modules/gdscript/tests/scripts/utils.notest.gd index 781843b8e2..31818c9d01 100644 --- a/modules/gdscript/tests/scripts/utils.notest.gd +++ b/modules/gdscript/tests/scripts/utils.notest.gd @@ -20,24 +20,32 @@ static func get_type(property: Dictionary, is_return: bool = false) -> String: return type_string(property.type) -static func get_property_signature(property: Dictionary, is_static: bool = false) -> String: +static func get_property_signature(property: Dictionary, base: Object = null, is_static: bool = false) -> String: + if property.usage & PROPERTY_USAGE_CATEGORY: + return '@export_category("%s")' % str(property.name).c_escape() + if property.usage & PROPERTY_USAGE_GROUP: + return '@export_group("%s")' % str(property.name).c_escape() + if property.usage & PROPERTY_USAGE_SUBGROUP: + return '@export_subgroup("%s")' % str(property.name).c_escape() + var result: String = "" if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE): printerr("Missing `PROPERTY_USAGE_SCRIPT_VARIABLE` flag.") - if property.usage & PROPERTY_USAGE_DEFAULT: - result += "@export " if is_static: result += "static " result += "var " + property.name + ": " + get_type(property) + if is_instance_valid(base): + result += " = " + var_to_str(base.get(property.name)) return result -static func get_property_additional_info(property: Dictionary) -> String: - return 'hint=%s hint_string="%s" usage=%s' % [ +static func print_property_extended_info(property: Dictionary, base: Object = null, is_static: bool = false) -> void: + print(get_property_signature(property, base, is_static)) + print(' hint=%s hint_string="%s" usage=%s' % [ get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"), str(property.hint_string).c_escape(), get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""), - ] + ]) static func get_method_signature(method: Dictionary, is_signal: bool = false) -> String: @@ -153,7 +161,6 @@ static func get_property_usage_string(usage: int) -> String: return "PROPERTY_USAGE_NONE" const FLAGS: Array[Array] = [ - [PROPERTY_USAGE_DEFAULT, "PROPERTY_USAGE_DEFAULT"], [PROPERTY_USAGE_STORAGE, "PROPERTY_USAGE_STORAGE"], [PROPERTY_USAGE_EDITOR, "PROPERTY_USAGE_EDITOR"], [PROPERTY_USAGE_INTERNAL, "PROPERTY_USAGE_INTERNAL"], @@ -187,6 +194,10 @@ static func get_property_usage_string(usage: int) -> String: var result: String = "" + if (usage & PROPERTY_USAGE_DEFAULT) == PROPERTY_USAGE_DEFAULT: + result += "PROPERTY_USAGE_DEFAULT|" + usage &= ~PROPERTY_USAGE_DEFAULT + for flag in FLAGS: if usage & flag[0]: result += flag[1] + "|" diff --git a/modules/gdscript/tests/test_completion.h b/modules/gdscript/tests/test_completion.h new file mode 100644 index 0000000000..fd6b5321e6 --- /dev/null +++ b/modules/gdscript/tests/test_completion.h @@ -0,0 +1,203 @@ +/**************************************************************************/ +/* test_completion.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef TEST_COMPLETION_H +#define TEST_COMPLETION_H + +#ifdef TOOLS_ENABLED + +#include "core/io/config_file.h" +#include "core/io/dir_access.h" +#include "core/io/file_access.h" +#include "core/object/script_language.h" +#include "core/variant/dictionary.h" +#include "core/variant/variant.h" +#include "gdscript_test_runner.h" +#include "modules/modules_enabled.gen.h" // For mono. +#include "scene/resources/packed_scene.h" + +#include "../gdscript.h" +#include "tests/test_macros.h" + +#include "editor/editor_settings.h" +#include "scene/theme/theme_db.h" + +namespace GDScriptTests { + +static bool match_option(const Dictionary p_expected, const ScriptLanguage::CodeCompletionOption p_got) { + if (p_expected.get("display", p_got.display) != p_got.display) { + return false; + } + if (p_expected.get("insert_text", p_got.insert_text) != p_got.insert_text) { + return false; + } + if (p_expected.get("kind", p_got.kind) != Variant(p_got.kind)) { + return false; + } + if (p_expected.get("location", p_got.location) != Variant(p_got.location)) { + return false; + } + return true; +} + +static void to_dict_list(Variant p_variant, List<Dictionary> &p_list) { + ERR_FAIL_COND(!p_variant.is_array()); + + Array arr = p_variant; + for (int i = 0; i < arr.size(); i++) { + if (arr[i].get_type() == Variant::DICTIONARY) { + p_list.push_back(arr[i]); + } + } +} + +static void test_directory(const String &p_dir) { + Error err = OK; + Ref<DirAccess> dir = DirAccess::open(p_dir, &err); + + if (err != OK) { + FAIL("Invalid test directory."); + return; + } + + String path = dir->get_current_dir(); + + dir->list_dir_begin(); + String next = dir->get_next(); + + while (!next.is_empty()) { + if (dir->current_is_dir()) { + if (next == "." || next == "..") { + next = dir->get_next(); + continue; + } + test_directory(path.path_join(next)); + } else if (next.ends_with(".gd") && !next.ends_with(".notest.gd")) { + Ref<FileAccess> acc = FileAccess::open(path.path_join(next), FileAccess::READ, &err); + + if (err != OK) { + next = dir->get_next(); + continue; + } + + String code = acc->get_as_utf8_string(); + // For ease of reading ➡ (0x27A1) acts as sentinel char instead of 0xFFFF in the files. + code = code.replace_first(String::chr(0x27A1), String::chr(0xFFFF)); + // Require pointer sentinel char in scripts. + CHECK(code.find_char(0xFFFF) != -1); + + ConfigFile conf; + if (conf.load(path.path_join(next.get_basename() + ".cfg")) != OK) { + FAIL("No config file found."); + } + +#ifndef MODULE_MONO_ENABLED + if (conf.get_value("input", "cs", false)) { + next = dir->get_next(); + continue; + } +#endif + + EditorSettings::get_singleton()->set_setting("text_editor/completion/use_single_quotes", conf.get_value("input", "use_single_quotes", false)); + + List<Dictionary> include; + to_dict_list(conf.get_value("output", "include", Array()), include); + + List<Dictionary> exclude; + to_dict_list(conf.get_value("output", "exclude", Array()), exclude); + + List<ScriptLanguage::CodeCompletionOption> options; + String call_hint; + bool forced; + + Node *owner = nullptr; + if (conf.has_section_key("input", "scene")) { + Ref<PackedScene> scene = ResourceLoader::load(conf.get_value("input", "scene"), "PackedScene"); + if (scene.is_valid()) { + owner = scene->instantiate(); + } + } else if (dir->file_exists(next.get_basename() + ".tscn")) { + Ref<PackedScene> scene = ResourceLoader::load(path.path_join(next.get_basename() + ".tscn"), "PackedScene"); + if (scene.is_valid()) { + owner = scene->instantiate(); + } + } + + GDScriptLanguage::get_singleton()->complete_code(code, path.path_join(next), owner, &options, forced, call_hint); + String contains_excluded; + for (ScriptLanguage::CodeCompletionOption &option : options) { + for (const Dictionary &E : exclude) { + if (match_option(E, option)) { + contains_excluded = option.display; + break; + } + } + if (!contains_excluded.is_empty()) { + break; + } + + for (const Dictionary &E : include) { + if (match_option(E, option)) { + include.erase(E); + break; + } + } + } + CHECK_MESSAGE(contains_excluded.is_empty(), "Autocompletion suggests illegal option '", contains_excluded, "' for '", path.path_join(next), "'."); + CHECK(include.is_empty()); + + String expected_call_hint = conf.get_value("output", "call_hint", call_hint); + bool expected_forced = conf.get_value("output", "forced", forced); + + CHECK(expected_call_hint == call_hint); + CHECK(expected_forced == forced); + + if (owner) { + memdelete(owner); + } + } + next = dir->get_next(); + } +} + +TEST_SUITE("[Modules][GDScript][Completion]") { + TEST_CASE("[Editor] Check suggestion list") { + // Set all editor settings that code completion relies on. + EditorSettings::get_singleton()->set_setting("text_editor/completion/use_single_quotes", false); + init_language("modules/gdscript/tests/scripts"); + + test_directory("modules/gdscript/tests/scripts/completion"); + } +} +} // namespace GDScriptTests + +#endif + +#endif // TEST_COMPLETION_H diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 467bedc4b2..f6965cf7cf 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -34,6 +34,7 @@ #include "../gdscript_compiler.h" #include "../gdscript_parser.h" #include "../gdscript_tokenizer.h" +#include "../gdscript_tokenizer_buffer.h" #include "core/config/project_settings.h" #include "core/io/file_access.h" @@ -50,7 +51,7 @@ namespace GDScriptTests { static void test_tokenizer(const String &p_code, const Vector<String> &p_lines) { - GDScriptTokenizer tokenizer; + GDScriptTokenizerText tokenizer; tokenizer.set_source_code(p_code); int tab_size = 4; @@ -107,6 +108,53 @@ static void test_tokenizer(const String &p_code, const Vector<String> &p_lines) print_line(current.get_name()); // Should be EOF } +static void test_tokenizer_buffer(const Vector<uint8_t> &p_buffer, const Vector<String> &p_lines); + +static void test_tokenizer_buffer(const String &p_code, const Vector<String> &p_lines) { + Vector<uint8_t> binary = GDScriptTokenizerBuffer::parse_code_string(p_code, GDScriptTokenizerBuffer::COMPRESS_NONE); + test_tokenizer_buffer(binary, p_lines); +} + +static void test_tokenizer_buffer(const Vector<uint8_t> &p_buffer, const Vector<String> &p_lines) { + GDScriptTokenizerBuffer tokenizer; + tokenizer.set_code_buffer(p_buffer); + + int tab_size = 4; +#ifdef TOOLS_ENABLED + if (EditorSettings::get_singleton()) { + tab_size = EditorSettings::get_singleton()->get_setting("text_editor/behavior/indent/size"); + } +#endif // TOOLS_ENABLED + String tab = String(" ").repeat(tab_size); + + GDScriptTokenizer::Token current = tokenizer.scan(); + while (current.type != GDScriptTokenizer::Token::TK_EOF) { + StringBuilder token; + token += " --> "; // Padding for line number. + + for (int l = current.start_line; l <= current.end_line && l <= p_lines.size(); l++) { + print_line(vformat("%04d %s", l, p_lines[l - 1]).replace("\t", tab)); + } + + token += current.get_name(); + + if (current.type == GDScriptTokenizer::Token::ERROR || current.type == GDScriptTokenizer::Token::LITERAL || current.type == GDScriptTokenizer::Token::IDENTIFIER || current.type == GDScriptTokenizer::Token::ANNOTATION) { + token += "("; + token += Variant::get_type_name(current.literal.get_type()); + token += ") "; + token += current.literal; + } + + print_line(token.as_string()); + + print_line("-------------------------------------------------------"); + + current = tokenizer.scan(); + } + + print_line(current.get_name()); // Should be EOF +} + static void test_parser(const String &p_code, const String &p_script_path, const Vector<String> &p_lines) { GDScriptParser parser; Error err = parser.parse(p_code, p_script_path, false); @@ -119,7 +167,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const } GDScriptAnalyzer analyzer(&parser); - analyzer.analyze(); + err = analyzer.analyze(); if (err != OK) { const List<GDScriptParser::ParserError> &errors = parser.get_errors(); @@ -212,7 +260,7 @@ void test(TestType p_type) { } String test = cmdlargs.back()->get(); - if (!test.ends_with(".gd")) { + if (!test.ends_with(".gd") && !test.ends_with(".gdc")) { print_line("This test expects a path to a GDScript file as its last parameter. Got: " + test); return; } @@ -255,6 +303,13 @@ void test(TestType p_type) { case TEST_TOKENIZER: test_tokenizer(code, lines); break; + case TEST_TOKENIZER_BUFFER: + if (test.ends_with(".gdc")) { + test_tokenizer_buffer(buf, lines); + } else { + test_tokenizer_buffer(code, lines); + } + break; case TEST_PARSER: test_parser(code, test, lines); break; diff --git a/modules/gdscript/tests/test_gdscript.h b/modules/gdscript/tests/test_gdscript.h index b39dfe2b5a..32f278d5ce 100644 --- a/modules/gdscript/tests/test_gdscript.h +++ b/modules/gdscript/tests/test_gdscript.h @@ -39,6 +39,7 @@ namespace GDScriptTests { enum TestType { TEST_TOKENIZER, + TEST_TOKENIZER_BUFFER, TEST_PARSER, TEST_COMPILER, TEST_BYTECODE, diff --git a/modules/gdscript/tests/test_lsp.h b/modules/gdscript/tests/test_lsp.h index e57df00e2d..6192272f80 100644 --- a/modules/gdscript/tests/test_lsp.h +++ b/modules/gdscript/tests/test_lsp.h @@ -76,7 +76,7 @@ namespace GDScriptTests { // LSP GDScript test scripts are located inside project of other GDScript tests: // Cannot reset `ProjectSettings` (singleton) -> Cannot load another workspace and resources in there. // -> Reuse GDScript test project. LSP specific scripts are then placed inside `lsp` folder. -// Access via `res://lsp/my_script.notest.gd`. +// Access via `res://lsp/my_script.gd`. const String root = "modules/gdscript/tests/scripts/"; /* @@ -394,7 +394,7 @@ func f(): Ref<GDScriptWorkspace> workspace = GDScriptLanguageProtocol::get_singleton()->get_workspace(); { - String path = "res://lsp/local_variables.notest.gd"; + String path = "res://lsp/local_variables.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -413,7 +413,7 @@ func f(): } SUBCASE("Can get correct ranges for indented variables") { - String path = "res://lsp/indentation.notest.gd"; + String path = "res://lsp/indentation.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -421,7 +421,7 @@ func f(): } SUBCASE("Can get correct ranges for scopes") { - String path = "res://lsp/scopes.notest.gd"; + String path = "res://lsp/scopes.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -429,7 +429,7 @@ func f(): } SUBCASE("Can get correct ranges for lambda") { - String path = "res://lsp/lambdas.notest.gd"; + String path = "res://lsp/lambdas.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -437,7 +437,7 @@ func f(): } SUBCASE("Can get correct ranges for inner class") { - String path = "res://lsp/class.notest.gd"; + String path = "res://lsp/class.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -445,7 +445,7 @@ func f(): } SUBCASE("Can get correct ranges for inner class") { - String path = "res://lsp/enums.notest.gd"; + String path = "res://lsp/enums.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -453,7 +453,7 @@ func f(): } SUBCASE("Can get correct ranges for shadowing & shadowed variables") { - String path = "res://lsp/shadowing_initializer.notest.gd"; + String path = "res://lsp/shadowing_initializer.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); @@ -461,7 +461,7 @@ func f(): } SUBCASE("Can get correct ranges for properties and getter/setter") { - String path = "res://lsp/properties.notest.gd"; + String path = "res://lsp/properties.gd"; assert_no_errors_in(path); String uri = workspace->get_file_uri(path); Vector<InlineTestData> all_test_data = read_tests(path); |