godot-xterm/addons/gut/logger.gd

425 lines
9.6 KiB
GDScript
Raw Normal View History

# ##############################################################################
#(G)odot (U)nit (T)est class
#
# ##############################################################################
# The MIT License (MIT)
# =====================
#
# Copyright (c) 2020 Tom "Butch" Wesley
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ##############################################################################
# This class wraps around the various printers and supplies formatting for the
# various message types (error, warning, etc).
# ##############################################################################
var types = {
2023-01-20 23:34:39 +01:00
debug = "debug",
deprecated = "deprecated",
error = "error",
failed = "failed",
info = "info",
normal = "normal",
orphan = "orphan",
passed = "passed",
pending = "pending",
2024-01-06 11:27:15 +01:00
risky = "risky",
2023-01-20 23:34:39 +01:00
warn = "warn",
}
var fmts = {
2023-01-20 23:34:39 +01:00
red = "red",
yellow = "yellow",
green = "green",
bold = "bold",
underline = "underline",
none = null
}
var _type_data = {
2023-01-20 23:34:39 +01:00
types.debug: {disp = "DEBUG", enabled = true, fmt = fmts.none},
types.deprecated: {disp = "DEPRECATED", enabled = true, fmt = fmts.none},
types.error: {disp = "ERROR", enabled = true, fmt = fmts.red},
types.failed: {disp = "Failed", enabled = true, fmt = fmts.red},
types.info: {disp = "INFO", enabled = true, fmt = fmts.bold},
types.normal: {disp = "NORMAL", enabled = true, fmt = fmts.none},
types.orphan: {disp = "Orphans", enabled = true, fmt = fmts.yellow},
types.passed: {disp = "Passed", enabled = true, fmt = fmts.green},
types.pending: {disp = "Pending", enabled = true, fmt = fmts.yellow},
2024-01-06 11:27:15 +01:00
types.risky: {disp = "Risky", enabled = true, fmt = fmts.yellow},
2023-01-20 23:34:39 +01:00
types.warn: {disp = "WARNING", enabled = true, fmt = fmts.yellow},
}
var _logs = {
types.warn: [],
types.error: [],
types.info: [],
types.debug: [],
types.deprecated: [],
}
2023-01-20 23:34:39 +01:00
var _printers = {terminal = null, gui = null, console = null}
var _gut = null
var _utils = null
var _indent_level = 0
2024-01-06 11:27:15 +01:00
var _min_indent_level = 0
2023-01-20 23:34:39 +01:00
var _indent_string = " "
var _skip_test_name_for_testing = false
var _less_test_names = false
var _yield_calls = 0
2023-01-20 23:34:39 +01:00
var _last_yield_text = ""
func _init():
2023-01-20 23:34:39 +01:00
_utils = load("res://addons/gut/utils.gd").get_instance()
_printers.terminal = _utils.Printers.TerminalPrinter.new()
_printers.console = _utils.Printers.ConsolePrinter.new()
# There were some problems in the timing of disabling this at the right
# time in gut_cmdln so it is disabled by default. This is enabled
# by plugin_control.gd based on settings.
_printers.console.set_disabled(true)
2023-01-20 23:34:39 +01:00
func get_indent_text():
2023-01-20 23:34:39 +01:00
var pad = ""
for i in range(_indent_level):
pad += _indent_string
return pad
2023-01-20 23:34:39 +01:00
func _indent_text(text):
var to_return = text
2023-01-20 23:34:39 +01:00
var ending_newline = ""
2023-01-20 23:34:39 +01:00
if text.ends_with("\n"):
ending_newline = "\n"
2023-01-20 23:34:39 +01:00
to_return = to_return.left(to_return.length() - 1)
var pad = get_indent_text()
to_return = to_return.replace("\n", "\n" + pad)
to_return += ending_newline
return pad + to_return
2023-01-20 23:34:39 +01:00
func _should_print_to_printer(key_name):
return _printers[key_name] != null and !_printers[key_name].get_disabled()
2023-01-20 23:34:39 +01:00
func _print_test_name():
2023-01-20 23:34:39 +01:00
if _gut == null:
return
var cur_test = _gut.get_current_test_object()
2023-01-20 23:34:39 +01:00
if cur_test == null:
return false
2023-01-20 23:34:39 +01:00
if !cur_test.has_printed_name:
2024-01-06 11:27:15 +01:00
var param_text = ""
if cur_test.arg_count > 0:
# Just an FYI, parameter_handler in gut might not be set yet so can't
# use it here for cooler output.
param_text = "<parameterized>"
_output(str("* ", cur_test.name, param_text, "\n"))
cur_test.has_printed_name = true
2023-01-20 23:34:39 +01:00
func _output(text, fmt = null):
for key in _printers:
2023-01-20 23:34:39 +01:00
if _should_print_to_printer(key):
var info = "" #str(self, ':', key, ':', _printers[key], '| ')
_printers[key].send(info + text, fmt)
2023-01-20 23:34:39 +01:00
func _log(text, fmt = fmts.none):
_print_test_name()
var indented = _indent_text(text)
_output(indented, fmt)
2023-01-20 23:34:39 +01:00
# ---------------
# Get Methods
# ---------------
func get_warnings():
return get_log_entries(types.warn)
2023-01-20 23:34:39 +01:00
func get_errors():
return get_log_entries(types.error)
2023-01-20 23:34:39 +01:00
func get_infos():
return get_log_entries(types.info)
2023-01-20 23:34:39 +01:00
func get_debugs():
return get_log_entries(types.debug)
2023-01-20 23:34:39 +01:00
func get_deprecated():
return get_log_entries(types.deprecated)
2023-01-20 23:34:39 +01:00
func get_count(log_type = null):
var count = 0
2023-01-20 23:34:39 +01:00
if log_type == null:
for key in _logs:
count += _logs[key].size()
else:
count = _logs[log_type].size()
return count
2023-01-20 23:34:39 +01:00
func get_log_entries(log_type):
return _logs[log_type]
2023-01-20 23:34:39 +01:00
# ---------------
# Log methods
# ---------------
func _output_type(type, text):
var td = _type_data[type]
2023-01-20 23:34:39 +01:00
if !td.enabled:
return
_print_test_name()
2023-01-20 23:34:39 +01:00
if type != types.normal:
if _logs.has(type):
_logs[type].append(text)
2023-01-20 23:34:39 +01:00
var start = str("[", td.disp, "]")
if text != null and text != "":
start += ": "
else:
2023-01-20 23:34:39 +01:00
start += " "
var indented_start = _indent_text(start)
var indented_end = _indent_text(text)
indented_end = indented_end.lstrip(_indent_string)
_output(indented_start, td.fmt)
_output(indented_end + "\n")
2023-01-20 23:34:39 +01:00
func debug(text):
_output_type(types.debug, text)
2023-01-20 23:34:39 +01:00
# supply some text or the name of the deprecated method and the replacement.
2023-01-20 23:34:39 +01:00
func deprecated(text, alt_method = null):
var msg = text
2023-01-20 23:34:39 +01:00
if alt_method:
msg = str("The method ", text, " is deprecated, use ", alt_method, " instead.")
return _output_type(types.deprecated, msg)
2023-01-20 23:34:39 +01:00
func error(text):
_output_type(types.error, text)
2024-01-06 11:27:15 +01:00
if _gut != null:
_gut._fail_for_error(text)
2023-01-20 23:34:39 +01:00
func failed(text):
_output_type(types.failed, text)
2023-01-20 23:34:39 +01:00
func info(text):
_output_type(types.info, text)
2023-01-20 23:34:39 +01:00
func orphan(text):
_output_type(types.orphan, text)
2023-01-20 23:34:39 +01:00
func passed(text):
_output_type(types.passed, text)
2023-01-20 23:34:39 +01:00
func pending(text):
_output_type(types.pending, text)
2023-01-20 23:34:39 +01:00
2024-01-06 11:27:15 +01:00
func risky(text):
_output_type(types.risky, text)
func warn(text):
_output_type(types.warn, text)
2023-01-20 23:34:39 +01:00
func log(text = "", fmt = fmts.none):
end_yield()
2023-01-20 23:34:39 +01:00
if text == "":
_output("\n")
else:
_log(text + "\n", fmt)
return null
2023-01-20 23:34:39 +01:00
func lograw(text, fmt = fmts.none):
return _output(text, fmt)
2023-01-20 23:34:39 +01:00
# Print the test name if we aren't skipping names of tests that pass (basically
# what _less_test_names means))
func log_test_name():
# suppress output if we haven't printed the test name yet and
# what to print is the test name.
2023-01-20 23:34:39 +01:00
if !_less_test_names:
_print_test_name()
2023-01-20 23:34:39 +01:00
# ---------------
# Misc
# ---------------
func get_gut():
return _gut
2023-01-20 23:34:39 +01:00
func set_gut(gut):
_gut = gut
2023-01-20 23:34:39 +01:00
if _gut == null:
_printers.gui = null
else:
2023-01-20 23:34:39 +01:00
if _printers.gui == null:
_printers.gui = _utils.Printers.GutGuiPrinter.new()
func get_indent_level():
return _indent_level
2023-01-20 23:34:39 +01:00
func set_indent_level(indent_level):
2024-01-06 11:27:15 +01:00
_indent_level = max(_min_indent_level, indent_level)
2023-01-20 23:34:39 +01:00
func get_indent_string():
return _indent_string
2023-01-20 23:34:39 +01:00
func set_indent_string(indent_string):
_indent_string = indent_string
2023-01-20 23:34:39 +01:00
func clear():
for key in _logs:
_logs[key].clear()
2023-01-20 23:34:39 +01:00
func inc_indent():
_indent_level += 1
2023-01-20 23:34:39 +01:00
func dec_indent():
2024-01-06 11:27:15 +01:00
_indent_level = max(_min_indent_level, _indent_level - 1)
2023-01-20 23:34:39 +01:00
func is_type_enabled(type):
return _type_data[type].enabled
2023-01-20 23:34:39 +01:00
func set_type_enabled(type, is_enabled):
_type_data[type].enabled = is_enabled
2023-01-20 23:34:39 +01:00
func get_less_test_names():
return _less_test_names
2023-01-20 23:34:39 +01:00
func set_less_test_names(less_test_names):
_less_test_names = less_test_names
2023-01-20 23:34:39 +01:00
func disable_printer(name, is_disabled):
_printers[name].set_disabled(is_disabled)
2023-01-20 23:34:39 +01:00
func is_printer_disabled(name):
return _printers[name].get_disabled()
2023-01-20 23:34:39 +01:00
func disable_formatting(is_disabled):
for key in _printers:
_printers[key].set_format_enabled(!is_disabled)
2023-01-20 23:34:39 +01:00
func disable_all_printers(is_disabled):
for p in _printers:
disable_printer(p, is_disabled)
2023-01-20 23:34:39 +01:00
func get_printer(printer_key):
return _printers[printer_key]
2023-01-20 23:34:39 +01:00
func _yield_text_terminal(text):
2023-01-20 23:34:39 +01:00
var printer = _printers["terminal"]
if _yield_calls != 0:
printer.clear_line()
printer.back(_last_yield_text.length())
printer.send(text, fmts.yellow)
2023-01-20 23:34:39 +01:00
func _end_yield_terminal():
2023-01-20 23:34:39 +01:00
var printer = _printers["terminal"]
printer.clear_line()
printer.back(_last_yield_text.length())
2023-01-20 23:34:39 +01:00
func _yield_text_gui(text):
pass
# var lbl = _gut.get_gui().get_waiting_label()
# lbl.visible = true
# lbl.set_bbcode('[color=yellow]' + text + '[/color]')
2023-01-20 23:34:39 +01:00
func _end_yield_gui():
pass
# var lbl = _gut.get_gui().get_waiting_label()
# lbl.visible = false
# lbl.set_text('')
2023-01-20 23:34:39 +01:00
# This is used for displaying the "yield detected" and "yielding to" messages.
func yield_msg(text):
2023-01-20 23:34:39 +01:00
if _type_data.warn.enabled:
self.log(text, fmts.yellow)
2023-01-20 23:34:39 +01:00
# This is used for the animated "waiting" message
func yield_text(text):
_yield_text_terminal(text)
_yield_text_gui(text)
_last_yield_text = text
_yield_calls += 1
2023-01-20 23:34:39 +01:00
# This is used for the animated "waiting" message
func end_yield():
2023-01-20 23:34:39 +01:00
if _yield_calls == 0:
return
_end_yield_terminal()
_end_yield_gui()
_yield_calls = 0
2023-01-20 23:34:39 +01:00
_last_yield_text = ""
func get_gui_bbcode():
return _printers.gui.get_bbcode()