Bladeren bron

GDScript: Allow tests to run on release builds

- Fix compilation issues by disabling warnings on release builds. This
  also strips warnings from expected result before the comparison to
  avoid false mismatches.
- Add a `#debug-only` flag to tests. Must be the first line of the test
  script. Those won't run with release builds. Can be used for test
  cases that rely on checks only available on debug builds.
George Marques 3 jaren geleden
bovenliggende
commit
b013c0d544

+ 42 - 0
modules/gdscript/tests/gdscript_test_runner.cpp

@@ -134,12 +134,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 +155,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 +187,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);
@@ -233,6 +253,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;
+				FileAccessRef 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);
@@ -387,6 +423,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 +509,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 +523,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;

+ 1 - 0
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

+ 1 - 1
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.