Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 87 additions & 37 deletions exercises/practice/acronym/lib/test_runner.gd
Original file line number Diff line number Diff line change
@@ -1,22 +1,52 @@
class_name TestRunner
extends SceneTree


class ErrorReader:
"""ErrorReader reads from a STDERR file (cmd 2>/file).

It filters out the less useful Godot output and handles retrieving lines iteratively.
"""

const EXPECTED_GODOT_ERRORS = [
"ERROR: Could not create directory: /root/.local\n at: make_dir_recursive (core/io/dir_access.cpp:180)\n",
"ERROR: Error attempting to create data dir: /root/.local/share/godot/app_userdata/[unnamed project].\n at: ensure_user_data_dir (core/os/os.cpp:344)\n",
"ERROR: Could not create editor data directory: /root/.local/share/godot\n at: EditorPaths (editor/editor_paths.cpp:183)\n",
"ERROR: Could not create directory: /root/.config\n at: make_dir_recursive (core/io/dir_access.cpp:180)\n",
"ERROR: Could not create editor config directory: /root/.config/godot\n at: EditorPaths (editor/editor_paths.cpp:198)\n",
"ERROR: Could not create directory: /root/.cache\n at: make_dir_recursive (core/io/dir_access.cpp:180)\n",
"ERROR: Could not create editor cache directory: /root/.cache/godot\n at: EditorPaths (editor/editor_paths.cpp:219)\n",
"ERROR: Can't save resource to empty path. Provide non-empty path or a Resource with non-empty resource_path.\n at: save (core/io/resource_saver.cpp:105)\n",
"ERROR: Error saving editor settings to \n at: save (editor/editor_settings.cpp:1013)\n",
(
"ERROR: Could not create directory: /root/.local\n"
+ " at: make_dir_recursive (core/io/dir_access.cpp:180)\n"
),
(
"ERROR: Error attempting to create data dir: "
+ "/root/.local/share/godot/app_userdata/[unnamed project].\n"
+ " at: ensure_user_data_dir (core/os/os.cpp:344)\n"
),
(
"ERROR: Could not create editor data directory: /root/.local/share/godot\n"
+ " at: EditorPaths (editor/editor_paths.cpp:183)\n"
),
(
"ERROR: Could not create directory: /root/.config\n"
+ " at: make_dir_recursive (core/io/dir_access.cpp:180)\n"
),
(
"ERROR: Could not create editor config directory: /root/.config/godot\n"
+ " at: EditorPaths (editor/editor_paths.cpp:198)\n"
),
(
"ERROR: Could not create directory: /root/.cache\n"
+ " at: make_dir_recursive (core/io/dir_access.cpp:180)\n"
),
(
"ERROR: Could not create editor cache directory: /root/.cache/godot\n"
+ " at: EditorPaths (editor/editor_paths.cpp:219)\n"
),
(
"ERROR: Can't save resource to empty path. "
+ "Provide non-empty path or a Resource with non-empty resource_path.\n"
+ " at: save (core/io/resource_saver.cpp:105)\n"
),
(
"ERROR: Error saving editor settings to \n"
+ " at: save (editor/editor_settings.cpp:1013)\n"
),
]
var already_processed_bytes: int = 0
var filename: String = ""
Expand Down Expand Up @@ -72,7 +102,6 @@ class ErrorReader:


class ResultWriter:

var json_file: String = ""
var stderr: ErrorReader = null

Expand Down Expand Up @@ -103,8 +132,7 @@ class ResultWriter:
"""
if self.json_file.is_empty():
return print_friendly_results(results)
else:
return write_results_file(results)
return write_results_file(results)

func print_friendly_results(results: Dictionary) -> Error:
"""
Expand All @@ -119,7 +147,9 @@ class ResultWriter:
if test.status == "pass":
rich_results.push_back(" %s [color=yellow]passed ✔[/color]" % test.name)
else:
rich_results.push_back(" %s [color=pink]failed: %s[/color]" % [test.name, test.message])
rich_results.push_back(
" %s [color=pink]failed: %s[/color]" % [test.name, test.message]
)
print_rich("\n".join(rich_results))
return OK

Expand Down Expand Up @@ -225,13 +255,14 @@ class ArgParser:


class Runner:

var test_suite: Object = null
var solution: Object = null
var stderr: ErrorReader = null
var result_writer: ResultWriter = null

func _init(test_suite: Object, solution: Object, stderr: ErrorReader, result_writer: ResultWriter) -> void:
func _init(
test_suite: Object, solution: Object, stderr: ErrorReader, result_writer: ResultWriter
) -> void:
self.test_suite = test_suite
self.solution = solution
self.stderr = stderr
Expand All @@ -243,7 +274,7 @@ class Runner:
var parts = []
var methods: Dictionary = {}
var name: String = ""
var func_re: RegEx = RegEx.create_from_string('^func ([^(]+)\\(')
var func_re: RegEx = RegEx.create_from_string("^func ([^(]+)\\(")
for line in self.test_suite.get_script().source_code.split("\n"):
if not in_func:
var matched = func_re.search(line)
Expand Down Expand Up @@ -315,26 +346,31 @@ class Runner:
var error_message = self.stderr.get_error_message()

if output == null:
test_results.append({
"name": test_method_name,
"status": "error",
"message": error_message,
})
(
test_results
. append(
{
"name": test_method_name,
"status": "error",
"message": error_message,
}
)
)
else:
var actual = output[0]
var expected = output[1]

var passed = (
typeof(actual) == typeof(expected) and
actual == expected and
error_message.is_empty()
typeof(actual) == typeof(expected)
and actual == expected
and error_message.is_empty()
)

var status = "error"
if error_message.is_empty():
status = "pass" if passed else "fail"
error_message = null if passed else self.get_failed_test_message(
actual, expected
error_message = (
null if passed else self.get_failed_test_message(actual, expected)
)

var test_code = test_codes[method["name"]]
Expand All @@ -346,12 +382,17 @@ class Runner:
test_code = test_code.replace("\t", " ")
test_code = test_code.dedent().strip_edges()

test_results.append({
"name": test_method_name,
"status": status,
"message": error_message,
"test_code": test_code,
})
(
test_results
. append(
{
"name": test_method_name,
"status": status,
"message": error_message,
"test_code": test_code,
}
)
)

return test_results

Expand Down Expand Up @@ -388,9 +429,14 @@ class Runner:
filtered_results.append(test_result)
elif not has_failure:
has_failure = true
test_result["message"] = "Passes %d/%d tests. First failure: %s" % [
success_count, len(test_results), test_result["message"],
]
test_result["message"] = (
"Passes %d/%d tests. First failure: %s"
% [
success_count,
len(test_results),
test_result["message"],
]
)
filtered_results.append(test_result)
results["tests"] = filtered_results

Expand Down Expand Up @@ -426,7 +472,9 @@ func load_solution(path: String) -> Object:
return solution


func load_solution_script(solution_script_path: String, result_writer: ResultWriter, stderr: ErrorReader) -> Array:
func load_solution_script(
solution_script_path: String, result_writer: ResultWriter, stderr: ErrorReader
) -> Array:
"""
Loads the solution script and saves it in a global variable. In case of any
issues, this method will save the `results.json` file with `error` status.
Expand All @@ -442,7 +490,9 @@ func load_solution_script(solution_script_path: String, result_writer: ResultWri
var error_message: String = stderr.get_error_message()
if not error_message.is_empty():
var msg = []
var stop = 'ERROR: Failed to load script "%s" with error "Parse error".' % solution_script_path
var stop = (
'ERROR: Failed to load script "%s" with error "Parse error".' % solution_script_path
)
for line in error_message.split("\n"):
if line == stop:
break
Expand Down
Loading
Loading