neon-sprawl/client/addons/gdUnit4/src/monitor/GodotGdErrorMonitor.gd

123 lines
3.4 KiB
GDScript

class_name GodotGdErrorMonitor
extends GdUnitMonitor
var _logger: GdUnitLogger
class GdUnitLogger extends Logger:
var _entries: Array[ErrorLogEntry] = []
var _line_number: int
var _is_report_push_errors: bool
var _is_report_script_errors: bool
func _init(is_report_push_errors: bool, is_report_script_errors: bool) -> void:
_is_report_push_errors = is_report_push_errors
_is_report_script_errors = is_report_script_errors
OS.add_logger(self)
func entries() -> Array[ErrorLogEntry]:
return _entries
func erase_log_entry(log_entry: ErrorLogEntry) -> void:
for entry in _entries:
if entry._type == log_entry._type and entry._message == log_entry._message:
_entries.erase(entry)
return
func _log_error(
_function: String,
_file: String,
_line: int,
message: String,
_rationale: String,
_editor_notify: bool,
error_type: int,
script_backtraces: Array[ScriptBacktrace]
) -> void:
match error_type:
ErrorType.ERROR_TYPE_WARNING:
if _is_report_push_errors:
var stack_trace := _build_stack_trace(script_backtraces)
_entries.append(ErrorLogEntry.of_push_warning(_line_number, message, stack_trace))
ErrorType.ERROR_TYPE_ERROR:
if _is_report_push_errors:
var stack_trace := _build_stack_trace(script_backtraces)
_entries.append(ErrorLogEntry.of_push_error(_line_number, message, stack_trace))
ErrorType.ERROR_TYPE_SCRIPT:
if _is_report_script_errors:
var stack_trace := _build_stack_trace(script_backtraces)
_entries.append(ErrorLogEntry.of_script_error(_line_number, message, stack_trace))
ErrorType.ERROR_TYPE_SHADER:
pass
_:
prints("Unknwon log type", message)
func _log_message(_message: String, _error: bool) -> void:
pass
func _build_stack_trace(script_backtraces: Array[ScriptBacktrace]) -> PackedStringArray:
for sb in script_backtraces:
for frame in sb.get_frame_count():
# Find start of test stack
if sb.get_frame_file(frame) == "res://addons/gdUnit4/src/core/_TestCase.gd":
var stack_trace := PackedStringArray()
for test_case_frame in range(0, frame):
_line_number = sb.get_frame_line(test_case_frame)
stack_trace.append(" at %s:%s" % [sb.get_frame_file(test_case_frame), sb.get_frame_line(test_case_frame)])
return stack_trace
# if no stack trace collected, we in an await function call
var sb := script_backtraces[0]
return [" at %s:%s" % [sb.get_frame_file(0), sb.get_frame_line(0)]]
func _init() -> void:
super("GdUnitLoggerMonitor")
_logger = GdUnitLogger.new(GdUnitSettings.is_report_push_errors(), GdUnitSettings.is_report_script_errors())
func start() -> void:
clear_logs()
func stop() -> void:
pass
func log_entries() -> Array[ErrorLogEntry]:
return _logger.entries()
func erase_log_entry(log_entry: ErrorLogEntry) -> void:
_logger.erase_log_entry(log_entry)
func to_reports() -> Array[GdUnitReport]:
var reports_: Array[GdUnitReport] = []
reports_.assign(log_entries().map(_to_report))
return reports_
static func _to_report(errorLog: ErrorLogEntry) -> GdUnitReport:
var failure := """
%s
%s %s
%s""".dedent().trim_prefix("\n") % [
GdAssertMessages._error("Godot Runtime Error !"),
GdAssertMessages._error("Error:"),
GdAssertMessages._colored_value(errorLog._message),
GdAssertMessages._colored(errorLog._details, GdAssertMessages.VALUE_COLOR)]
return GdUnitReport.new().create(GdUnitReport.ABORT, errorLog._line, failure)
func clear_logs() -> void:
log_entries().clear()