summaryrefslogtreecommitdiff
path: root/modules/gdscript/tests
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/tests')
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.cpp101
-rw-r--r--modules/gdscript/tests/gdscript_test_runner.h8
-rw-r--r--modules/gdscript/tests/gdscript_test_runner_suite.h4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.gd8
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.gd8
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.gd13
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.gd13
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.gd14
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.gd13
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.out5
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.gd21
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.out7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.gd13
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.out7
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.gd14
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd17
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.out3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd15
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.gd4
-rw-r--r--modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/advanced_expression_matching.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd58
-rw-r--r--modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out5
-rw-r--r--modules/gdscript/tests/scripts/parser/features/class_inheritance_access.gd40
-rw-r--r--modules/gdscript/tests/scripts/parser/features/class_inheritance_access.out16
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary.out6
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.gd6
-rw-r--r--modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/features/nested_dictionary.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/features/signal_declaration.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.gd15
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.out21
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out9
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd1
-rw-r--r--modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out2
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_use_self.gd23
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/lambda_use_self.out5
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/params_default_values.gd35
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/params_default_values.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/stringify.out6
-rw-r--r--modules/gdscript/tests/test_gdscript.cpp8
-rw-r--r--modules/gdscript/tests/test_gdscript.h4
71 files changed, 639 insertions, 57 deletions
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index d2e71efee7..de5cd10e7c 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 */
@@ -48,11 +48,11 @@
namespace GDScriptTests {
void init_autoloads() {
- OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
+ HashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list();
// First pass, add the constants so they exist before any script is loaded.
- for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) {
- const ProjectSettings::AutoloadInfo &info = E.get();
+ for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
+ const ProjectSettings::AutoloadInfo &info = E.value;
if (info.is_singleton) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -62,34 +62,32 @@ void init_autoloads() {
}
// Second pass, load into global constants.
- for (OrderedHashMap<StringName, ProjectSettings::AutoloadInfo>::Element E = autoloads.front(); E; E = E.next()) {
- const ProjectSettings::AutoloadInfo &info = E.get();
+ for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
+ const ProjectSettings::AutoloadInfo &info = E.value;
if (!info.is_singleton) {
// Skip non-singletons since we don't have a scene tree here anyway.
continue;
}
- RES res = ResourceLoader::load(info.path);
+ Ref<Resource> res = ResourceLoader::load(info.path);
ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path);
Node *n = nullptr;
- if (res->is_class("PackedScene")) {
- Ref<PackedScene> ps = res;
- n = ps->instantiate();
- } else if (res->is_class("Script")) {
- Ref<Script> script_res = res;
- StringName ibt = script_res->get_instance_base_type();
+ Ref<PackedScene> scn = res;
+ Ref<Script> script = res;
+ if (scn.is_valid()) {
+ n = scn->instantiate();
+ } else if (script.is_valid()) {
+ StringName ibt = script->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
- ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path);
+ ERR_CONTINUE_MSG(!valid_type, "Script does not inherit from Node: " + info.path);
Object *obj = ClassDB::instantiate(ibt);
- ERR_CONTINUE_MSG(obj == nullptr,
- "Cannot instance script for autoload, expected 'Node' inheritance, got: " +
- String(ibt));
+ ERR_CONTINUE_MSG(!obj, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + ".");
n = Object::cast_to<Node>(obj);
- n->set_script(script_res);
+ n->set_script(script);
}
ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path);
@@ -134,12 +132,14 @@ GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_l
if (do_init_languages) {
init_language(p_source_dir);
}
+#ifdef DEBUG_ENABLED
// Enable all warnings for GDScript, so we can test them.
ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true);
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/" + warning, true);
}
+#endif
// Enable printing to show results
_print_line_enabled = true;
@@ -153,6 +153,21 @@ GDScriptTestRunner::~GDScriptTestRunner() {
}
}
+#ifndef DEBUG_ENABLED
+static String strip_warnings(const String &p_expected) {
+ // On release builds we don't have warnings. Here we remove them from the output before comparison
+ // so it doesn't fail just because of difference in warnings.
+ String expected_no_warnings;
+ for (String line : p_expected.split("\n")) {
+ if (line.begins_with(">> ")) {
+ continue;
+ }
+ expected_no_warnings += line + "\n";
+ }
+ return expected_no_warnings.strip_edges() + "\n";
+}
+#endif
+
int GDScriptTestRunner::run_tests() {
if (!make_tests()) {
FAIL("An error occurred while making the tests.");
@@ -170,6 +185,9 @@ int GDScriptTestRunner::run_tests() {
GDScriptTest::TestResult result = test.run_test();
String expected = FileAccess::get_file_as_string(test.get_output_file());
+#ifndef DEBUG_ENABLED
+ expected = strip_warnings(expected);
+#endif
INFO(test.get_source_file());
if (!result.passed) {
INFO(expected);
@@ -211,7 +229,7 @@ bool GDScriptTestRunner::generate_outputs() {
bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) {
Error err = OK;
- DirAccessRef dir(DirAccess::open(p_dir, &err));
+ Ref<DirAccess> dir(DirAccess::open(p_dir, &err));
if (err != OK) {
return false;
@@ -233,6 +251,22 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) {
}
} else {
if (next.get_extension().to_lower() == "gd") {
+#ifndef DEBUG_ENABLED
+ // On release builds, skip tests marked as debug only.
+ Error open_err = OK;
+ Ref<FileAccess> script_file(FileAccess::open(current_dir.plus_file(next), FileAccess::READ, &open_err));
+ if (open_err != OK) {
+ ERR_PRINT(vformat(R"(Couldn't open test file "%s".)", next));
+ next = dir->get_next();
+ continue;
+ } else {
+ if (script_file->get_line() == "#debug-only") {
+ next = dir->get_next();
+ continue;
+ }
+ }
+#endif
+
String out_file = next.get_basename() + ".out";
if (!is_generating && !dir->file_exists(out_file)) {
ERR_FAIL_V_MSG(false, "Could not find output file for " + next);
@@ -252,7 +286,7 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) {
bool GDScriptTestRunner::make_tests() {
Error err = OK;
- DirAccessRef dir(DirAccess::open(source_dir, &err));
+ Ref<DirAccess> dir(DirAccess::open(source_dir, &err));
ERR_FAIL_COND_V_MSG(err != OK, false, "Could not open specified test directory.");
@@ -267,7 +301,7 @@ bool GDScriptTestRunner::generate_class_index() {
String base_type;
String class_name = GDScriptLanguage::get_singleton()->get_global_class_name(test.get_source_file(), &base_type);
- if (class_name == String()) {
+ if (class_name.is_empty()) {
continue;
}
ERR_FAIL_COND_V_MSG(ScriptServer::is_global_class(class_name), false,
@@ -362,16 +396,16 @@ void GDScriptTest::error_handler(void *p_this, const char *p_function, const cha
}
builder.append("\n>> on function: ");
- builder.append(p_function);
+ builder.append(String::utf8(p_function));
builder.append("()\n>> ");
- builder.append(String(p_file).trim_prefix(self->base_dir));
+ builder.append(String::utf8(p_file).trim_prefix(self->base_dir));
builder.append("\n>> ");
builder.append(itos(p_line));
builder.append("\n>> ");
- builder.append(p_error);
+ builder.append(String::utf8(p_error));
if (strlen(p_explanation) > 0) {
builder.append("\n>> ");
- builder.append(p_explanation);
+ builder.append(String::utf8(p_explanation));
}
builder.append("\n");
@@ -387,6 +421,10 @@ bool GDScriptTest::check_output(const String &p_output) const {
String got = p_output.strip_edges(); // TODO: may be hacky.
got += "\n"; // Make sure to insert newline for CI static checks.
+#ifndef DEBUG_ENABLED
+ expected = strip_warnings(expected);
+#endif
+
return got == expected;
}
@@ -469,6 +507,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
return result;
}
+#ifdef DEBUG_ENABLED
StringBuilder warning_string;
for (const GDScriptWarning &E : parser.get_warnings()) {
const GDScriptWarning warning = E;
@@ -482,6 +521,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
warning_string.append("\n");
}
result.output += warning_string.as_string();
+#endif
// Test compiling.
GDScriptCompiler compiler;
@@ -503,8 +543,8 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
return result;
}
// Test running.
- const Map<StringName, GDScriptFunction *>::Element *test_function_element = script->get_member_functions().find(GDScriptTestRunner::test_function_name);
- if (test_function_element == nullptr) {
+ const HashMap<StringName, GDScriptFunction *>::ConstIterator test_function_element = script->get_member_functions().find(GDScriptTestRunner::test_function_name);
+ if (!test_function_element) {
enable_stdout();
result.status = GDTEST_LOAD_ERROR;
result.output = "";
@@ -533,7 +573,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
// Call test function.
Callable::CallError call_err;
- instance->call(GDScriptTestRunner::test_function_name, nullptr, 0, call_err);
+ instance->callp(GDScriptTestRunner::test_function_name, nullptr, 0, call_err);
// Tear down output handlers.
remove_print_handler(&_print_handler);
@@ -571,7 +611,7 @@ bool GDScriptTest::generate_output() {
}
Error err = OK;
- FileAccessRef out_file = FileAccess::open(output_file, FileAccess::WRITE, &err);
+ Ref<FileAccess> out_file = FileAccess::open(output_file, FileAccess::WRITE, &err);
if (err != OK) {
return false;
}
@@ -580,7 +620,6 @@ bool GDScriptTest::generate_output() {
output += "\n"; // Make sure to insert newline for CI static checks.
out_file->store_string(output);
- out_file->close();
return true;
}
diff --git a/modules/gdscript/tests/gdscript_test_runner.h b/modules/gdscript/tests/gdscript_test_runner.h
index 98c57dc97c..d6c6419e21 100644
--- a/modules/gdscript/tests/gdscript_test_runner.h
+++ b/modules/gdscript/tests/gdscript_test_runner.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 */
@@ -63,8 +63,8 @@ public:
private:
struct ErrorHandlerData {
- TestResult *result;
- GDScriptTest *self;
+ TestResult *result = nullptr;
+ GDScriptTest *self = nullptr;
ErrorHandlerData(TestResult *p_result, GDScriptTest *p_this) {
result = p_result;
self = p_this;
diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h
index cf4e61f07d..0722fb800e 100644
--- a/modules/gdscript/tests/gdscript_test_runner_suite.h
+++ b/modules/gdscript/tests/gdscript_test_runner_suite.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 */
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.gd
new file mode 100644
index 0000000000..928c886650
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.gd
@@ -0,0 +1,10 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+enum MyOtherEnum { OTHER_ENUM_VALUE_1, OTHER_ENUM_VALUE_2 }
+
+# Different enum types can't be assigned without casting.
+var class_var: MyEnum = MyEnum.ENUM_VALUE_1
+
+func test():
+ print(class_var)
+ class_var = MyOtherEnum.OTHER_ENUM_VALUE_2
+ print(class_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.out
new file mode 100644
index 0000000000..fde7e92f8c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_assign_with_wrong_enum_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Cannot assign a value of type "MyOtherEnum (enum)" to a target of type "MyEnum (enum)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.gd
new file mode 100644
index 0000000000..03a1711d7b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.gd
@@ -0,0 +1,8 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+enum MyOtherEnum { OTHER_ENUM_VALUE_1, OTHER_ENUM_VALUE_2 }
+
+# Different enum types can't be assigned without casting.
+var class_var: MyEnum = MyOtherEnum.OTHER_ENUM_VALUE_1
+
+func test():
+ print(class_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.out
new file mode 100644
index 0000000000..b1710c798d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_class_var_init_with_wrong_enum_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Value of type "MyOtherEnum (enum)" cannot be assigned to a variable of type "MyEnum (enum)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.gd
new file mode 100644
index 0000000000..d08d3dd7b2
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.gd
@@ -0,0 +1,8 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+enum MyOtherEnum { OTHER_ENUM_VALUE_1, OTHER_ENUM_VALUE_2 }
+
+func test():
+ var local_var: MyEnum = MyEnum.ENUM_VALUE_1
+ print(local_var)
+ local_var = MyOtherEnum.OTHER_ENUM_VALUE_2
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.out
new file mode 100644
index 0000000000..fde7e92f8c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_assign_with_wrong_enum_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Cannot assign a value of type "MyOtherEnum (enum)" to a target of type "MyEnum (enum)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.gd
new file mode 100644
index 0000000000..ca6d892218
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.gd
@@ -0,0 +1,6 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+enum MyOtherEnum { OTHER_ENUM_VALUE_1, OTHER_ENUM_VALUE_2 }
+
+func test():
+ var local_var: MyEnum = MyOtherEnum.OTHER_ENUM_VALUE_1
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.out
new file mode 100644
index 0000000000..b1710c798d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_local_var_init_with_wrong_enum_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Value of type "MyOtherEnum (enum)" cannot be assigned to a variable of type "MyEnum (enum)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.gd b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.gd
new file mode 100644
index 0000000000..435711fcaf
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.gd
@@ -0,0 +1,10 @@
+func test():
+ print("Shouldn't reach this")
+
+class Parent:
+ func my_function(_par1: int) -> int:
+ return 0
+
+class Child extends Parent:
+ func my_function() -> int:
+ return 0
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.out b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.out
new file mode 100644
index 0000000000..3baeb17066
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_less.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The function signature doesn't match the parent. Parent signature is "int my_function(int)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.gd b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.gd
new file mode 100644
index 0000000000..2bd392e8f8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.gd
@@ -0,0 +1,10 @@
+func test():
+ print("Shouldn't reach this")
+
+class Parent:
+ func my_function(_par1: int) -> int:
+ return 0
+
+class Child extends Parent:
+ func my_function(_pary1: int, _par2: int) -> int:
+ return 0
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.out b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.out
new file mode 100644
index 0000000000..3baeb17066
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_count_more.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The function signature doesn't match the parent. Parent signature is "int my_function(int)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.gd b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.gd
new file mode 100644
index 0000000000..49ec82ce2d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.gd
@@ -0,0 +1,10 @@
+func test():
+ print("Shouldn't reach this")
+
+class Parent:
+ func my_function(_par1: int = 0) -> int:
+ return 0
+
+class Child extends Parent:
+ func my_function(_par1: int) -> int:
+ return 0
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.out b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.out
new file mode 100644
index 0000000000..665c229339
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_default_values.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The function signature doesn't match the parent. Parent signature is "int my_function(int = default)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.gd
new file mode 100644
index 0000000000..4a17a7831f
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.gd
@@ -0,0 +1,10 @@
+func test():
+ print("Shouldn't reach this")
+
+class Parent:
+ func my_function(_par1: int) -> int:
+ return 0
+
+class Child extends Parent:
+ func my_function(_par1: Vector2) -> int:
+ return 0
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.out b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.out
new file mode 100644
index 0000000000..3baeb17066
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_parameter_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The function signature doesn't match the parent. Parent signature is "int my_function(int)".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.gd
new file mode 100644
index 0000000000..b205ec96ef
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.gd
@@ -0,0 +1,10 @@
+func test():
+ print("Shouldn't reach this")
+
+class Parent:
+ func my_function() -> int:
+ return 0
+
+class Child extends Parent:
+ func my_function() -> Vector2:
+ return Vector2()
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.out b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.out
new file mode 100644
index 0000000000..5b22739a93
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/function_dont_match_parent_signature_return_type.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The function signature doesn't match the parent. Parent signature is "int my_function()".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out b/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out
index 015ad756f8..6f7f0783f0 100644
--- a/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out
+++ b/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out
@@ -1,2 +1,2 @@
GDTEST_ANALYZER_ERROR
-Invalid index type "bool" for a base of type "Array".
+Cannot get index "true" from "[0, 1]".
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.gd b/modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.gd
new file mode 100644
index 0000000000..05d9bd6a3d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.gd
@@ -0,0 +1,9 @@
+# https://github.com/godotengine/godot/issues/56702
+
+func test():
+ # somewhat obscure feature: referencing parameters in defaults, but only earlier ones!
+ ref_default("non-optional")
+
+
+func ref_default(nondefault1, defa=nondefault1, defb=defc, defc=1):
+ prints(nondefault1, nondefault2, defa, defb, defc)
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.out b/modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.out
new file mode 100644
index 0000000000..1d5b5bf393
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/params_default_forward_reference.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Identifier "defc" not declared in the current scope.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.gd
new file mode 100644
index 0000000000..edb785c8b6
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.gd
@@ -0,0 +1,13 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+
+var class_var: int = MyEnum.ENUM_VALUE_1
+
+func test():
+ print(class_var)
+ class_var = MyEnum.ENUM_VALUE_2
+ print(class_var)
+
+ var local_var: int = MyEnum.ENUM_VALUE_1
+ print(local_var)
+ local_var = MyEnum.ENUM_VALUE_2
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.out b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.out
new file mode 100644
index 0000000000..5f53802c33
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_enum_to_int_typed_var.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+0
+1
+0
+1
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.gd
new file mode 100644
index 0000000000..726e4fd413
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.gd
@@ -0,0 +1,13 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+
+var class_var: MyEnum = 0 as MyEnum
+
+func test():
+ print(class_var)
+ class_var = 1 as MyEnum
+ print(class_var)
+
+ var local_var: MyEnum = 0 as MyEnum
+ print(local_var)
+ local_var = 1 as MyEnum
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.out b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.out
new file mode 100644
index 0000000000..5f53802c33
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_int_cast_to_same_enum.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+0
+1
+0
+1
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.gd
new file mode 100644
index 0000000000..798912c987
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.gd
@@ -0,0 +1,14 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+enum MyOtherEnum { OTHER_ENUM_VALUE_1, OTHER_ENUM_VALUE_2 }
+
+var class_var: MyEnum = MyOtherEnum.OTHER_ENUM_VALUE_1 as MyEnum
+
+func test():
+ print(class_var)
+ class_var = MyOtherEnum.OTHER_ENUM_VALUE_2 as MyEnum
+ print(class_var)
+
+ var local_var: MyEnum = MyOtherEnum.OTHER_ENUM_VALUE_1 as MyEnum
+ print(local_var)
+ local_var = MyOtherEnum.OTHER_ENUM_VALUE_2 as MyEnum
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.out b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.out
new file mode 100644
index 0000000000..5f53802c33
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_other_enum_cast_to_same_enum.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+0
+1
+0
+1
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.gd
new file mode 100644
index 0000000000..2bfb318c3c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.gd
@@ -0,0 +1,13 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+
+var class_var: MyEnum = MyEnum.ENUM_VALUE_1
+
+func test():
+ print(class_var)
+ class_var = MyEnum.ENUM_VALUE_2
+ print(class_var)
+
+ var local_var: MyEnum = MyEnum.ENUM_VALUE_1
+ print(local_var)
+ local_var = MyEnum.ENUM_VALUE_2
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.out b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.out
new file mode 100644
index 0000000000..5f53802c33
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_assign_same_enum.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+0
+1
+0
+1
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.gd
new file mode 100644
index 0000000000..7022d14566
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.gd
@@ -0,0 +1,21 @@
+# Enum is equivalent to int for comparisons and operations.
+enum MyEnum {
+ ZERO,
+ ONE,
+ TWO,
+}
+
+enum OtherEnum {
+ ZERO,
+ ONE,
+ TWO,
+}
+
+func test():
+ print(MyEnum.ZERO == OtherEnum.ZERO)
+ print(MyEnum.ZERO == 1)
+ print(MyEnum.ZERO != OtherEnum.ONE)
+ print(MyEnum.ZERO != 0)
+
+ print(MyEnum.ONE + OtherEnum.TWO)
+ print(2 - MyEnum.ONE)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.out b/modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.out
new file mode 100644
index 0000000000..c8f34c11db
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_is_treated_as_int.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+true
+false
+true
+false
+3
+1
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.gd b/modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.gd
new file mode 100644
index 0000000000..885d70408a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.gd
@@ -0,0 +1,13 @@
+enum MyEnum {
+ ZERO,
+ ONE,
+ TWO,
+}
+
+func test():
+ for key in MyEnum.keys():
+ prints(key, MyEnum[key])
+
+ # https://github.com/godotengine/godot/issues/55491
+ for key in MyEnum:
+ prints(key, MyEnum[key])
diff --git a/modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.out b/modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.out
new file mode 100644
index 0000000000..d29f53109c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/enum_type_is_treated_as_dictionary.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+ZERO 0
+ONE 1
+TWO 2
+ZERO 0
+ONE 1
+TWO 2
diff --git a/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.gd b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.gd
new file mode 100644
index 0000000000..631e7be5ce
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.gd
@@ -0,0 +1,14 @@
+func test():
+ var instance := Parent.new()
+ instance.my_function({"a": 1})
+ instance = Child.new()
+ instance.my_function({"a": 1})
+ print("No failure")
+
+class Parent:
+ func my_function(_par1: Dictionary = {}) -> void:
+ pass
+
+class Child extends Parent:
+ func my_function(_par1: Dictionary = {}) -> void:
+ pass
diff --git a/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.out b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.out
new file mode 100644
index 0000000000..67f0045867
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_default_dict_void.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+No failure
diff --git a/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd
new file mode 100644
index 0000000000..d678f3acfc
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.gd
@@ -0,0 +1,17 @@
+func test():
+ var instance := Parent.new()
+ var result := instance.my_function(1)
+ print(result)
+ assert(result == 1)
+ instance = Child.new()
+ result = instance.my_function(2)
+ print(result)
+ assert(result == 0)
+
+class Parent:
+ func my_function(par1: int) -> int:
+ return par1
+
+class Child extends Parent:
+ func my_function(_par1: int, par2: int = 0) -> int:
+ return par2
diff --git a/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.out b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.out
new file mode 100644
index 0000000000..fc5315a501
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/function_match_parent_signature_with_extra_parameters.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+1
+0
diff --git a/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd
new file mode 100644
index 0000000000..877a4ea221
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.gd
@@ -0,0 +1,15 @@
+@warning_ignore(unused_private_class_variable)
+var _unused = 2
+
+@warning_ignore(unused_variable)
+func test():
+ print("test")
+ var unused = 3
+
+ @warning_ignore(redundant_await)
+ print(await regular_func())
+
+ print("done")
+
+func regular_func():
+ return 0
diff --git a/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out
new file mode 100644
index 0000000000..42292774a0
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/warning_ignore_annotation.out
@@ -0,0 +1,4 @@
+GDTEST_OK
+test
+0
+done
diff --git a/modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.gd b/modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.gd
new file mode 100644
index 0000000000..e9690ee93d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.gd
@@ -0,0 +1,2 @@
+func test():
+ $=$
diff --git a/modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.out b/modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.out
new file mode 100644
index 0000000000..b3dc181a22
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/dollar-assignment-bug-53696.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+Expect node path as string or identifier after "$".
diff --git a/modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.gd b/modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.gd
new file mode 100644
index 0000000000..4608c778aa
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.gd
@@ -0,0 +1,4 @@
+func test():
+ match 1:
+ [[[var a]]], 2:
+ pass
diff --git a/modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.out b/modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.out
new file mode 100644
index 0000000000..1cdc24683b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/errors/match_multiple_variable_binds_in_branch.out
@@ -0,0 +1,2 @@
+GDTEST_PARSER_ERROR
+Cannot use a variable bind with multiple patterns.
diff --git a/modules/gdscript/tests/scripts/parser/features/advanced_expression_matching.out b/modules/gdscript/tests/scripts/parser/features/advanced_expression_matching.out
index 67c7e28046..3cdafb04a9 100644
--- a/modules/gdscript/tests/scripts/parser/features/advanced_expression_matching.out
+++ b/modules/gdscript/tests/scripts/parser/features/advanced_expression_matching.out
@@ -10,5 +10,5 @@ wildcard
[1,2,[1,{1:2,2:var z,..}]]
3
[1,2,[1,{1:2,2:var z,..}]]
-[1, 3, 5, 123]
+[1, 3, 5, "123"]
wildcard
diff --git a/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd
new file mode 100644
index 0000000000..cc78309ae4
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd
@@ -0,0 +1,58 @@
+# https://github.com/godotengine/godot/issues/50285
+
+@warning_ignore(unused_local_constant)
+func test():
+ const CONST_INNER_DICTIONARY = { "key": true }
+ const CONST_NESTED_DICTIONARY_OLD_WORKAROUND = {
+ "key1": "value1",
+ "key2": CONST_INNER_DICTIONARY
+ }
+ # All of these should be valid
+ const CONST_NESTED_DICTIONARY = {
+ "key1": "value1",
+ "key2": { "key": true }
+ }
+
+
+ const CONST_DICTIONARY_WITH_ARRAY = {
+ "key1": [1,2,3,4]
+ }
+
+ const CONST_NESTED_ARRAY = [[],[2],[1,2,3]]
+ const CONST_ARRAY_WITH_DICT = [{"key1": 3}, {"key2": 5}]
+
+ const THREE_DIMENSIONAL_ARRAY = [[[],[],[]],[[],[],[]],[[],[],[]]]
+ const MANY_NESTED_DICT = {
+ "key1": {
+ "key11": {
+ "key111": {},
+ "key112": {},
+ },
+ "key12": {
+ "key121": {},
+ "key122": {},
+ },
+ },
+ "key2": {
+ "key21": {
+ "key211": {},
+ "key212": {},
+ },
+ "key22": {
+ "key221": {},
+ "key222": {},
+ },
+ }
+ }
+
+
+ const CONST_ARRAY_ACCESS = [1,2,3][0]
+ const CONST_DICT_ACCESS = {"key1": 5}["key1"]
+
+ const CONST_ARRAY_NESTED_ACCESS = [[1,2,3],[4,5,6],[8,9,10]][0][1]
+ const CONST_DICT_NESTED_ACCESS = {"key1": {"key2": 1}}["key1"]["key2"]
+
+ print(CONST_ARRAY_ACCESS)
+ print(CONST_DICT_ACCESS)
+ print(CONST_ARRAY_NESTED_ACCESS)
+ print(CONST_DICT_NESTED_ACCESS)
diff --git a/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out
new file mode 100644
index 0000000000..5883fc5c18
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+1
+5
+2
+1
diff --git a/modules/gdscript/tests/scripts/parser/features/class_inheritance_access.gd b/modules/gdscript/tests/scripts/parser/features/class_inheritance_access.gd
new file mode 100644
index 0000000000..eb392672eb
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/class_inheritance_access.gd
@@ -0,0 +1,40 @@
+# Test access visibility of parent elements in nested class architectures.
+class Parent:
+ const parent_const := 1
+
+ var parent_variable := 2
+
+ signal parent_signal
+
+ var parent_attribute: int:
+ get:
+ return 3
+
+ func parent_func():
+ return 4
+
+ class Nested:
+ const nested_const := 5
+
+
+class Child extends Parent:
+ func child_test():
+ print(parent_const)
+ print(self.parent_const)
+ print(parent_variable)
+ print(self.parent_variable)
+ print(parent_signal.get_name())
+ print(self.parent_signal.get_name())
+ print(parent_attribute)
+ print(self.parent_attribute)
+ print(parent_func.get_method())
+ print(self.parent_func.get_method())
+ print(parent_func())
+ print(self.parent_func())
+ print(Nested.nested_const)
+ print(self.Nested.nested_const)
+ print(Parent.Nested.nested_const)
+
+
+func test():
+ Child.new().child_test()
diff --git a/modules/gdscript/tests/scripts/parser/features/class_inheritance_access.out b/modules/gdscript/tests/scripts/parser/features/class_inheritance_access.out
new file mode 100644
index 0000000000..09e87bccfa
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/class_inheritance_access.out
@@ -0,0 +1,16 @@
+GDTEST_OK
+1
+1
+2
+2
+parent_signal
+parent_signal
+3
+3
+parent_func
+parent_func
+4
+4
+5
+5
+5
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary.out b/modules/gdscript/tests/scripts/parser/features/dictionary.out
index 54083c1afc..5f999f573a 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary.out
@@ -7,8 +7,8 @@ null
false
empty array
zero Vector2i
-{22:{4:[nesting, arrays]}}
-{4:[nesting, arrays]}
-[nesting, arrays]
+{22:{4:["nesting", "arrays"]}}
+{4:["nesting", "arrays"]}
+["nesting", "arrays"]
nesting
arrays
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out b/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
index 447d7e223c..5143d040a9 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary_lua_style.out
@@ -1,2 +1,2 @@
GDTEST_OK
-{2:4, a:1, b:2, with spaces:3}
+{"a":1, "b":2, "with spaces":3, "2":4}
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out b/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
index 62be807a1f..dd28609850 100644
--- a/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
+++ b/modules/gdscript/tests/scripts/parser/features/dictionary_mixed_syntax.out
@@ -1,2 +1,2 @@
GDTEST_OK
-{hello:{world:{is:beautiful}}}
+{"hello":{"world":{"is":"beautiful"}}}
diff --git a/modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.gd b/modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.gd
new file mode 100644
index 0000000000..a0ae7fb17c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.gd
@@ -0,0 +1,6 @@
+func test():
+ match [1, 2, 3]:
+ [var a, var b, var c]:
+ print(a == 1)
+ print(b == 2)
+ print(c == 3)
diff --git a/modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.out b/modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.out
new file mode 100644
index 0000000000..316db6d748
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/features/match_multiple_variable_binds_in_pattern.out
@@ -0,0 +1,4 @@
+GDTEST_OK
+true
+true
+true
diff --git a/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out b/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
index 4009160439..8b8c33202f 100644
--- a/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
+++ b/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
@@ -1,5 +1,5 @@
GDTEST_OK
-{8:{key:value}}
-{key:value}
+{8:{"key":"value"}}
+{"key":"value"}
value
value
diff --git a/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd b/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd
index 9ad98b78a8..e4d6a72f90 100644
--- a/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd
+++ b/modules/gdscript/tests/scripts/parser/features/signal_declaration.gd
@@ -6,7 +6,7 @@ signal a
# No parameters.
signal b()
-# With paramters.
+# With parameters.
signal c(a, b, c)
# With parameters multiline.
diff --git a/modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.gd b/modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.gd
new file mode 100644
index 0000000000..2be1024214
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.gd
@@ -0,0 +1,15 @@
+enum MyEnum { ENUM_VALUE_1, ENUM_VALUE_2 }
+
+# Assigning int value to enum-typed variable without explicit cast causes a warning.
+# While it is valid it may be a mistake in the assignment.
+var class_var: MyEnum = 0
+
+func test():
+ print(class_var)
+ class_var = 1
+ print(class_var)
+
+ var local_var: MyEnum = 0
+ print(local_var)
+ local_var = 1
+ print(local_var)
diff --git a/modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.out b/modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.out
new file mode 100644
index 0000000000..eef13bbff8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/enum_assign_int_without_casting.out
@@ -0,0 +1,21 @@
+GDTEST_OK
+>> WARNING
+>> Line: 5
+>> INT_ASSIGNED_TO_ENUM
+>> Integer used when an enum value is expected. If this is intended cast the integer to the enum type.
+>> WARNING
+>> Line: 9
+>> INT_ASSIGNED_TO_ENUM
+>> Integer used when an enum value is expected. If this is intended cast the integer to the enum type.
+>> WARNING
+>> Line: 12
+>> INT_ASSIGNED_TO_ENUM
+>> Integer used when an enum value is expected. If this is intended cast the integer to the enum type.
+>> WARNING
+>> Line: 14
+>> INT_ASSIGNED_TO_ENUM
+>> Integer used when an enum value is expected. If this is intended cast the integer to the enum type.
+0
+1
+0
+1
diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd
new file mode 100644
index 0000000000..3c64be571b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.gd
@@ -0,0 +1,2 @@
+func test():
+ var abs = "This variable has the same name as the built-in function."
diff --git a/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out
new file mode 100644
index 0000000000..c613140eb8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/shadowed_global_identifier.out
@@ -0,0 +1,9 @@
+GDTEST_OK
+>> WARNING
+>> Line: 2
+>> UNUSED_VARIABLE
+>> The local variable 'abs' is declared but never used in the block. If this is intended, prefix it with an underscore: '_abs'
+>> WARNING
+>> Line: 2
+>> SHADOWED_GLOBAL_IDENTIFIER
+>> The variable 'abs' has the same name as a built-in function.
diff --git a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd
index 10780b5379..7b3c112fe9 100644
--- a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd
+++ b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd
@@ -1,3 +1,4 @@
+#debug-only
func test():
var node := Node.new()
var inside_tree = node.is_inside_tree
diff --git a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out
index e585c374e2..fe48ade26b 100644
--- a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out
+++ b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out
@@ -2,5 +2,5 @@ GDTEST_RUNTIME_ERROR
>> SCRIPT ERROR
>> on function: test()
>> runtime/errors/callable_call_after_free_object.gd
->> 5
+>> 6
>> Attempt to call function 'null::is_inside_tree (Callable)' on a null instance.
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_use_self.gd b/modules/gdscript/tests/scripts/runtime/features/lambda_use_self.gd
new file mode 100644
index 0000000000..3d063869ab
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_use_self.gd
@@ -0,0 +1,23 @@
+var member = "foo"
+
+func bar():
+ print("bar")
+
+func test():
+ var lambda1 = func():
+ print(member)
+ lambda1.call()
+
+ var lambda2 = func():
+ var nested = func():
+ print(member)
+ nested.call()
+ lambda2.call()
+
+ var lambda3 = func():
+ bar()
+ lambda3.call()
+
+ var lambda4 = func():
+ return self
+ print(lambda4.call() == self)
diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_use_self.out b/modules/gdscript/tests/scripts/runtime/features/lambda_use_self.out
new file mode 100644
index 0000000000..53d602b234
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/lambda_use_self.out
@@ -0,0 +1,5 @@
+GDTEST_OK
+foo
+foo
+bar
+true
diff --git a/modules/gdscript/tests/scripts/runtime/features/params_default_values.gd b/modules/gdscript/tests/scripts/runtime/features/params_default_values.gd
new file mode 100644
index 0000000000..8156b4ec68
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/params_default_values.gd
@@ -0,0 +1,35 @@
+# https://github.com/godotengine/godot/issues/56702
+
+func test():
+ const_default()
+ func_result_default()
+ # calling again will run the initializer again,
+ # as the default is not evaluated at time of defining the function (as in python)
+ # but every time the function is called (as in C++)
+ func_result_default()
+ lots_of_defaults("non-optional")
+ # somewhat obscure feature: referencing earlier parameters
+ ref_default("non-optional", 42)
+
+
+func const_default(param=42):
+ print(param)
+
+
+var default_val := 0
+
+func get_default():
+ default_val += 1
+ return default_val
+
+
+func func_result_default(param=get_default()):
+ print(param)
+
+
+func lots_of_defaults(nondefault, one=1, two=2, three=get_default()):
+ prints(nondefault, one, two, three)
+
+
+func ref_default(nondefault1, nondefault2, defa=nondefault1, defb=nondefault2 - 1):
+ prints(nondefault1, nondefault2, defa, defb)
diff --git a/modules/gdscript/tests/scripts/runtime/features/params_default_values.out b/modules/gdscript/tests/scripts/runtime/features/params_default_values.out
new file mode 100644
index 0000000000..50e0885ae5
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/params_default_values.out
@@ -0,0 +1,6 @@
+GDTEST_OK
+42
+1
+2
+non-optional 1 2 3
+non-optional 42 non-optional 41
diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.out b/modules/gdscript/tests/scripts/runtime/features/stringify.out
index 7670fc0128..d4468737a5 100644
--- a/modules/gdscript/tests/scripts/runtime/features/stringify.out
+++ b/modules/gdscript/tests/scripts/runtime/features/stringify.out
@@ -21,14 +21,14 @@ hello/world
RID(0)
Node::get_name
Node::[signal]property_list_changed
-{hello:123}
-[hello, 123]
+{"hello":123}
+["hello", 123]
[255, 0, 1]
[-1, 0, 1]
[-1, 0, 1]
[-1, 0, 1]
[-1, 0, 1]
-[hello, world]
+["hello", "world"]
[(1, 1), (0, 0)]
[(1, 1, 1), (0, 0, 0)]
[(1, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1)]
diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp
index 80eabc1596..d8f60d5e9b 100644
--- a/modules/gdscript/tests/test_gdscript.cpp
+++ b/modules/gdscript/tests/test_gdscript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 */
@@ -204,8 +204,8 @@ void test(TestType p_type) {
return;
}
- FileAccessRef fa = FileAccess::open(test, FileAccess::READ);
- ERR_FAIL_COND_MSG(!fa, "Could not open file: " + test);
+ Ref<FileAccess> fa = FileAccess::open(test, FileAccess::READ);
+ ERR_FAIL_COND_MSG(fa.is_null(), "Could not open file: " + test);
// Initialize the language for the test routine.
init_language(fa->get_path_absolute().get_base_dir());
diff --git a/modules/gdscript/tests/test_gdscript.h b/modules/gdscript/tests/test_gdscript.h
index c7ee5a2208..b6b1f26203 100644
--- a/modules/gdscript/tests/test_gdscript.h
+++ b/modules/gdscript/tests/test_gdscript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 */