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.cpp73
-rw-r--r--modules/gdscript/tests/gdscript_test_runner_suite.h34
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_inner_base.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/external_inner_base.out3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.notest.gd (renamed from modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd)3
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/inner_base.gd18
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/inner_base.out4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.gd4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_a.notest.gd12
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_b.notest.gd10
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/property_inline.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/class.gd4
-rw-r--r--modules/gdscript/tests/scripts/parser/features/dictionary.out4
-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/function_many_parameters.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/features/nested_dictionary.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/features/str_preserves_case.out2
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out4
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd11
-rw-r--r--modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out7
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.gd4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.gd60
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.out (renamed from modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.out)0
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/range_returns_ints.gd77
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/range_returns_ints.out1
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/stringify.out2
39 files changed, 349 insertions, 45 deletions
diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp
index ff4832bde0..f59983ca90 100644
--- a/modules/gdscript/tests/gdscript_test_runner.cpp
+++ b/modules/gdscript/tests/gdscript_test_runner.cpp
@@ -36,6 +36,7 @@
#include "../gdscript_parser.h"
#include "core/config/project_settings.h"
+#include "core/core_globals.h"
#include "core/core_string_names.h"
#include "core/io/dir_access.h"
#include "core/io/file_access_pack.h"
@@ -70,27 +71,38 @@ void init_autoloads() {
continue;
}
- Ref<Resource> res = ResourceLoader::load(info.path);
- ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path);
Node *n = nullptr;
- 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 from Node: " + info.path);
+ if (ResourceLoader::get_resource_type(info.path) == "PackedScene") {
+ // Cache the scene reference before loading it (for cyclic references)
+ Ref<PackedScene> scn;
+ scn.instantiate();
+ scn->set_path(info.path);
+ scn->reload_from_file();
+ ERR_CONTINUE_MSG(!scn.is_valid(), vformat("Can't autoload: %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));
- Object *obj = ClassDB::instantiate(ibt);
+ 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(!obj, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + ".");
+ Object *obj = ClassDB::instantiate(ibt);
- n = Object::cast_to<Node>(obj);
- n->set_script(script);
+ ERR_CONTINUE_MSG(!obj, vformat("Cannot instance script for Autoload, expected 'Node' inheritance, got: %s.", ibt));
+
+ n = Object::cast_to<Node>(obj);
+ n->set_script(scr);
+ }
}
- ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path);
+ ERR_CONTINUE_MSG(!n, vformat("Path in autoload not a node or script: %s.", info.path));
n->set_name(info.name);
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -142,8 +154,8 @@ GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_l
#endif
// Enable printing to show results
- _print_line_enabled = true;
- _print_error_enabled = true;
+ CoreGlobals::print_line_enabled = true;
+ CoreGlobals::print_error_enabled = true;
}
GDScriptTestRunner::~GDScriptTestRunner() {
@@ -246,15 +258,18 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) {
next = dir->get_next();
continue;
}
- if (!make_tests_for_dir(current_dir.plus_file(next))) {
+ if (!make_tests_for_dir(current_dir.path_join(next))) {
return false;
}
} else {
- if (next.get_extension().to_lower() == "gd") {
+ if (next.ends_with(".notest.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.
Error open_err = OK;
- Ref<FileAccess> script_file(FileAccess::open(current_dir.plus_file(next), FileAccess::READ, &open_err));
+ Ref<FileAccess> script_file(FileAccess::open(current_dir.path_join(next), FileAccess::READ, &open_err));
if (open_err != OK) {
ERR_PRINT(vformat(R"(Couldn't open test file "%s".)", next));
next = dir->get_next();
@@ -271,7 +286,7 @@ bool GDScriptTestRunner::make_tests_for_dir(const String &p_dir) {
if (!is_generating && !dir->file_exists(out_file)) {
ERR_FAIL_V_MSG(false, "Could not find output file for " + next);
}
- GDScriptTest test(current_dir.plus_file(next), current_dir.plus_file(out_file), source_dir);
+ GDScriptTest test(current_dir.path_join(next), current_dir.path_join(out_file), source_dir);
tests.push_back(test);
}
}
@@ -460,7 +475,6 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
Ref<GDScript> script;
script.instantiate();
script->set_path(source_file);
- script->set_script_path(source_file);
err = script->load_source_code(source_file);
if (err != OK) {
enable_stdout();
@@ -478,9 +492,9 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
result.output = get_text_for_status(result.status) + "\n";
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const GDScriptParser::ParserError &E : errors) {
- result.output += E.message + "\n"; // TODO: line, column?
- break; // Only the first error since the following might be cascading.
+ if (!errors.is_empty()) {
+ // Only the first error since the following might be cascading.
+ result.output += errors[0].message + "\n"; // TODO: line, column?
}
if (!p_is_generating) {
result.passed = check_output(result.output);
@@ -497,9 +511,9 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
result.output = get_text_for_status(result.status) + "\n";
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
- for (const GDScriptParser::ParserError &E : errors) {
- result.output += E.message + "\n"; // TODO: line, column?
- break; // Only the first error since the following might be cascading.
+ if (!errors.is_empty()) {
+ // Only the first error since the following might be cascading.
+ result.output += errors[0].message + "\n"; // TODO: line, column?
}
if (!p_is_generating) {
result.passed = check_output(result.output);
@@ -597,6 +611,9 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
}
enable_stdout();
+
+ GDScriptCache::remove_script(script->get_path());
+
return result;
}
diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h
index 0722fb800e..90f6d7f7e8 100644
--- a/modules/gdscript/tests/gdscript_test_runner_suite.h
+++ b/modules/gdscript/tests/gdscript_test_runner_suite.h
@@ -69,6 +69,40 @@ func _init():
CHECK_MESSAGE(int(ref_counted->get_meta("result")) == 42, "The script should assign object metadata successfully.");
}
+TEST_CASE("[Modules][GDScript] Validate built-in API") {
+ GDScriptLanguage *lang = GDScriptLanguage::get_singleton();
+
+ // Validate methods.
+ List<MethodInfo> builtin_methods;
+ lang->get_public_functions(&builtin_methods);
+
+ SUBCASE("[Modules][GDScript] Validate built-in methods") {
+ for (const MethodInfo &mi : builtin_methods) {
+ for (int j = 0; j < mi.arguments.size(); j++) {
+ PropertyInfo arg = mi.arguments[j];
+
+ TEST_COND((arg.name.is_empty() || arg.name.begins_with("_unnamed_arg")),
+ vformat("Unnamed argument in position %d of built-in method '%s'.", j, mi.name));
+ }
+ }
+ }
+
+ // Validate annotations.
+ List<MethodInfo> builtin_annotations;
+ lang->get_public_annotations(&builtin_annotations);
+
+ SUBCASE("[Modules][GDScript] Validate built-in annotations") {
+ for (const MethodInfo &ai : builtin_annotations) {
+ for (int j = 0; j < ai.arguments.size(); j++) {
+ PropertyInfo arg = ai.arguments[j];
+
+ TEST_COND((arg.name.is_empty() || arg.name.begins_with("_unnamed_arg")),
+ vformat("Unnamed argument in position %d of built-in annotation '%s'.", j, ai.name));
+ }
+ }
+ }
+}
+
} // namespace GDScriptTests
#endif // GDSCRIPT_TEST_RUNNER_SUITE_H
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd
new file mode 100644
index 0000000000..5c8b9fa4ae
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd
@@ -0,0 +1,6 @@
+extends Node
+
+var script: int
+
+func test():
+ pass
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out
new file mode 100644
index 0000000000..8454aaa404
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Member "script" redefined (original in native class 'Node')
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd
new file mode 100644
index 0000000000..28561ff94b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd
@@ -0,0 +1,9 @@
+func test():
+ pass
+
+class A:
+ func overload_me():
+ pass
+
+class B extends A:
+ var overload_me
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out
new file mode 100644
index 0000000000..32357f9f6a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The member "overload_me" already exists in parent class A.
diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_inner_base.gd b/modules/gdscript/tests/scripts/analyzer/features/external_inner_base.gd
new file mode 100644
index 0000000000..3f9bfe189c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/external_inner_base.gd
@@ -0,0 +1,4 @@
+extends "inner_base.gd".InnerA.InnerAB
+
+func test():
+ super.test()
diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_inner_base.out b/modules/gdscript/tests/scripts/analyzer/features/external_inner_base.out
new file mode 100644
index 0000000000..62f1383392
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/external_inner_base.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+InnerA.InnerAB.test
+InnerB.test
diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd b/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.notest.gd
index fb0ace6a90..c3fc176679 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.gd
+++ b/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.notest.gd
@@ -1,5 +1,4 @@
-func test():
- pass
+const A := 42
func something():
return "OK"
diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_base.gd b/modules/gdscript/tests/scripts/analyzer/features/inner_base.gd
new file mode 100644
index 0000000000..a825b59255
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/inner_base.gd
@@ -0,0 +1,18 @@
+extends InnerA
+
+func test():
+ super.test()
+
+class InnerA extends InnerAB:
+ func test():
+ print("InnerA.test")
+ super.test()
+
+ class InnerAB extends InnerB:
+ func test():
+ print("InnerA.InnerAB.test")
+ super.test()
+
+class InnerB:
+ func test():
+ print("InnerB.test")
diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_base.out b/modules/gdscript/tests/scripts/analyzer/features/inner_base.out
new file mode 100644
index 0000000000..ddd5ffcfd3
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/inner_base.out
@@ -0,0 +1,4 @@
+GDTEST_OK
+InnerA.test
+InnerA.InnerAB.test
+InnerB.test
diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd
new file mode 100644
index 0000000000..9d0324ead8
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.gd
@@ -0,0 +1,6 @@
+const Constants = preload("gdscript_to_preload.notest.gd")
+
+func test():
+ var a := Constants.A
+ print(a)
+
diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out
new file mode 100644
index 0000000000..0982f3718c
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/preload_constant_types_are_inferred.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+42
diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.gd b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.gd
new file mode 100644
index 0000000000..b730453a8a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.gd
@@ -0,0 +1,4 @@
+const A = preload("preload_cyclic_reference_a.notest.gd")
+
+func test():
+ A.test_cyclic_reference()
diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.out b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.out
new file mode 100644
index 0000000000..14bb971221
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference.out
@@ -0,0 +1,2 @@
+GDTEST_OK
+godot
diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_a.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_a.notest.gd
new file mode 100644
index 0000000000..7a6035ded1
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_a.notest.gd
@@ -0,0 +1,12 @@
+const B = preload("preload_cyclic_reference_b.notest.gd")
+
+const WAITING_FOR = "godot"
+
+static func test_cyclic_reference():
+ B.test_cyclic_reference()
+
+static func test_cyclic_reference_2():
+ B.test_cyclic_reference_2()
+
+static func test_cyclic_reference_3():
+ B.test_cyclic_reference_3()
diff --git a/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_b.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_b.notest.gd
new file mode 100644
index 0000000000..3ea5b01156
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/preload_cyclic_reference_b.notest.gd
@@ -0,0 +1,10 @@
+const A = preload("preload_cyclic_reference_a.notest.gd")
+
+static func test_cyclic_reference():
+ A.test_cyclic_reference_2()
+
+static func test_cyclic_reference_2():
+ A.test_cyclic_reference_3()
+
+static func test_cyclic_reference_3():
+ print(A.WAITING_FOR)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/property_inline.out b/modules/gdscript/tests/scripts/analyzer/features/property_inline.out
index 5482592e90..63e59398ae 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/property_inline.out
+++ b/modules/gdscript/tests/scripts/analyzer/features/property_inline.out
@@ -1,5 +1,5 @@
GDTEST_OK
-null
+<null>
0
1
2
diff --git a/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd b/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd
index 5f73064cc0..beabf3d2e5 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd
+++ b/modules/gdscript/tests/scripts/analyzer/features/use_preload_script_as_type.gd
@@ -1,4 +1,4 @@
-const preloaded : GDScript = preload("gdscript_to_preload.gd")
+const preloaded : GDScript = preload("gdscript_to_preload.notest.gd")
func test():
var preloaded_instance: preloaded = preloaded.new()
diff --git a/modules/gdscript/tests/scripts/parser/features/class.gd b/modules/gdscript/tests/scripts/parser/features/class.gd
index 6652f85ad9..af24b32322 100644
--- a/modules/gdscript/tests/scripts/parser/features/class.gd
+++ b/modules/gdscript/tests/scripts/parser/features/class.gd
@@ -21,5 +21,5 @@ func test():
assert(test_sub.number == 25) # From Test.
assert(test_sub.other_string == "bye") # From TestSub.
- TestConstructor.new()
- TestConstructor.new(500)
+ var _test_constructor = TestConstructor.new()
+ _test_constructor = TestConstructor.new(500)
diff --git a/modules/gdscript/tests/scripts/parser/features/dictionary.out b/modules/gdscript/tests/scripts/parser/features/dictionary.out
index 5f999f573a..e1eeb46f78 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"]}
+{ 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 5143d040a9..553d40d953 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
-{"a":1, "b":2, "with spaces":3, "2":4}
+{ "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 dd28609850..cf79845f53 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/function_many_parameters.out b/modules/gdscript/tests/scripts/parser/features/function_many_parameters.out
index 3a979227d4..80df7a3d4c 100644
--- a/modules/gdscript/tests/scripts/parser/features/function_many_parameters.out
+++ b/modules/gdscript/tests/scripts/parser/features/function_many_parameters.out
@@ -1,2 +1,2 @@
GDTEST_OK
-123456789101112131415161718192212223242526272829303132333435363738394041424344454647falsetruenull
+123456789101112131415161718192212223242526272829303132333435363738394041424344454647falsetrue<null>
diff --git a/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out b/modules/gdscript/tests/scripts/parser/features/nested_dictionary.out
index 8b8c33202f..508f0ff217 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/str_preserves_case.out b/modules/gdscript/tests/scripts/parser/features/str_preserves_case.out
index abba38e87c..867f45f0ac 100644
--- a/modules/gdscript/tests/scripts/parser/features/str_preserves_case.out
+++ b/modules/gdscript/tests/scripts/parser/features/str_preserves_case.out
@@ -1,4 +1,4 @@
GDTEST_OK
-null
+<null>
true
false
diff --git a/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out b/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out
index d73c5eb7cd..e89bb9226f 100644
--- a/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out
+++ b/modules/gdscript/tests/scripts/parser/warnings/return_value_discarded.out
@@ -1 +1,5 @@
GDTEST_OK
+>> WARNING
+>> Line: 6
+>> RETURN_VALUE_DISCARDED
+>> The function 'i_return_int()' returns a value that will be discarded if not used.
diff --git a/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd
new file mode 100644
index 0000000000..29d8501b78
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.gd
@@ -0,0 +1,11 @@
+class Player:
+ var x = 3
+
+func test():
+ # These should not emit a warning.
+ var _player = Player.new()
+ print(String.num_uint64(8589934592)) # 2 ^ 33
+
+ # This should emit a warning.
+ var some_string = String()
+ print(some_string.num_uint64(8589934592)) # 2 ^ 33
diff --git a/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out
new file mode 100644
index 0000000000..3933a35178
--- /dev/null
+++ b/modules/gdscript/tests/scripts/parser/warnings/static_called_on_instance.out
@@ -0,0 +1,7 @@
+GDTEST_OK
+>> WARNING
+>> Line: 11
+>> STATIC_CALLED_ON_INSTANCE
+>> The function 'num_uint64()' is a static function but was called from an instance. Instead, it should be directly called from the type: 'String.num_uint64()'.
+8589934592
+8589934592
diff --git a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
index 5e7ccf534a..22929bf636 100644
--- a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
+++ b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out
@@ -1,6 +1,6 @@
GDTEST_OK
-{1:(2, 0)}
-{3:(4, 0)}
+{ 1: (2, 0) }
+{ 3: (4, 0) }
[[(5, 0)]]
[[(6, 0)]]
[[(7, 0)]]
diff --git a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.gd b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.gd
index c6645c2c34..809d0d28a9 100644
--- a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.gd
@@ -69,6 +69,10 @@ func test():
value = Transform3D()
print(value == null)
+ # Projection
+ value = Projection()
+ print(value == null)
+
# Color
value = Color()
print(value == null)
diff --git a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.out b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.out
index 639f6027b9..27423ab8e7 100644
--- a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.out
+++ b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-equals-null.out
@@ -33,3 +33,4 @@ false
false
false
false
+false
diff --git a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.gd b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.gd
index ee622bf22f..f46afb0f18 100644
--- a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.gd
@@ -69,6 +69,10 @@ func test():
value = Transform3D()
print(value != null)
+ # Projection
+ value = Projection()
+ print(value != null)
+
# Color
value = Color()
print(value != null)
diff --git a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.out b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.out
index d1e332afba..a11c47854a 100644
--- a/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.out
+++ b/modules/gdscript/tests/scripts/runtime/features/compare-builtin-not-equals-null.out
@@ -33,3 +33,4 @@ true
true
true
true
+true
diff --git a/modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.gd b/modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.gd
new file mode 100644
index 0000000000..e24137a20d
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.gd
@@ -0,0 +1,60 @@
+func test():
+ # All combinations of 1/2/3 arguments, each being int/float.
+
+ for number in range(5):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(5.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+
+ for number in range(1, 5):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1, 5.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1.2, 5):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1.2, 5.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+
+ for number in range(1, 5, 2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1, 5, 2.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1, 5.2, 2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1, 5.2, 2.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1.2, 5, 2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1.2, 5.2, 2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1.2, 5, 2.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ for number in range(1.2, 5.2, 2.2):
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
diff --git a/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.out b/modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.out
index d73c5eb7cd..d73c5eb7cd 100644
--- a/modules/gdscript/tests/scripts/analyzer/features/gdscript_to_preload.out
+++ b/modules/gdscript/tests/scripts/runtime/features/range_optimized_in_for_has_int_iterator.out
diff --git a/modules/gdscript/tests/scripts/runtime/features/range_returns_ints.gd b/modules/gdscript/tests/scripts/runtime/features/range_returns_ints.gd
new file mode 100644
index 0000000000..63c3b84305
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/range_returns_ints.gd
@@ -0,0 +1,77 @@
+func test():
+ # All combinations of 1/2/3 arguments, each being int/float.
+ # Store result in variable to ensure actual array is created (avoid `for` + `range` optimization).
+
+ var result
+
+ result = range(5)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(5.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+
+ result = range(1, 5)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1, 5.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1.2, 5)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1.2, 5.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+
+ result = range(1, 5, 2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1, 5, 2.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1, 5.2, 2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1, 5.2, 2.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1.2, 5, 2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1.2, 5.2, 2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1.2, 5, 2.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
+
+ result = range(1.2, 5.2, 2.2)
+ for number in result:
+ if typeof(number) != TYPE_INT:
+ print("Number returned from `range` was not an int!")
diff --git a/modules/gdscript/tests/scripts/runtime/features/range_returns_ints.out b/modules/gdscript/tests/scripts/runtime/features/range_returns_ints.out
new file mode 100644
index 0000000000..d73c5eb7cd
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/range_returns_ints.out
@@ -0,0 +1 @@
+GDTEST_OK
diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.out b/modules/gdscript/tests/scripts/runtime/features/stringify.out
index d4468737a5..1f33de00cc 100644
--- a/modules/gdscript/tests/scripts/runtime/features/stringify.out
+++ b/modules/gdscript/tests/scripts/runtime/features/stringify.out
@@ -21,7 +21,7 @@ hello/world
RID(0)
Node::get_name
Node::[signal]property_list_changed
-{"hello":123}
+{ "hello": 123 }
["hello", 123]
[255, 0, 1]
[-1, 0, 1]