From e563a15ce273cd5a7431a8cecd06f9c00bee4495 Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Sat, 21 Jan 2023 11:34:39 +1300 Subject: [PATCH] Format files using GDScript Toolkit --- addons/godot_xterm/util/tput.gd | 2 +- addons/gut/GutScene.gd | 90 +- addons/gut/UserFileViewer.gd | 22 +- addons/gut/autofree.gd | 15 +- addons/gut/awaiter.gd | 27 +- addons/gut/comparator.gd | 86 +- addons/gut/compare_result.gd | 29 +- addons/gut/diff_formatter.gd | 41 +- addons/gut/diff_tool.gd | 104 +- addons/gut/double_tools.gd | 32 +- addons/gut/doubler.gd | 152 ++- addons/gut/gui/BottomPanelShortcuts.gd | 38 +- addons/gut/gui/GutBottomPanel.gd | 159 +-- addons/gut/gui/GutRunner.gd | 67 +- addons/gut/gui/OutputText.gd | 117 +- addons/gut/gui/RunAtCursor.gd | 21 +- addons/gut/gui/RunResults.gd | 270 +++-- addons/gut/gui/ShortcutButton.gd | 49 +- addons/gut/gui/gut_config_gui.gd | 317 ++++-- addons/gut/gui/script_text_editor_controls.gd | 78 +- addons/gut/gut.gd | 626 +++++----- addons/gut/gut_cmdln.gd | 317 ++++-- addons/gut/gut_config.gd | 81 +- addons/gut/gut_plugin.gd | 4 +- addons/gut/gut_to_move.gd | 28 +- addons/gut/hook_script.gd | 20 +- addons/gut/inner_class_registry.gd | 27 +- addons/gut/input_factory.gd | 32 +- addons/gut/input_sender.gd | 121 +- addons/gut/junit_xml_export.gd | 25 +- addons/gut/logger.gd | 189 ++-- addons/gut/method_maker.gd | 210 ++-- addons/gut/one_to_many.gd | 17 +- addons/gut/optparse.gd | 88 +- addons/gut/orphan_counter.gd | 14 +- addons/gut/parameter_factory.gd | 4 +- addons/gut/parameter_handler.gd | 19 +- addons/gut/printers.gd | 76 +- addons/gut/result_exporter.gd | 75 +- addons/gut/script_parser.gd | 212 ++-- addons/gut/signal_watcher.gd | 104 +- addons/gut/spy.gd | 79 +- addons/gut/strutils.gd | 149 +-- addons/gut/stub_params.gd | 70 +- addons/gut/stubber.gd | 93 +- addons/gut/summary.gd | 105 +- addons/gut/test.gd | 1005 +++++++++++------ addons/gut/test_collector.gd | 144 +-- addons/gut/thing_counter.gd | 14 +- addons/gut/utils.gd | 232 ++-- test/integration/terminal.test.gd | 7 +- test/platform/unix/unix.test.gd | 10 +- 52 files changed, 3459 insertions(+), 2454 deletions(-) diff --git a/addons/godot_xterm/util/tput.gd b/addons/godot_xterm/util/tput.gd index 27a77e8..b6a4c80 100644 --- a/addons/godot_xterm/util/tput.gd +++ b/addons/godot_xterm/util/tput.gd @@ -39,7 +39,7 @@ class ANSIColor: func _init(): # "ANSIColor is an abstract class. You should only use the color constants (e.g. ANSIColor.black)." assert(false) - + var terminal diff --git a/addons/gut/GutScene.gd b/addons/gut/GutScene.gd index d13b4d8..ba84e99 100644 --- a/addons/gut/GutScene.gd +++ b/addons/gut/GutScene.gd @@ -20,24 +20,23 @@ class GuiHandler: _gui = gui # Brute force, but flexible. - _ctrls.btn_continue = _get_first_child_named('Continue', _gui) - _ctrls.path_dir = _get_first_child_named('Path', _gui) - _ctrls.path_file = _get_first_child_named('File', _gui) - _ctrls.prog_script = _get_first_child_named('ProgressScript', _gui) - _ctrls.prog_test = _get_first_child_named('ProgressTest', _gui) - _ctrls.rtl = _get_first_child_named('Output', _gui) - _ctrls.rtl_bg = _get_first_child_named('OutputBG', _gui) - _ctrls.time_label = _get_first_child_named('TimeLabel', _gui) + _ctrls.btn_continue = _get_first_child_named("Continue", _gui) + _ctrls.path_dir = _get_first_child_named("Path", _gui) + _ctrls.path_file = _get_first_child_named("File", _gui) + _ctrls.prog_script = _get_first_child_named("ProgressScript", _gui) + _ctrls.prog_test = _get_first_child_named("ProgressTest", _gui) + _ctrls.rtl = _get_first_child_named("Output", _gui) + _ctrls.rtl_bg = _get_first_child_named("OutputBG", _gui) + _ctrls.time_label = _get_first_child_named("TimeLabel", _gui) _ctrls.btn_continue.visible = false _ctrls.btn_continue.pressed.connect(_on_continue_pressed) _ctrls.prog_script.value = 0 _ctrls.prog_test.value = 0 - _ctrls.path_dir.text = '' - _ctrls.path_file.text = '' - _ctrls.time_label.text = '' - + _ctrls.path_dir.text = "" + _ctrls.path_file.text = "" + _ctrls.time_label.text = "" # ------------------ # Events @@ -46,55 +45,49 @@ class GuiHandler: _ctrls.btn_continue.visible = false _gut.end_teardown_pause() - func _on_gut_start_run(): - if(_ctrls.rtl != null): + if _ctrls.rtl != null: _ctrls.rtl.clear() set_num_scripts(_gut.get_test_collector().scripts.size()) - func _on_gut_end_run(): - _ctrls.time_label.text = '' - + _ctrls.time_label.text = "" func _on_gut_start_script(script_obj): next_script(script_obj.get_full_name(), script_obj.tests.size()) - func _on_gut_end_script(): pass - func _on_gut_start_test(test_name): next_test(test_name) - func _on_gut_end_test(): pass - func _on_gut_start_pause(): pause_before_teardown() func _on_gut_end_pause(): pass + # ------------------ # Private # ------------------ func _get_first_child_named(obj_name, parent_obj): - if(parent_obj == null): + if parent_obj == null: return null var kids = parent_obj.get_children() var index = 0 var to_return = null - while(index < kids.size() and to_return == null): - if(str(kids[index]).find(str(obj_name, ':')) != -1): + while index < kids.size() and to_return == null: + if str(kids[index]).find(str(obj_name, ":")) != -1: to_return = kids[index] else: to_return = _get_first_child_named(obj_name, kids[index]) - if(to_return == null): + if to_return == null: index += 1 return to_return @@ -106,7 +99,6 @@ class GuiHandler: _ctrls.prog_script.value = 0 _ctrls.prog_script.max_value = val - func next_script(path, num_tests): _ctrls.prog_script.value += 1 _ctrls.prog_test.value = 0 @@ -115,15 +107,12 @@ class GuiHandler: _ctrls.path_dir.text = path.get_base_dir() _ctrls.path_file.text = path.get_file() - func next_test(test_name): _ctrls.prog_test.value += 1 - func pause_before_teardown(): _ctrls.btn_continue.visible = true - func set_gut(g): _gut = g g.start_run.connect(_on_gut_start_run) @@ -142,17 +131,17 @@ class GuiHandler: return _ctrls.rtl func set_elapsed_time(t): - _ctrls.time_label.text = str(t, 's') - + _ctrls.time_label.text = str(t, "s") func set_bg_color(c): _ctrls.rtl_bg.color = c + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ var _large_handler = null var _min_handler = null -var gut = null : +var gut = null: set(val): gut = val _set_gut(val) @@ -165,31 +154,36 @@ func _ready(): $Min.visible = false $Large.visible = !$Min.visible + func _process(_delta): - if(gut != null and gut.is_running()): + if gut != null and gut.is_running(): _large_handler.set_elapsed_time(gut.get_elapsed_time()) _min_handler.set_elapsed_time(gut.get_elapsed_time()) + func _set_gut(val): _large_handler.set_gut(val) _min_handler.set_gut(val) + func get_textbox(): return _large_handler.get_textbox() func set_font_size(new_size): var rtl = _large_handler.get_textbox() - if(rtl.get('custom_fonts/normal_font') != null): - rtl.get('custom_fonts/bold_italics_font').size = new_size - rtl.get('custom_fonts/bold_font').size = new_size - rtl.get('custom_fonts/italics_font').size = new_size - rtl.get('custom_fonts/normal_font').size = new_size + if rtl.get("custom_fonts/normal_font") != null: + rtl.get("custom_fonts/bold_italics_font").size = new_size + rtl.get("custom_fonts/bold_font").size = new_size + rtl.get("custom_fonts/italics_font").size = new_size + rtl.get("custom_fonts/normal_font").size = new_size + func set_font(font_name): pass #_set_all_fonts_in_rtl(_large_handler.get_textbox(), font_name) + # Needs rework for 4.0, DynamicFont DNE func _set_font(rtl, font_name, custom_name): pass @@ -205,20 +199,20 @@ func _set_font(rtl, font_name, custom_name): func _set_all_fonts_in_rtl(rtl, base_name): - if(base_name == 'Default'): - _set_font(rtl, null, 'normal_font') - _set_font(rtl, null, 'bold_font') - _set_font(rtl, null, 'italics_font') - _set_font(rtl, null, 'bold_italics_font') + if base_name == "Default": + _set_font(rtl, null, "normal_font") + _set_font(rtl, null, "bold_font") + _set_font(rtl, null, "italics_font") + _set_font(rtl, null, "bold_italics_font") else: - _set_font(rtl, base_name + '-Regular', 'normal_font') - _set_font(rtl, base_name + '-Bold', 'bold_font') - _set_font(rtl, base_name + '-Italic', 'italics_font') - _set_font(rtl, base_name + '-BoldItalic', 'bold_italics_font') + _set_font(rtl, base_name + "-Regular", "normal_font") + _set_font(rtl, base_name + "-Bold", "bold_font") + _set_font(rtl, base_name + "-Italic", "italics_font") + _set_font(rtl, base_name + "-BoldItalic", "bold_italics_font") func set_default_font_color(color): - _large_handler.get_textbox().set('custom_colors/default_color', color) + _large_handler.get_textbox().set("custom_colors/default_color", color) func set_background_color(color): diff --git a/addons/gut/UserFileViewer.gd b/addons/gut/UserFileViewer.gd index b56703c..ed81a63 100644 --- a/addons/gut/UserFileViewer.gd +++ b/addons/gut/UserFileViewer.gd @@ -2,50 +2,62 @@ extends Window @onready var rtl = $TextDisplay/RichTextLabel + func _get_file_as_text(path): var to_return = null var f = FileAccess.open(path, FileAccess.READ) - if(f != null): + if f != null: to_return = f.get_as_text() else: - to_return = str('ERROR: Could not open file. Error code ', FileAccess.get_open_error()) + to_return = str("ERROR: Could not open file. Error code ", FileAccess.get_open_error()) return to_return + func _ready(): rtl.clear() + func _on_OpenFile_pressed(): $FileDialog.popup_centered() + func _on_FileDialog_file_selected(path): show_file(path) + func _on_Close_pressed(): self.hide() + func show_file(path): var text = _get_file_as_text(path) - if(text == ''): - text = '' + if text == "": + text = "" rtl.set_text(text) self.window_title = path + func show_open(): self.popup_centered() $FileDialog.popup_centered() + func get_rich_text_label(): return $TextDisplay/RichTextLabel + func _on_Home_pressed(): rtl.scroll_to_line(0) + func _on_End_pressed(): - rtl.scroll_to_line(rtl.get_line_count() -1) + rtl.scroll_to_line(rtl.get_line_count() - 1) + func _on_Copy_pressed(): OS.clipboard = rtl.text + func _on_file_dialog_visibility_changed(): if rtl.text.length() == 0 and not $FileDialog.visible: self.hide() diff --git a/addons/gut/autofree.gd b/addons/gut/autofree.gd index b82676b..5dae4ab 100644 --- a/addons/gut/autofree.gd +++ b/addons/gut/autofree.gd @@ -31,29 +31,32 @@ var _to_free = [] var _to_queue_free = [] + func add_free(thing): - if(typeof(thing) == TYPE_OBJECT): - if(!thing is RefCounted): + if typeof(thing) == TYPE_OBJECT: + if !thing is RefCounted: _to_free.append(thing) + func add_queue_free(thing): _to_queue_free.append(thing) + func get_queue_free_count(): return _to_queue_free.size() + func get_free_count(): return _to_free.size() + func free_all(): for i in range(_to_free.size()): - if(is_instance_valid(_to_free[i])): + if is_instance_valid(_to_free[i]): _to_free[i].free() _to_free.clear() for i in range(_to_queue_free.size()): - if(is_instance_valid(_to_queue_free[i])): + if is_instance_valid(_to_queue_free[i]): _to_queue_free[i].queue_free() _to_queue_free.clear() - - diff --git a/addons/gut/awaiter.gd b/addons/gut/awaiter.gd index 4d568a2..d8e1c2c 100644 --- a/addons/gut/awaiter.gd +++ b/addons/gut/awaiter.gd @@ -12,14 +12,14 @@ var _elapsed_frames = 0 func _physics_process(delta): - if(_wait_time != 0.0): + if _wait_time != 0.0: _elapsed_time += delta - if(_elapsed_time >= _wait_time): + if _elapsed_time >= _wait_time: _end_wait() - if(_wait_frames != 0): + if _wait_frames != 0: _elapsed_frames += 1 - if(_elapsed_frames >= _wait_frames): + if _elapsed_frames >= _wait_frames: _end_wait() @@ -32,12 +32,20 @@ func _end_wait(): timeout.emit() -const ARG_NOT_SET = '_*_argument_*_is_*_not_set_*_' -func _signal_callback( - arg1=ARG_NOT_SET, arg2=ARG_NOT_SET, arg3=ARG_NOT_SET, - arg4=ARG_NOT_SET, arg5=ARG_NOT_SET, arg6=ARG_NOT_SET, - arg7=ARG_NOT_SET, arg8=ARG_NOT_SET, arg9=ARG_NOT_SET): +const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_" + +func _signal_callback( + arg1 = ARG_NOT_SET, + arg2 = ARG_NOT_SET, + arg3 = ARG_NOT_SET, + arg4 = ARG_NOT_SET, + arg5 = ARG_NOT_SET, + arg6 = ARG_NOT_SET, + arg7 = ARG_NOT_SET, + arg8 = ARG_NOT_SET, + arg9 = ARG_NOT_SET +): _signal_to_wait_on.disconnect(_signal_callback) # DO NOT _end_wait here. For other parts of the test to get the signal that # was waited on, we have to wait for a couple more frames. For example, the @@ -64,4 +72,3 @@ func wait_for_signal(the_signal, x): func is_waiting(): return _wait_time != 0.0 || _wait_frames != 0 - diff --git a/addons/gut/comparator.gd b/addons/gut/comparator.gd index c85f289..37e3e10 100644 --- a/addons/gut/comparator.gd +++ b/addons/gut/comparator.gd @@ -1,85 +1,93 @@ -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _strutils = _utils.Strutils.new() var _max_length = 100 var _should_compare_int_to_float = true -const MISSING = '|__missing__gut__compare__value__|' -const DICTIONARY_DISCLAIMER = 'Dictionaries are compared-by-ref. See assert_eq in wiki.' +const MISSING = "|__missing__gut__compare__value__|" +const DICTIONARY_DISCLAIMER = "Dictionaries are compared-by-ref. See assert_eq in wiki." + func _cannot_compare_text(v1, v2): - return str('Cannot compare ', _strutils.types[typeof(v1)], ' with ', - _strutils.types[typeof(v2)], '.') + return str( + "Cannot compare ", _strutils.types[typeof(v1)], " with ", _strutils.types[typeof(v2)], "." + ) + func _make_missing_string(text): - return '' + return "" + func _create_missing_result(v1, v2, text): var to_return = null var v1_str = format_value(v1) var v2_str = format_value(v2) - if(typeof(v1) == TYPE_STRING and v1 == MISSING): + if typeof(v1) == TYPE_STRING and v1 == MISSING: v1_str = _make_missing_string(text) to_return = _utils.CompareResult.new() - elif(typeof(v2) == TYPE_STRING and v2 == MISSING): + elif typeof(v2) == TYPE_STRING and v2 == MISSING: v2_str = _make_missing_string(text) to_return = _utils.CompareResult.new() - if(to_return != null): - to_return.summary = str(v1_str, ' != ', v2_str) + if to_return != null: + to_return.summary = str(v1_str, " != ", v2_str) to_return.are_equal = false return to_return -func simple(v1, v2, missing_string=''): +func simple(v1, v2, missing_string = ""): var missing_result = _create_missing_result(v1, v2, missing_string) - if(missing_result != null): + if missing_result != null: return missing_result var result = _utils.CompareResult.new() var cmp_str = null - var extra = '' + var extra = "" var tv1 = typeof(v1) var tv2 = typeof(v2) # print(tv1, '::', tv2, ' ', _strutils.types[tv1], '::', _strutils.types[tv2]) - if(_should_compare_int_to_float and [TYPE_INT, TYPE_FLOAT].has(tv1) and [TYPE_INT, TYPE_FLOAT].has(tv2)): + if ( + _should_compare_int_to_float + and [TYPE_INT, TYPE_FLOAT].has(tv1) + and [TYPE_INT, TYPE_FLOAT].has(tv2) + ): result.are_equal = v1 == v2 - elif([TYPE_STRING, TYPE_STRING_NAME].has(tv1) and [TYPE_STRING, TYPE_STRING_NAME].has(tv2)): + elif [TYPE_STRING, TYPE_STRING_NAME].has(tv1) and [TYPE_STRING, TYPE_STRING_NAME].has(tv2): result.are_equal = v1 == v2 - elif(_utils.are_datatypes_same(v1, v2)): + elif _utils.are_datatypes_same(v1, v2): result.are_equal = v1 == v2 - if(typeof(v1) == TYPE_DICTIONARY): - if(result.are_equal): - extra = '. Same dictionary ref. ' + if typeof(v1) == TYPE_DICTIONARY: + if result.are_equal: + extra = ". Same dictionary ref. " else: - extra = '. Different dictionary refs. ' + extra = ". Different dictionary refs. " extra += DICTIONARY_DISCLAIMER - if(typeof(v1) == TYPE_ARRAY): + if typeof(v1) == TYPE_ARRAY: var array_result = _utils.DiffTool.new(v1, v2, _utils.DIFF.SHALLOW) result.summary = array_result.get_short_summary() - if(!array_result.are_equal): + if !array_result.are_equal: extra = ".\n" + array_result.get_short_summary() else: - cmp_str = '!=' + cmp_str = "!=" result.are_equal = false - extra = str('. ', _cannot_compare_text(v1, v2)) + extra = str(". ", _cannot_compare_text(v1, v2)) cmp_str = get_compare_symbol(result.are_equal) - result.summary = str(format_value(v1), ' ', cmp_str, ' ', format_value(v2), extra) + result.summary = str(format_value(v1), " ", cmp_str, " ", format_value(v2), extra) return result func shallow(v1, v2): - var result = null + var result = null - if(_utils.are_datatypes_same(v1, v2)): - if(typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]): + if _utils.are_datatypes_same(v1, v2): + if typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]: result = _utils.DiffTool.new(v1, v2, _utils.DIFF.SHALLOW) else: result = simple(v1, v2) @@ -90,10 +98,10 @@ func shallow(v1, v2): func deep(v1, v2): - var result = null + var result = null - if(_utils.are_datatypes_same(v1, v2)): - if(typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]): + if _utils.are_datatypes_same(v1, v2): + if typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]: result = _utils.DiffTool.new(v1, v2, _utils.DIFF.DEEP) else: result = simple(v1, v2) @@ -103,17 +111,17 @@ func deep(v1, v2): return result -func format_value(val, max_val_length=_max_length): +func format_value(val, max_val_length = _max_length): return _strutils.truncate_string(_strutils.type2str(val), max_val_length) -func compare(v1, v2, diff_type=_utils.DIFF.SIMPLE): +func compare(v1, v2, diff_type = _utils.DIFF.SIMPLE): var result = null - if(diff_type == _utils.DIFF.SIMPLE): + if diff_type == _utils.DIFF.SIMPLE: result = simple(v1, v2) - elif(diff_type == _utils.DIFF.SHALLOW): + elif diff_type == _utils.DIFF.SHALLOW: result = shallow(v1, v2) - elif(diff_type == _utils.DIFF.DEEP): + elif diff_type == _utils.DIFF.DEEP: result = deep(v1, v2) return result @@ -128,7 +136,7 @@ func set_should_compare_int_to_float(should_compare_int_float): func get_compare_symbol(is_equal): - if(is_equal): - return '==' + if is_equal: + return "==" else: - return '!=' + return "!=" diff --git a/addons/gut/compare_result.gd b/addons/gut/compare_result.gd index 1a8afb5..382bc5f 100644 --- a/addons/gut/compare_result.gd +++ b/addons/gut/compare_result.gd @@ -1,70 +1,83 @@ var _are_equal = false -var are_equal = false : +var are_equal = false: get: return get_are_equal() set(val): set_are_equal(val) var _summary = null -var summary = null : +var summary = null: get: return get_summary() set(val): set_summary(val) var _max_differences = 30 -var max_differences = 30 : +var max_differences = 30: get: return get_max_differences() set(val): set_max_differences(val) var _differences = {} -var differences : +var differences: get: return get_differences() set(val): set_differences(val) + func _block_set(which, val): - push_error(str('cannot set ', which, ', value [', val, '] ignored.')) + push_error(str("cannot set ", which, ", value [", val, "] ignored.")) + func _to_string(): - return str(get_summary()) # could be null, gotta str it. + return str(get_summary()) # could be null, gotta str it. + func get_are_equal(): return _are_equal + func set_are_equal(r_eq): _are_equal = r_eq + func get_summary(): return _summary + func set_summary(smry): _summary = smry + func get_total_count(): pass + func get_different_count(): pass + func get_short_summary(): return summary + func get_max_differences(): return _max_differences + func set_max_differences(max_diff): _max_differences = max_diff + func get_differences(): return _differences + func set_differences(diffs): - _block_set('differences', diffs) + _block_set("differences", diffs) + func get_brackets(): return null - diff --git a/addons/gut/diff_formatter.gd b/addons/gut/diff_formatter.gd index fd954af..b07d9e2 100644 --- a/addons/gut/diff_formatter.gd +++ b/addons/gut/diff_formatter.gd @@ -1,20 +1,24 @@ -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _strutils = _utils.Strutils.new() -const INDENT = ' ' +const INDENT = " " var _max_to_display = 30 const ABSOLUTE_MAX_DISPLAYED = 10000 const UNLIMITED = -1 -func _single_diff(diff, depth=0): +func _single_diff(diff, depth = 0): var to_return = "" var brackets = diff.get_brackets() - if(brackets != null and !diff.are_equal): - to_return = '' - to_return += str(brackets.open, "\n", - _strutils.indent_text(differences_to_s(diff.differences, depth), depth+1, INDENT), "\n", - brackets.close) + if brackets != null and !diff.are_equal: + to_return = "" + to_return += str( + brackets.open, + "\n", + _strutils.indent_text(differences_to_s(diff.differences, depth), depth + 1, INDENT), + "\n", + brackets.close + ) else: to_return = str(diff) @@ -22,20 +26,20 @@ func _single_diff(diff, depth=0): func make_it(diff): - var to_return = '' - if(diff.are_equal): + var to_return = "" + if diff.are_equal: to_return = diff.summary else: - if(_max_to_display == ABSOLUTE_MAX_DISPLAYED): - to_return = str(diff.get_value_1(), ' != ', diff.get_value_2()) + if _max_to_display == ABSOLUTE_MAX_DISPLAYED: + to_return = str(diff.get_value_1(), " != ", diff.get_value_2()) else: to_return = diff.get_short_summary() - to_return += str("\n", _strutils.indent_text(_single_diff(diff, 0), 1, ' ')) + to_return += str("\n", _strutils.indent_text(_single_diff(diff, 0), 1, " ")) return to_return -func differences_to_s(differences, depth=0): - var to_return = '' +func differences_to_s(differences, depth = 0): + var to_return = "" var keys = differences.keys() keys.sort() var limit = min(_max_to_display, differences.size()) @@ -44,10 +48,10 @@ func differences_to_s(differences, depth=0): var key = keys[i] to_return += str(key, ": ", _single_diff(differences[key], depth)) - if(i != limit -1): + if i != limit - 1: to_return += "\n" - if(differences.size() > _max_to_display): + if differences.size() > _max_to_display: to_return += str("\n\n... ", differences.size() - _max_to_display, " more.") return to_return @@ -59,6 +63,5 @@ func get_max_to_display(): func set_max_to_display(max_to_display): _max_to_display = max_to_display - if(_max_to_display == UNLIMITED): + if _max_to_display == UNLIMITED: _max_to_display = ABSOLUTE_MAX_DISPLAYED - diff --git a/addons/gut/diff_tool.gd b/addons/gut/diff_tool.gd index d4c1374..0ad91ed 100644 --- a/addons/gut/diff_tool.gd +++ b/addons/gut/diff_tool.gd @@ -1,15 +1,11 @@ -extends 'res://addons/gut/compare_result.gd' -const INDENT = ' ' -enum { - DEEP, - SHALLOW, - SIMPLE -} +extends "res://addons/gut/compare_result.gd" +const INDENT = " " +enum { DEEP, SHALLOW, SIMPLE } -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _strutils = _utils.Strutils.new() var _compare = _utils.Comparator.new() -var DiffTool = load('res://addons/gut/diff_tool.gd') +var DiffTool = load("res://addons/gut/diff_tool.gd") var _value_1 = null var _value_2 = null @@ -17,42 +13,62 @@ var _total_count = 0 var _diff_type = null var _brackets = null var _valid = true -var _desc_things = 'somethings' +var _desc_things = "somethings" + # -------- comapre_result.gd "interface" --------------------- func set_are_equal(val): - _block_set('are_equal', val) + _block_set("are_equal", val) + func get_are_equal(): - if(!_valid): + if !_valid: return null else: return differences.size() == 0 func set_summary(val): - _block_set('summary', val) + _block_set("summary", val) + func get_summary(): return summarize() + func get_different_count(): return differences.size() -func get_total_count(): + +func get_total_count(): return _total_count + func get_short_summary(): - var text = str(_strutils.truncate_string(str(_value_1), 50), - ' ', _compare.get_compare_symbol(are_equal), ' ', - _strutils.truncate_string(str(_value_2), 50)) - if(!are_equal): - text += str(' ', get_different_count(), ' of ', get_total_count(), - ' ', _desc_things, ' do not match.') + var text = str( + _strutils.truncate_string(str(_value_1), 50), + " ", + _compare.get_compare_symbol(are_equal), + " ", + _strutils.truncate_string(str(_value_2), 50) + ) + if !are_equal: + text += str( + " ", + get_different_count(), + " of ", + get_total_count(), + " ", + _desc_things, + " do not match." + ) return text + func get_brackets(): return _brackets + + # -------- comapre_result.gd "interface" --------------------- @@ -61,7 +77,7 @@ func _invalidate(): differences = null -func _init(v1,v2,diff_type=DEEP): +func _init(v1, v2, diff_type = DEEP): _value_1 = v1 _value_2 = v2 _diff_type = diff_type @@ -70,41 +86,41 @@ func _init(v1,v2,diff_type=DEEP): func _find_differences(v1, v2): - if(_utils.are_datatypes_same(v1, v2)): - if(typeof(v1) == TYPE_ARRAY): - _brackets = {'open':'[', 'close':']'} - _desc_things = 'indexes' + if _utils.are_datatypes_same(v1, v2): + if typeof(v1) == TYPE_ARRAY: + _brackets = {"open": "[", "close": "]"} + _desc_things = "indexes" _diff_array(v1, v2) - elif(typeof(v2) == TYPE_DICTIONARY): - _brackets = {'open':'{', 'close':'}'} - _desc_things = 'keys' + elif typeof(v2) == TYPE_DICTIONARY: + _brackets = {"open": "{", "close": "}"} + _desc_things = "keys" _diff_dictionary(v1, v2) else: _invalidate() - _utils.get_logger().error('Only Arrays and Dictionaries are supported.') + _utils.get_logger().error("Only Arrays and Dictionaries are supported.") else: _invalidate() - _utils.get_logger().error('Only Arrays and Dictionaries are supported.') + _utils.get_logger().error("Only Arrays and Dictionaries are supported.") func _diff_array(a1, a2): _total_count = max(a1.size(), a2.size()) for i in range(a1.size()): var result = null - if(i < a2.size()): - if(_diff_type == DEEP): + if i < a2.size(): + if _diff_type == DEEP: result = _compare.deep(a1[i], a2[i]) else: result = _compare.simple(a1[i], a2[i]) else: - result = _compare.simple(a1[i], _compare.MISSING, 'index') + result = _compare.simple(a1[i], _compare.MISSING, "index") - if(!result.are_equal): + if !result.are_equal: differences[i] = result - if(a1.size() < a2.size()): + if a1.size() < a2.size(): for i in range(a1.size(), a2.size()): - differences[i] = _compare.simple(_compare.MISSING, a2[i], 'index') + differences[i] = _compare.simple(_compare.MISSING, a2[i], "index") func _diff_dictionary(d1, d2): @@ -114,33 +130,33 @@ func _diff_dictionary(d1, d2): # Process all the keys in d1 _total_count += d1_keys.size() for key in d1_keys: - if(!d2.has(key)): - differences[key] = _compare.simple(d1[key], _compare.MISSING, 'key') + if !d2.has(key): + differences[key] = _compare.simple(d1[key], _compare.MISSING, "key") else: d2_keys.remove_at(d2_keys.find(key)) var result = null - if(_diff_type == DEEP): + if _diff_type == DEEP: result = _compare.deep(d1[key], d2[key]) else: result = _compare.simple(d1[key], d2[key]) - if(!result.are_equal): + if !result.are_equal: differences[key] = result # Process all the keys in d2 that didn't exist in d1 _total_count += d2_keys.size() for i in range(d2_keys.size()): - differences[d2_keys[i]] = _compare.simple(_compare.MISSING, d2[d2_keys[i]], 'key') + differences[d2_keys[i]] = _compare.simple(_compare.MISSING, d2[d2_keys[i]], "key") func summarize(): - var summary = '' + var summary = "" - if(are_equal): + if are_equal: summary = get_short_summary() else: - var formatter = load('res://addons/gut/diff_formatter.gd').new() + var formatter = load("res://addons/gut/diff_formatter.gd").new() formatter.set_max_to_display(max_differences) summary = formatter.make_it(self) diff --git a/addons/gut/double_tools.gd b/addons/gut/double_tools.gd index ab75cc7..7feb12c 100644 --- a/addons/gut/double_tools.gd +++ b/addons/gut/double_tools.gd @@ -1,5 +1,5 @@ -var thepath = '' -var subpath = '' +var thepath = "" +var subpath = "" var stubber = null var spy = null var gut = null @@ -7,37 +7,44 @@ var from_singleton = null var is_partial = null var double = null -const NO_DEFAULT_VALUE = '!__gut__no__default__value__!' +const NO_DEFAULT_VALUE = "!__gut__no__default__value__!" + + func from_id(inst_id): - if(inst_id == -1): + if inst_id == -1: return null else: return instance_from_id(inst_id) + func should_call_super(method_name, called_with): - if(stubber != null): + if stubber != null: return stubber.should_call_super(double, method_name, called_with) else: return false + func spy_on(method_name, called_with): - if(spy != null): + if spy != null: spy.add_call(double, method_name, called_with) + func get_stubbed_return(method_name, called_with): - if(stubber != null): + if stubber != null: return stubber.get_return(double, method_name, called_with) else: return null -func default_val(method_name, p_index, default_val=NO_DEFAULT_VALUE): - if(stubber != null): + +func default_val(method_name, p_index, default_val = NO_DEFAULT_VALUE): + if stubber != null: return stubber.get_default_value(double, method_name, p_index) else: return null -func _init(values=null): - if(values != null): + +func _init(values = null): + if values != null: double = values.double thepath = values.thepath subpath = values.subpath @@ -47,6 +54,5 @@ func _init(values=null): from_singleton = values.from_singleton is_partial = values.is_partial - if(gut != null): + if gut != null: gut.get_autofree().add_free(double) - diff --git a/addons/gut/doubler.gd b/addons/gut/doubler.gd index 50ecb68..e81591a 100644 --- a/addons/gut/doubler.gd +++ b/addons/gut/doubler.gd @@ -30,8 +30,6 @@ # ----------- # ############################################################################## - - # ------------------------------------------------------------------------------ # A stroke of genius if I do say so. This allows for doubling a scene without # having to write any files. By overloading the "instantiate" method we can @@ -39,15 +37,15 @@ # ------------------------------------------------------------------------------ class PackedSceneDouble: extends PackedScene - var _script = null + var _script = null var _scene = null func set_script_obj(obj): _script = obj - func instantiate(edit_state=0): + func instantiate(edit_state = 0): var inst = _scene.instantiate(edit_state) - if(_script != null): + if _script != null: inst.set_script(_script) return inst @@ -55,13 +53,13 @@ class PackedSceneDouble: _scene = load(path) - - # ------------------------------------------------------------------------------ # START Doubler # ------------------------------------------------------------------------------ -var _utils = load('res://addons/gut/utils.gd').get_instance() -var _base_script_text = _utils.get_file_as_text('res://addons/gut/double_templates/script_template.txt') +var _utils = load("res://addons/gut/utils.gd").get_instance() +var _base_script_text = _utils.get_file_as_text( + "res://addons/gut/double_templates/script_template.txt" +) var _script_collector = _utils.ScriptCollector.new() # used by tests for debugging purposes. var print_source = false @@ -71,62 +69,92 @@ var inner_class_registry = _utils.InnerClassRegistry.new() # Properties # ############### var _stubber = _utils.Stubber.new() + + func get_stubber(): return _stubber + + func set_stubber(stubber): _stubber = stubber + var _lgr = _utils.get_logger() + + func get_logger(): return _lgr + + func set_logger(logger): _lgr = logger _method_maker.set_logger(logger) + var _spy = null + + func get_spy(): return _spy + + func set_spy(spy): _spy = spy + var _gut = null + + func get_gut(): return _gut + + func set_gut(gut): _gut = gut + var _strategy = null + + func get_strategy(): return _strategy + + func set_strategy(strategy): _strategy = strategy var _method_maker = _utils.MethodMaker.new() + + func get_method_maker(): return _method_maker + var _ignored_methods = _utils.OneToMany.new() + + func get_ignored_methods(): return _ignored_methods + # ############### # Private # ############### -func _init(strategy=_utils.DOUBLE_STRATEGY.SCRIPT_ONLY): +func _init(strategy = _utils.DOUBLE_STRATEGY.SCRIPT_ONLY): set_logger(_utils.get_logger()) _strategy = strategy func _get_indented_line(indents, text): - var to_return = '' + var to_return = "" for _i in range(indents): to_return += "\t" return str(to_return, text, "\n") func _stub_to_call_super(parsed, method_name): - if(_utils.non_super_methods.has(method_name)): + if _utils.non_super_methods.has(method_name): return var params = _utils.StubParams.new(parsed.script_path, method_name, parsed.subpath) @@ -136,43 +164,41 @@ func _stub_to_call_super(parsed, method_name): func _get_base_script_text(parsed, override_path, partial): var path = parsed.script_path - if(override_path != null): + if override_path != null: path = override_path var stubber_id = -1 - if(_stubber != null): + if _stubber != null: stubber_id = _stubber.get_instance_id() var spy_id = -1 - if(_spy != null): + if _spy != null: spy_id = _spy.get_instance_id() var gut_id = -1 - if(_gut != null): + if _gut != null: gut_id = _gut.get_instance_id() - var extends_text = parsed.get_extends_text() + var extends_text = parsed.get_extends_text() var values = { # Top sections - "extends":extends_text, - "constants":'',#obj_info.get_constants_text(), - "properties":'',#obj_info.get_properties_text(), - + "extends": extends_text, + "constants": "", #obj_info.get_constants_text(), + "properties": "", #obj_info.get_properties_text(), # metadata values - "path":path, - "subpath":_utils.nvl(parsed.subpath, ''), - "stubber_id":stubber_id, - "spy_id":spy_id, - "gut_id":gut_id, - "singleton_name":'',#_utils.nvl(obj_info.get_singleton_name(), ''), - "is_partial":partial, + "path": path, + "subpath": _utils.nvl(parsed.subpath, ""), + "stubber_id": stubber_id, + "spy_id": spy_id, + "gut_id": gut_id, + "singleton_name": "", #_utils.nvl(obj_info.get_singleton_name(), ''), + "is_partial": partial, } return _base_script_text.format(values) - func _create_double(parsed, strategy, override_path, partial): var base_script = _get_base_script_text(parsed, override_path, partial) var super_name = "" @@ -183,21 +209,24 @@ func _create_double(parsed, strategy, override_path, partial): dbl_src += base_script for method in parsed.get_local_methods(): - if(!method.is_black_listed() && !_ignored_methods.has(parsed.resource, method.meta.name)): + if !method.is_black_listed() && !_ignored_methods.has(parsed.resource, method.meta.name): var mthd = parsed.get_local_method(method.meta.name) dbl_src += _get_func_text(method.meta, path, super_name) - if(strategy == _utils.DOUBLE_STRATEGY.INCLUDE_SUPER): + if strategy == _utils.DOUBLE_STRATEGY.INCLUDE_SUPER: for method in parsed.get_super_methods(): - if(!method.is_black_listed() && !_ignored_methods.has(parsed.resource, method.meta.name)): + if ( + !method.is_black_listed() + && !_ignored_methods.has(parsed.resource, method.meta.name) + ): _stub_to_call_super(parsed, method.meta.name) dbl_src += _get_func_text(method.meta, path, super_name) - if(print_source): + if print_source: print(_utils.add_line_numbers(dbl_src)) var DblClass = _utils.create_script_from_source(dbl_src) - if(_stubber != null): + if _stubber != null: _stub_method_default_values(DblClass, parsed, strategy) return DblClass @@ -205,19 +234,18 @@ func _create_double(parsed, strategy, override_path, partial): func _stub_method_default_values(which, parsed, strategy): for method in parsed.get_local_methods(): - if(!method.is_black_listed() && !_ignored_methods.has(parsed.resource, method.meta.name)): + if !method.is_black_listed() && !_ignored_methods.has(parsed.resource, method.meta.name): _stubber.stub_defaults_from_meta(parsed.script_path, method.meta) - func _double_scene_and_script(scene, strategy, partial): var to_return = PackedSceneDouble.new() to_return.load_scene(scene.get_path()) var script_obj = _utils.get_scene_script_object(scene) - if(script_obj != null): + if script_obj != null: var script_dbl = null - if(partial): + if partial: script_dbl = _partial_double(script_obj, strategy, scene.get_path()) else: script_dbl = _double(script_obj, strategy, scene.get_path()) @@ -227,18 +255,18 @@ func _double_scene_and_script(scene, strategy, partial): func _get_inst_id_ref_str(inst): - var ref_str = 'null' - if(inst): - ref_str = str('instance_from_id(', inst.get_instance_id(),')') + var ref_str = "null" + if inst: + ref_str = str("instance_from_id(", inst.get_instance_id(), ")") return ref_str -func _get_func_text(method_hash, path, super_=""): - var override_count = null; - if(_stubber != null): +func _get_func_text(method_hash, path, super_ = ""): + var override_count = null + if _stubber != null: override_count = _stubber.get_parameter_count(path, method_hash.name) - if(override_count != null): - print(method_hash.name, ' override: ', override_count) + if override_count != null: + print(method_hash.name, " override: ", override_count) var text = _method_maker.get_function_text(method_hash, path, override_count, super_) + "\n" @@ -248,11 +276,13 @@ func _get_func_text(method_hash, path, super_=""): func _parse_script(obj): var parsed = null - if(_utils.is_inner_class(obj)): - if(inner_class_registry.has(obj)): + if _utils.is_inner_class(obj): + if inner_class_registry.has(obj): parsed = _script_collector.parse(inner_class_registry.get_base_resource(obj), obj) else: - _lgr.error('Doubling Inner Classes requires you register them first. Call register_inner_classes passing the script that contains the inner class.') + _lgr.error( + "Doubling Inner Classes requires you register them first. Call register_inner_classes passing the script that contains the inner class." + ) else: parsed = _script_collector.parse(obj) @@ -260,15 +290,15 @@ func _parse_script(obj): # Override path is used with scenes. -func _double(obj, strategy, override_path=null): +func _double(obj, strategy, override_path = null): var parsed = _parse_script(obj) - if(parsed != null): + if parsed != null: return _create_double(parsed, strategy, override_path, false) -func _partial_double(obj, strategy, override_path=null): +func _partial_double(obj, strategy, override_path = null): var parsed = _parse_script(obj) - if(parsed != null): + if parsed != null: return _create_double(parsed, strategy, override_path, true) @@ -276,35 +306,39 @@ func _partial_double(obj, strategy, override_path=null): # Public # ------------------------- + # double a script/object -func double(obj, strategy=_strategy): +func double(obj, strategy = _strategy): return _double(obj, strategy) -func partial_double(obj, strategy=_strategy): + +func partial_double(obj, strategy = _strategy): return _partial_double(obj, strategy) # double a scene -func double_scene(scene, strategy=_strategy): +func double_scene(scene, strategy = _strategy): return _double_scene_and_script(scene, strategy, false) -func partial_double_scene(scene, strategy=_strategy): + +func partial_double_scene(scene, strategy = _strategy): return _double_scene_and_script(scene, strategy, true) func double_gdnative(which): return _double(which, _utils.DOUBLE_STRATEGY.INCLUDE_SUPER) + func partial_double_gdnative(which): return _partial_double(which, _utils.DOUBLE_STRATEGY.INCLUDE_SUPER) -func double_inner(parent, inner, strategy=_strategy): +func double_inner(parent, inner, strategy = _strategy): var parsed = _script_collector.parse(parent, inner) return _create_double(parsed, strategy, null, false) -func partial_double_inner(parent, inner, strategy=_strategy): +func partial_double_inner(parent, inner, strategy = _strategy): var parsed = _script_collector.parse(parent, inner) return _create_double(parsed, strategy, null, true) diff --git a/addons/gut/gui/BottomPanelShortcuts.gd b/addons/gut/gui/BottomPanelShortcuts.gd index 2e167c5..ebdd2a2 100644 --- a/addons/gut/gui/BottomPanelShortcuts.gd +++ b/addons/gut/gui/BottomPanelShortcuts.gd @@ -9,51 +9,59 @@ extends Window panel_button = $Layout/CPanelButton/ShortcutButton, } + func _ready(): for key in _ctrls: var sc_button = _ctrls[key] - sc_button.connect('start_edit', _on_edit_start.bind(sc_button)) - sc_button.connect('end_edit', _on_edit_end) - + sc_button.connect("start_edit", _on_edit_start.bind(sc_button)) + sc_button.connect("end_edit", _on_edit_end) # show dialog when running scene from editor. - if(get_parent() == get_tree().root): + if get_parent() == get_tree().root: popup_centered() + # ------------ # Events # ------------ func _on_Hide_pressed(): hide() + func _on_edit_start(which): for key in _ctrls: var sc_button = _ctrls[key] - if(sc_button != which): + if sc_button != which: sc_button.disable_set(true) sc_button.disable_clear(true) + func _on_edit_end(): for key in _ctrls: var sc_button = _ctrls[key] sc_button.disable_set(false) sc_button.disable_clear(false) + # ------------ # Public # ------------ func get_run_all(): return _ctrls.run_all.get_shortcut() + func get_run_current_script(): return _ctrls.run_current_script.get_shortcut() + func get_run_current_inner(): return _ctrls.run_current_inner.get_shortcut() + func get_run_current_test(): return _ctrls.run_current_test.get_shortcut() + func get_panel_button(): return _ctrls.panel_button.get_shortcut() @@ -61,11 +69,11 @@ func get_panel_button(): func save_shortcuts(path): var f = ConfigFile.new() - f.set_value('main', 'run_all', _ctrls.run_all.get_shortcut()) - f.set_value('main', 'run_current_script', _ctrls.run_current_script.get_shortcut()) - f.set_value('main', 'run_current_inner', _ctrls.run_current_inner.get_shortcut()) - f.set_value('main', 'run_current_test', _ctrls.run_current_test.get_shortcut()) - f.set_value('main', 'panel_button', _ctrls.panel_button.get_shortcut()) + f.set_value("main", "run_all", _ctrls.run_all.get_shortcut()) + f.set_value("main", "run_current_script", _ctrls.run_current_script.get_shortcut()) + f.set_value("main", "run_current_inner", _ctrls.run_current_inner.get_shortcut()) + f.set_value("main", "run_current_test", _ctrls.run_current_test.get_shortcut()) + f.set_value("main", "panel_button", _ctrls.panel_button.get_shortcut()) f.save(path) @@ -75,8 +83,8 @@ func load_shortcuts(path): var f = ConfigFile.new() f.load(path) - _ctrls.run_all.set_shortcut(f.get_value('main', 'run_all', emptyShortcut)) - _ctrls.run_current_script.set_shortcut(f.get_value('main', 'run_current_script', emptyShortcut)) - _ctrls.run_current_inner.set_shortcut(f.get_value('main', 'run_current_inner', emptyShortcut)) - _ctrls.run_current_test.set_shortcut(f.get_value('main', 'run_current_test', emptyShortcut)) - _ctrls.panel_button.set_shortcut(f.get_value('main', 'panel_button', emptyShortcut)) + _ctrls.run_all.set_shortcut(f.get_value("main", "run_all", emptyShortcut)) + _ctrls.run_current_script.set_shortcut(f.get_value("main", "run_current_script", emptyShortcut)) + _ctrls.run_current_inner.set_shortcut(f.get_value("main", "run_current_inner", emptyShortcut)) + _ctrls.run_current_test.set_shortcut(f.get_value("main", "run_current_test", emptyShortcut)) + _ctrls.panel_button.set_shortcut(f.get_value("main", "panel_button", emptyShortcut)) diff --git a/addons/gut/gui/GutBottomPanel.gd b/addons/gut/gui/GutBottomPanel.gd index 404320b..43fcf97 100644 --- a/addons/gut/gui/GutBottomPanel.gd +++ b/addons/gut/gui/GutBottomPanel.gd @@ -1,39 +1,37 @@ @tool extends Control -const RUNNER_JSON_PATH = 'res://.gut_editor_config.json' -const RESULT_FILE = 'user://.gut_editor.bbcode' -const RESULT_JSON = 'user://.gut_editor.json' -const SHORTCUTS_PATH = 'res://.gut_editor_shortcuts.cfg' +const RUNNER_JSON_PATH = "res://.gut_editor_config.json" +const RESULT_FILE = "user://.gut_editor.bbcode" +const RESULT_JSON = "user://.gut_editor.json" +const SHORTCUTS_PATH = "res://.gut_editor_shortcuts.cfg" -var TestScript = load('res://addons/gut/test.gd') -var GutConfigGui = load('res://addons/gut/gui/gut_config_gui.gd') -var ScriptTextEditors = load('res://addons/gut/gui/script_text_editor_controls.gd') +var TestScript = load("res://addons/gut/test.gd") +var GutConfigGui = load("res://addons/gut/gui/gut_config_gui.gd") +var ScriptTextEditors = load("res://addons/gut/gui/script_text_editor_controls.gd") -var _interface = null; -var _is_running = false; -var _gut_config = load('res://addons/gut/gut_config.gd').new() +var _interface = null +var _is_running = false +var _gut_config = load("res://addons/gut/gut_config.gd").new() var _gut_config_gui = null var _gut_plugin = null var _light_color = Color(0, 0, 0, .5) var _panel_button = null var _last_selected_path = null - @onready var _ctrls = { output = $layout/RSplit/CResults/TabBar/OutputText.get_rich_text_edit(), output_ctrl = $layout/RSplit/CResults/TabBar/OutputText, run_button = $layout/ControlBar/RunAll, shortcuts_button = $layout/ControlBar/Shortcuts, - settings_button = $layout/ControlBar/Settings, run_results_button = $layout/ControlBar/RunResultsBtn, output_button = $layout/ControlBar/OutputBtn, - settings = $layout/RSplit/sc/Settings, shortcut_dialog = $BottomPanelShortcuts, light = $layout/RSplit/CResults/ControlBar/Light3D, - results = { + results = + { bar = $layout/RSplit/CResults/ControlBar, passing = $layout/RSplit/CResults/ControlBar/Passing/value, failing = $layout/RSplit/CResults/ControlBar/Failing/value, @@ -52,27 +50,37 @@ func _init(): func _ready(): - _ctrls.results.bar.connect('draw', _on_results_bar_draw.bind(_ctrls.results.bar)) + _ctrls.results.bar.connect("draw", _on_results_bar_draw.bind(_ctrls.results.bar)) hide_settings(!_ctrls.settings_button.button_pressed) _gut_config_gui = GutConfigGui.new(_ctrls.settings) _gut_config_gui.set_options(_gut_config.options) _apply_options_to_controls() - _ctrls.shortcuts_button.icon = get_theme_icon('Shortcut', 'EditorIcons') - _ctrls.settings_button.icon = get_theme_icon('Tools', 'EditorIcons') - _ctrls.run_results_button.icon = get_theme_icon('AnimationTrackGroup', 'EditorIcons') # Tree - _ctrls.output_button.icon = get_theme_icon('Font', 'EditorIcons') + _ctrls.shortcuts_button.icon = get_theme_icon("Shortcut", "EditorIcons") + _ctrls.settings_button.icon = get_theme_icon("Tools", "EditorIcons") + _ctrls.run_results_button.icon = get_theme_icon("AnimationTrackGroup", "EditorIcons") # Tree + _ctrls.output_button.icon = get_theme_icon("Font", "EditorIcons") _ctrls.run_results.set_output_control(_ctrls.output_ctrl) - _ctrls.run_results.set_font( - _gut_config.options.panel_options.font_name, - _gut_config.options.panel_options.font_size) + ( + _ctrls + . run_results + . set_font( + _gut_config.options.panel_options.font_name, _gut_config.options.panel_options.font_size + ) + ) - var check_import = load('res://addons/gut/images/red.png') - if(check_import == null): - _ctrls.run_results.add_centered_text("GUT got some new images that are not imported yet. Please restart Godot.") - print('GUT got some new images that are not imported yet. Please restart Godot.') + var check_import = load("res://addons/gut/images/red.png") + if check_import == null: + ( + _ctrls + . run_results + . add_centered_text( + "GUT got some new images that are not imported yet. Please restart Godot." + ) + ) + print("GUT got some new images that are not imported yet. Please restart Godot.") else: _ctrls.run_results.add_centered_text("Let's run some tests!") @@ -86,24 +94,30 @@ func _apply_options_to_controls(): _ctrls.output_ctrl.set_all_fonts(_gut_config.options.panel_options.font_name) _ctrls.output_ctrl.set_font_size(_gut_config.options.panel_options.font_size) - _ctrls.run_results.set_font( - _gut_config.options.panel_options.font_name, - _gut_config.options.panel_options.font_size) + ( + _ctrls + . run_results + . set_font( + _gut_config.options.panel_options.font_name, _gut_config.options.panel_options.font_size + ) + ) _ctrls.run_results.set_show_orphans(!_gut_config.options.hide_orphans) func _process(delta): - if(_is_running): - if(!_interface.is_playing_scene()): + if _is_running: + if !_interface.is_playing_scene(): _is_running = false _ctrls.output_ctrl.add_text("\ndone") load_result_output() _gut_plugin.make_bottom_panel_item_visible(self) + # --------------- # Private # --------------- + func load_shortcuts(): _ctrls.shortcut_dialog.load_shortcuts(SHORTCUTS_PATH) _apply_shortcuts() @@ -111,7 +125,7 @@ func load_shortcuts(): func _is_test_script(script): var from = script.get_base_script() - while(from and from.resource_path != 'res://addons/gut/test.gd'): + while from and from.resource_path != "res://addons/gut/test.gd": from = from.get_base_script() return from != null @@ -121,7 +135,7 @@ func _show_errors(errs): _ctrls.output_ctrl.clear() var text = "Cannot run tests, you have a configuration error:\n" for e in errs: - text += str('* ', e, "\n") + text += str("* ", e, "\n") text += "Check your settings ----->" _ctrls.output_ctrl.add_text(text) hide_output_text(false) @@ -136,39 +150,40 @@ func _save_config(): _gut_config.options.panel_options.use_colors = _ctrls.output_ctrl.get_use_colors() var w_result = _gut_config.write_options(RUNNER_JSON_PATH) - if(w_result != OK): - push_error(str('Could not write options to ', RUNNER_JSON_PATH, ': ', w_result)) - return; + if w_result != OK: + push_error(str("Could not write options to ", RUNNER_JSON_PATH, ": ", w_result)) + return func _run_tests(): var issues = _gut_config_gui.get_config_issues() - if(issues.size() > 0): + if issues.size() > 0: _show_errors(issues) return - write_file(RESULT_FILE, 'Run in progress') + write_file(RESULT_FILE, "Run in progress") _save_config() _apply_options_to_controls() _ctrls.output_ctrl.clear() _ctrls.run_results.clear() - _ctrls.run_results.add_centered_text('Running...') + _ctrls.run_results.add_centered_text("Running...") - _interface.play_custom_scene('res://addons/gut/gui/GutRunner.tscn') + _interface.play_custom_scene("res://addons/gut/gui/GutRunner.tscn") _is_running = true - _ctrls.output_ctrl.add_text('Running...') + _ctrls.output_ctrl.add_text("Running...") func _apply_shortcuts(): _ctrls.run_button.shortcut = _ctrls.shortcut_dialog.get_run_all() - _ctrls.run_at_cursor.get_script_button().shortcut = \ - _ctrls.shortcut_dialog.get_run_current_script() - _ctrls.run_at_cursor.get_inner_button().shortcut = \ - _ctrls.shortcut_dialog.get_run_current_inner() - _ctrls.run_at_cursor.get_test_button().shortcut = \ - _ctrls.shortcut_dialog.get_run_current_test() + _ctrls.run_at_cursor.get_script_button().shortcut = ( + _ctrls . shortcut_dialog . get_run_current_script() + ) + _ctrls.run_at_cursor.get_inner_button().shortcut = ( + _ctrls . shortcut_dialog . get_run_current_inner() + ) + _ctrls.run_at_cursor.get_test_button().shortcut = _ctrls.shortcut_dialog.get_run_current_test() _panel_button.shortcut = _ctrls.shortcut_dialog.get_panel_button() @@ -194,7 +209,7 @@ func _on_Light_draw(): func _on_editor_script_changed(script): - if(script): + if script: set_current_script(script) @@ -205,10 +220,12 @@ func _on_RunAll_pressed(): func _on_Shortcuts_pressed(): _ctrls.shortcut_dialog.popup_centered() + func _on_bottom_panel_shortcuts_visibility_changed(): _apply_shortcuts() _ctrls.shortcut_dialog.save_shortcuts(SHORTCUTS_PATH) + func _on_RunAtCursor_run_tests(what): _gut_config.options.selected = what.script _gut_config.options.inner_class = what.inner_class @@ -228,7 +245,7 @@ func _on_OutputBtn_pressed(): func _on_RunResultsBtn_pressed(): - hide_result_tree(! _ctrls.run_results_button.button_pressed) + hide_result_tree(!_ctrls.run_results_button.button_pressed) _save_config() @@ -237,6 +254,7 @@ func _on_RunResultsBtn_pressed(): func _on_UseColors_pressed(): pass + # --------------- # Public # --------------- @@ -251,7 +269,7 @@ func hide_settings(should): # collapse only collapses the first control, so we move # settings around to be the collapsed one - if(should): + if should: s_scroll.get_parent().move_child(s_scroll, 0) else: s_scroll.get_parent().move_child(s_scroll, 1) @@ -270,13 +288,13 @@ func load_result_output(): var summary = get_file_as_text(RESULT_JSON) var test_json_conv = JSON.new() - if (test_json_conv.parse(summary) != OK): + if test_json_conv.parse(summary) != OK: return var results = test_json_conv.get_data() _ctrls.run_results.load_json_results(results) - var summary_json = results['test_scripts']['props'] + var summary_json = results["test_scripts"]["props"] _ctrls.results.passing.text = str(summary_json.passing) _ctrls.results.passing.get_parent().visible = true @@ -284,22 +302,24 @@ func load_result_output(): _ctrls.results.failing.get_parent().visible = true _ctrls.results.pending.text = str(summary_json.pending) - _ctrls.results.pending.get_parent().visible = _ctrls.results.pending.text != '0' + _ctrls.results.pending.get_parent().visible = _ctrls.results.pending.text != "0" _ctrls.results.errors.text = str(summary_json.errors) - _ctrls.results.errors.get_parent().visible = _ctrls.results.errors.text != '0' + _ctrls.results.errors.get_parent().visible = _ctrls.results.errors.text != "0" _ctrls.results.warnings.text = str(summary_json.warnings) - _ctrls.results.warnings.get_parent().visible = _ctrls.results.warnings.text != '0' + _ctrls.results.warnings.get_parent().visible = _ctrls.results.warnings.text != "0" _ctrls.results.orphans.text = str(summary_json.orphans) - _ctrls.results.orphans.get_parent().visible = _ctrls.results.orphans.text != '0' and !_gut_config.options.hide_orphans + _ctrls.results.orphans.get_parent().visible = ( + _ctrls.results.orphans.text != "0" and !_gut_config.options.hide_orphans + ) - if(summary_json.tests == 0): + if summary_json.tests == 0: _light_color = Color(1, 0, 0, .75) - elif(summary_json.failures != 0): + elif summary_json.failures != 0: _light_color = Color(1, 0, 0, .75) - elif(summary_json.pending != 0): + elif summary_json.pending != 0: _light_color = Color(1, 1, 0, .75) else: _light_color = Color(0, 1, 0, .75) @@ -308,8 +328,8 @@ func load_result_output(): func set_current_script(script): - if(script): - if(_is_test_script(script)): + if script: + if _is_test_script(script): var file = script.resource_path.get_file() _last_selected_path = script.resource_path.get_file() _ctrls.run_at_cursor.activate_for_script(script.resource_path) @@ -317,7 +337,11 @@ func set_current_script(script): func set_interface(value): _interface = value - _interface.get_script_editor().connect("editor_script_changed",Callable(self,'_on_editor_script_changed')) + ( + _interface + . get_script_editor() + . connect("editor_script_changed", Callable(self, "_on_editor_script_changed")) + ) var ste = ScriptTextEditors.new(_interface.get_script_editor()) _ctrls.run_results.set_interface(_interface) @@ -333,14 +357,15 @@ func set_plugin(value): func set_panel_button(value): _panel_button = value + # ------------------------------------------------------------------------------ # Write a file. # ------------------------------------------------------------------------------ func write_file(path, content): var f = FileAccess.open(path, FileAccess.WRITE) - if(f != null): + if f != null: f.store_string(content) - f = null; + f = null return FileAccess.get_open_error() @@ -349,9 +374,9 @@ func write_file(path, content): # Returns the text of a file or an empty string if the file could not be opened. # ------------------------------------------------------------------------------ func get_file_as_text(path): - var to_return = '' + var to_return = "" var f = FileAccess.open(path, FileAccess.READ) - if(f != null): + if f != null: to_return = f.get_as_text() f = null return to_return @@ -361,7 +386,7 @@ func get_file_as_text(path): # return if_null if value is null otherwise return value # ------------------------------------------------------------------------------ func nvl(value, if_null): - if(value == null): + if value == null: return if_null else: return value diff --git a/addons/gut/gui/GutRunner.gd b/addons/gut/gui/GutRunner.gd index 7a3e63e..db0042b 100644 --- a/addons/gut/gui/GutRunner.gd +++ b/addons/gut/gui/GutRunner.gd @@ -1,15 +1,15 @@ extends Node2D -var Gut = load('res://addons/gut/gut.gd') -var ResultExporter = load('res://addons/gut/result_exporter.gd') -var GutConfig = load('res://addons/gut/gut_config.gd') +var Gut = load("res://addons/gut/gut.gd") +var ResultExporter = load("res://addons/gut/result_exporter.gd") +var GutConfig = load("res://addons/gut/gut_config.gd") -const RUNNER_JSON_PATH = 'res://.gut_editor_config.json' -const RESULT_FILE = 'user://.gut_editor.bbcode' -const RESULT_JSON = 'user://.gut_editor.json' +const RUNNER_JSON_PATH = "res://.gut_editor_config.json" +const RESULT_FILE = "user://.gut_editor.bbcode" +const RESULT_JSON = "user://.gut_editor.json" var _gut_config = null -var _gut = null; +var _gut = null var _wrote_results = false # Flag for when this is being used at the command line. Otherwise it is # assumed this is being used by the panel and being launched with @@ -21,55 +21,63 @@ var _cmdln_mode = false var auto_run_tests = true + func _ready(): - if(_gut_config == null): + if _gut_config == null: _gut_config = GutConfig.new() _gut_config.load_panel_options(RUNNER_JSON_PATH) # The command line will call run_tests on its own. When used from the panel # we have to kick off the tests ourselves b/c there's no way I know of to # interact with the scene that was run via play_custom_scene. - if(!_cmdln_mode and auto_run_tests): - call_deferred('run_tests') + if !_cmdln_mode and auto_run_tests: + call_deferred("run_tests") -func run_tests(show_gui=true): - - if(_gut == null): +func run_tests(show_gui = true): + if _gut == null: get_gut() _setup_gui(show_gui) _gut.add_children_to = self - if(_gut_config.options.gut_on_top): + if _gut_config.options.gut_on_top: _gut_layer.add_child(_gut) else: add_child(_gut) - if(!_cmdln_mode): - _gut.end_run.connect(_on_tests_finished.bind(_gut_config.options.should_exit, _gut_config.options.should_exit_on_success)) + if !_cmdln_mode: + ( + _gut + . end_run + . connect( + _on_tests_finished.bind( + _gut_config.options.should_exit, _gut_config.options.should_exit_on_success + ) + ) + ) _gut_config.config_gut(_gut) - var run_rest_of_scripts = _gut_config.options.unit_test_name == '' + var run_rest_of_scripts = _gut_config.options.unit_test_name == "" _gut.test_scripts(run_rest_of_scripts) func _setup_gui(show_gui): - if(show_gui): + if show_gui: _gui.gut = _gut - var printer = _gut.logger.get_printer('gui') + var printer = _gut.logger.get_printer("gui") printer.set_textbox(_gui.get_textbox()) else: - _gut.logger.disable_printer('gui', true) + _gut.logger.disable_printer("gui", true) _gui.visible = false var opts = _gut_config.options _gui.set_font_size(opts.font_size) _gui.set_font(opts.font_name) - if(opts.font_color != null and opts.font_color.is_valid_html_color()): + if opts.font_color != null and opts.font_color.is_valid_html_color(): _gui.set_default_font_color(Color(opts.font_color)) - if(opts.background_color != null and opts.background_color.is_valid_html_color()): + if opts.background_color != null and opts.background_color.is_valid_html_color(): _gui.set_background_color(Color(opts.background_color)) #_tester.set_modulate(Color(1.0, 1.0, 1.0, min(1.0, float(opts.opacity) / 100))) @@ -79,16 +87,15 @@ func _setup_gui(show_gui): # _tester.get_gui().compact_mode(true) - func _write_results(): - var content = _gui.get_textbox().text #_gut.logger.get_gui_bbcode() + var content = _gui.get_textbox().text #_gut.logger.get_gui_bbcode() var f = FileAccess.open(RESULT_FILE, FileAccess.WRITE) - if(f != null): + if f != null: f.store_string(content) f.close() else: - push_error('Could not save bbcode, result = ', FileAccess.get_open_error()) + push_error("Could not save bbcode, result = ", FileAccess.get_open_error()) var exporter = ResultExporter.new() var f_result = exporter.write_json_file(_gut, RESULT_JSON) @@ -96,21 +103,21 @@ func _write_results(): func _exit_tree(): - if(!_wrote_results and !_cmdln_mode): + if !_wrote_results and !_cmdln_mode: _write_results() func _on_tests_finished(should_exit, should_exit_on_success): _write_results() - if(should_exit): + if should_exit: get_tree().quit() - elif(should_exit_on_success and _gut.get_fail_count() == 0): + elif should_exit_on_success and _gut.get_fail_count() == 0: get_tree().quit() func get_gut(): - if(_gut == null): + if _gut == null: _gut = Gut.new() return _gut diff --git a/addons/gut/gui/OutputText.gd b/addons/gut/gui/OutputText.gd index 39729ae..46ade42 100644 --- a/addons/gut/gui/OutputText.gd +++ b/addons/gut/gui/OutputText.gd @@ -1,32 +1,37 @@ extends VBoxContainer @tool + class SearchResults: var L = 0 var C = 0 var positions = [] var te = null - var _last_term = '' + var _last_term = "" - func _search_te(text, start_position, flags=0): + func _search_te(text, start_position, flags = 0): var start_pos = start_position - if(start_pos[L] < 0 or start_pos[L] > te.get_line_count()): + if start_pos[L] < 0 or start_pos[L] > te.get_line_count(): start_pos[L] = 0 - if(start_pos[C] < 0): + if start_pos[C] < 0: start_pos[L] = 0 var result = te.search(text, flags, start_pos[L], start_pos[C]) - if(result.size() == 2 and result[L] == start_position[L] and - result[C] == start_position[C] and text == _last_term): - if(flags == TextEdit.SEARCH_BACKWARDS): + if ( + result.size() == 2 + and result[L] == start_position[L] + and result[C] == start_position[C] + and text == _last_term + ): + if flags == TextEdit.SEARCH_BACKWARDS: result[C] -= 1 else: result[C] += 1 result = _search_te(text, result, flags) L = result.y C = result.x - elif(result.size() == 2): + elif result.size() == 2: te.scroll_vertical = result[L] te.select(result[L], result[C], result[L], result[C] + text.length()) te.set_caret_column(result[C]) @@ -67,12 +72,13 @@ class SearchResults: var last_pos = [0, 0] positions.clear() - while(found): + while found: c_pos = te.search(text, 0, c_pos[L], c_pos[C]) - if(c_pos.size() > 0 and - (c_pos[L] > last_pos[L] or - (c_pos[L] == last_pos[L] and c_pos[C] > last_pos[C]))): + if ( + c_pos.size() > 0 + and (c_pos[L] > last_pos[L] or (c_pos[L] == last_pos[L] and c_pos[C] > last_pos[C])) + ): positions.append([c_pos[L], c_pos[C]]) c_pos[C] += 1 last_pos = c_pos @@ -80,42 +86,41 @@ class SearchResults: found = false - @onready var _ctrls = { output = $Output, - copy_button = $Toolbar/CopyButton, use_colors = $Toolbar/UseColors, clear_button = $Toolbar/ClearButton, word_wrap = $Toolbar/WordWrap, show_search = $Toolbar/ShowSearch, - - search_bar = { + search_bar = + { bar = $Search, search_term = $Search/SearchTerm, } } var _sr = SearchResults.new() + func _test_running_setup(): - _ctrls.use_colors.text = 'use colors' - _ctrls.show_search.text = 'search' - _ctrls.word_wrap.text = 'ww' + _ctrls.use_colors.text = "use colors" + _ctrls.show_search.text = "search" + _ctrls.word_wrap.text = "ww" set_all_fonts("CourierPrime") set_font_size(20) - load_file('user://.gut_editor.bbcode') + load_file("user://.gut_editor.bbcode") func _ready(): _sr.te = _ctrls.output - _ctrls.use_colors.icon = get_theme_icon('RichTextEffect', 'EditorIcons') - _ctrls.show_search.icon = get_theme_icon('Search', 'EditorIcons') - _ctrls.word_wrap.icon = get_theme_icon('Loop', 'EditorIcons') + _ctrls.use_colors.icon = get_theme_icon("RichTextEffect", "EditorIcons") + _ctrls.show_search.icon = get_theme_icon("Search", "EditorIcons") + _ctrls.word_wrap.icon = get_theme_icon("Loop", "EditorIcons") _setup_colors() - if(get_parent() == get_tree().root): + if get_parent() == get_tree().root: _test_running_setup() @@ -125,23 +130,23 @@ func _ready(): func _setup_colors(): _ctrls.output.clear() var keywords = [ - ['Failed', Color.RED], - ['Passed', Color.GREEN], - ['Pending', Color.YELLOW], - ['Orphans', Color.YELLOW], - ['WARNING', Color.YELLOW], - ['ERROR', Color.RED] + ["Failed", Color.RED], + ["Passed", Color.GREEN], + ["Pending", Color.YELLOW], + ["Orphans", Color.YELLOW], + ["WARNING", Color.YELLOW], + ["ERROR", Color.RED] ] for keyword in keywords: - if (_ctrls.output.syntax_highlighter == null) : + if _ctrls.output.syntax_highlighter == null: _ctrls.output.syntax_highlighter = CodeHighlighter.new() _ctrls.output.syntax_highlighter.add_keyword_color(keyword[0], keyword[1]) var f_color = null - if (_ctrls.output.theme == null) : + if _ctrls.output.theme == null: f_color = get_theme_color("font_color") - else : + else: f_color = _ctrls.output.theme.font_color _ctrls.output.add_theme_color_override("font_color_readonly", f_color) _ctrls.output.add_theme_color_override("function_color", f_color) @@ -151,8 +156,8 @@ func _setup_colors(): func _set_font(font_name, custom_name): var rtl = _ctrls.output - if(font_name == null): - rtl.set('custom_fonts/' + custom_name, null) + if font_name == null: + rtl.set("custom_fonts/" + custom_name, null) else: pass # cuasing issues in 4.0 @@ -184,7 +189,8 @@ func _on_ShowSearch_pressed(): func _on_SearchTerm_focus_entered(): - _ctrls.search_bar.search_term.call_deferred('select_all') + _ctrls.search_bar.search_term.call_deferred("select_all") + func _on_SearchNext_pressed(): _sr.find_next(_ctrls.search_bar.search_term.text) @@ -195,63 +201,67 @@ func _on_SearchPrev_pressed(): func _on_SearchTerm_text_changed(new_text): - if(new_text == ''): + if new_text == "": _ctrls.output.deselect() else: _sr.find_next(new_text) func _on_SearchTerm_text_entered(new_text): - if(Input.is_physical_key_pressed(KEY_SHIFT)): + if Input.is_physical_key_pressed(KEY_SHIFT): _sr.find_prev(new_text) else: _sr.find_next(new_text) func _on_SearchTerm_gui_input(event): - if(event is InputEventKey and !event.pressed and event.scancode == KEY_ESCAPE): + if event is InputEventKey and !event.pressed and event.scancode == KEY_ESCAPE: show_search(false) + func _on_WordWrap_pressed(): _ctrls.output.wrap_enabled = _ctrls.word_wrap.pressed _ctrls.output.queue_redraw() + # ------------------ # Public # ------------------ func show_search(should): _ctrls.search_bar.bar.visible = should - if(should): + if should: _ctrls.search_bar.search_term.grab_focus() _ctrls.search_bar.search_term.select_all() _ctrls.show_search.button_pressed = should -func search(text, start_pos, highlight=true): +func search(text, start_pos, highlight = true): return _sr.find_next(text) func copy_to_clipboard(): var selected = _ctrls.output.get_selection_text() - if(selected != ''): + if selected != "": OS.clipboard = selected else: OS.clipboard = _ctrls.output.text func clear(): - _ctrls.output.text = '' + _ctrls.output.text = "" func set_all_fonts(base_name): - if(base_name == 'Default'): - _set_font(null, 'font') + if base_name == "Default": + _set_font(null, "font") # _set_font(null, 'normal_font') # _set_font(null, 'bold_font') # _set_font(null, 'italics_font') # _set_font(null, 'bold_italics_font') else: - _set_font(base_name + '-Regular', 'font') + _set_font(base_name + "-Regular", "font") + + # _set_font(base_name + '-Regular', 'normal_font') # _set_font(base_name + '-Bold', 'bold_font') # _set_font(base_name + '-Italic', 'italics_font') @@ -260,8 +270,10 @@ func set_all_fonts(base_name): func set_font_size(new_size): var rtl = _ctrls.output - if(rtl.get('custom_fonts/font') != null): - rtl.get('custom_fonts/font').size = new_size + if rtl.get("custom_fonts/font") != null: + rtl.get("custom_fonts/font").size = new_size + + # rtl.get('custom_fonts/bold_italics_font').size = new_size # rtl.get('custom_fonts/bold_font').size = new_size # rtl.get('custom_fonts/italics_font').size = new_size @@ -273,7 +285,7 @@ func set_use_colors(value): func get_use_colors(): - return false; + return false func get_rich_text_edit(): @@ -281,20 +293,19 @@ func get_rich_text_edit(): func load_file(path): - var f = FileAccess.open(path, FileAccess.READ) - if(f == null): + if f == null: return var t = f.get_as_text() f.close() _ctrls.output.text = t _ctrls.output.scroll_vertical = _ctrls.output.get_line_count() - _ctrls.output.set_deferred('scroll_vertical', _ctrls.output.get_line_count()) + _ctrls.output.set_deferred("scroll_vertical", _ctrls.output.get_line_count()) func add_text(text): - if(is_inside_tree()): + if is_inside_tree(): _ctrls.output.text += text diff --git a/addons/gut/gui/RunAtCursor.gd b/addons/gut/gui/RunAtCursor.gd index 93c261b..9219ff9 100644 --- a/addons/gut/gui/RunAtCursor.gd +++ b/addons/gut/gui/RunAtCursor.gd @@ -1,8 +1,7 @@ @tool extends Control - -var ScriptTextEditors = load('res://addons/gut/gui/script_text_editor_controls.gd') +var ScriptTextEditors = load("res://addons/gut/gui/script_text_editor_controls.gd") @onready var _ctrls = { btn_script = $HBox/BtnRunScript, @@ -28,17 +27,18 @@ func _ready(): _ctrls.btn_inner.visible = false _ctrls.btn_method.visible = false + # ---------------- # Private # ---------------- func _set_editor(which): _last_line = -1 - if(_cur_editor != null and _cur_editor.get_ref()): - _cur_editor.get_ref().disconnect('cursor_changed',Callable(self,'_on_cursor_changed')) + if _cur_editor != null and _cur_editor.get_ref(): + _cur_editor.get_ref().disconnect("cursor_changed", Callable(self, "_on_cursor_changed")) - if(which != null): + if which != null: _cur_editor = weakref(which) - which.connect('cursor_changed',Callable(self,'_on_cursor_changed'),[which]) + which.connect("cursor_changed", Callable(self, "_on_cursor_changed"), [which]) _last_line = which.get_caret_line() _last_info = _editors.get_line_info() @@ -58,20 +58,22 @@ func _update_buttons(info): _ctrls.arrow_2.visible = info.test_method != null _ctrls.btn_method.text = str(info.test_method) _ctrls.btn_method.hint_tooltip = str("Run test ", info.test_method) - + # The button's new size won't take effect until the next frame. # This appears to be what was causing the button to not be clickable the # first time. call_deferred("_update_size") + func _update_size(): custom_minimum_size.x = _ctrls.btn_method.size.x + _ctrls.btn_method.rect_position.x + # ---------------- # Events # ---------------- func _on_cursor_changed(which): - if(which.get_caret_line() != _last_line): + if which.get_caret_line() != _last_line: _last_line = which.get_caret_line() _last_info = _editors.get_line_info() _update_buttons(_last_info) @@ -147,6 +149,3 @@ func search_current_editor_for_text(txt): to_return = result[TextEdit.SEARCH_RESULT_LINE] return to_return - - - diff --git a/addons/gut/gui/RunResults.gd b/addons/gut/gui/RunResults.gd index be40c5f..6c0d6a4 100644 --- a/addons/gut/gui/RunResults.gd +++ b/addons/gut/gui/RunResults.gd @@ -2,22 +2,22 @@ extends Control @tool var _interface = null -var _utils = load('res://addons/gut/utils.gd').new() +var _utils = load("res://addons/gut/utils.gd").new() var _hide_passing = true var _font = null var _font_size = null var _root = null var _max_icon_width = 10 -var _editors = null # script_text_editor_controls.gd +var _editors = null # script_text_editor_controls.gd var _show_orphans = true var _output_control = null const _col_1_bg_color = Color(0, 0, 0, .1) -var _icons = { - red = load('res://addons/gut/images/red.png'), - green = load('res://addons/gut/images/green.png'), - yellow = load('res://addons/gut/images/yellow.png'), +var _icons = { + red = load("res://addons/gut/images/red.png"), + green = load("res://addons/gut/images/green.png"), + yellow = load("res://addons/gut/images/yellow.png"), } signal search_for_text(text) @@ -26,7 +26,8 @@ signal search_for_text(text) tree = $VBox/Output/Scroll/Tree, lbl_overlay = $VBox/Output/OverlayMessage, chk_hide_passing = $VBox/Toolbar/HidePassing, - toolbar = { + toolbar = + { toolbar = $VBox/Toolbar, collapse = $VBox/Toolbar/Collapse, collapse_all = $VBox/Toolbar/CollapseAll, @@ -38,31 +39,32 @@ signal search_for_text(text) } } + func _test_running_setup(): _hide_passing = true _show_orphans = true - var _gut_config = load('res://addons/gut/gut_config.gd').new() - _gut_config.load_panel_options('res://.gut_editor_config.json') + var _gut_config = load("res://addons/gut/gut_config.gd").new() + _gut_config.load_panel_options("res://.gut_editor_config.json") set_font( - _gut_config.options.panel_options.font_name, - _gut_config.options.panel_options.font_size) + _gut_config.options.panel_options.font_name, _gut_config.options.panel_options.font_size + ) - _ctrls.toolbar.hide_passing.text = '[hp]' - load_json_file('user://.gut_editor.json') + _ctrls.toolbar.hide_passing.text = "[hp]" + load_json_file("user://.gut_editor.json") func _set_toolbutton_icon(btn, icon_name, text): - if(Engine.is_editor_hint()): - btn.icon = get_theme_icon(icon_name, 'EditorIcons') + if Engine.is_editor_hint(): + btn.icon = get_theme_icon(icon_name, "EditorIcons") else: - btn.text = str('[', text, ']') + btn.text = str("[", text, "]") func _ready(): var f = null - if ($FontSampler.get_label_settings() == null) : + if $FontSampler.get_label_settings() == null: f = get_theme_default_font() - else : + else: f = $FontSampler.get_label_settings().font var s_size = f.get_string_size("000 of 000 passed") _root = _ctrls.tree.create_item() @@ -72,37 +74,49 @@ func _ready(): _ctrls.tree.set_column_expand(1, false) _ctrls.tree.set_column_custom_minimum_width(1, s_size.x) - _set_toolbutton_icon(_ctrls.toolbar.collapse, 'CollapseTree', 'c') - _set_toolbutton_icon(_ctrls.toolbar.collapse_all, 'CollapseTree', 'c') - _set_toolbutton_icon(_ctrls.toolbar.expand, 'ExpandTree', 'e') - _set_toolbutton_icon(_ctrls.toolbar.expand_all, 'ExpandTree', 'e') - _set_toolbutton_icon(_ctrls.toolbar.show_script, 'Script', 'ss') - _set_toolbutton_icon(_ctrls.toolbar.scroll_output, 'Font', 'so') + _set_toolbutton_icon(_ctrls.toolbar.collapse, "CollapseTree", "c") + _set_toolbutton_icon(_ctrls.toolbar.collapse_all, "CollapseTree", "c") + _set_toolbutton_icon(_ctrls.toolbar.expand, "ExpandTree", "e") + _set_toolbutton_icon(_ctrls.toolbar.expand_all, "ExpandTree", "e") + _set_toolbutton_icon(_ctrls.toolbar.show_script, "Script", "ss") + _set_toolbutton_icon(_ctrls.toolbar.scroll_output, "Font", "so") - _ctrls.toolbar.hide_passing.set('custom_icons/checked', get_theme_icon('GuiVisibilityHidden', 'EditorIcons')) - _ctrls.toolbar.hide_passing.set('custom_icons/unchecked', get_theme_icon('GuiVisibilityVisible', 'EditorIcons')) + ( + _ctrls + . toolbar + . hide_passing + . set("custom_icons/checked", get_theme_icon("GuiVisibilityHidden", "EditorIcons")) + ) + ( + _ctrls + . toolbar + . hide_passing + . set("custom_icons/unchecked", get_theme_icon("GuiVisibilityVisible", "EditorIcons")) + ) - if(get_parent() == get_tree().root): + if get_parent() == get_tree().root: _test_running_setup() - call_deferred('_update_min_width') + call_deferred("_update_min_width") + func _update_min_width(): custom_minimum_size.x = _ctrls.toolbar.toolbar.size.x + func _open_file(path, line_number): - if(_interface == null): - print('Too soon, wait a bit and try again.') + if _interface == null: + print("Too soon, wait a bit and try again.") return var r = load(path) - if(line_number != -1): + if line_number != -1: _interface.edit_script(r, line_number) else: _interface.edit_script(r) - if(_ctrls.toolbar.show_script.pressed): - _interface.set_main_screen_editor('Script') + if _ctrls.toolbar.show_script.pressed: + _interface.set_main_screen_editor("Script") func _add_script_tree_item(script_path, script_json): @@ -111,19 +125,20 @@ func _add_script_tree_item(script_path, script_json): var item_text = script_path var parent = _root - if(path_info.inner_class != ''): + if path_info.inner_class != "": parent = _find_script_item_with_path(path_info.path) item_text = path_info.inner_class - if(parent == null): + if parent == null: parent = _add_script_tree_item(path_info.path, {}) var item = _ctrls.tree.create_item(parent) item.set_text(0, item_text) var meta = { - "type":"script", - "path":path_info.path, - "inner_class":path_info.inner_class, - "json":script_json} + "type": "script", + "path": path_info.path, + "inner_class": path_info.inner_class, + "json": script_json + } item.set_metadata(0, meta) item.set_custom_bg_color(1, _col_1_bg_color) @@ -135,7 +150,7 @@ func _add_assert_item(text, icon, parent_item): var assert_item = _ctrls.tree.create_item(parent_item) assert_item.set_icon_max_width(0, _max_icon_width) assert_item.set_text(0, text) - assert_item.set_metadata(0, {"type":"assert"}) + assert_item.set_metadata(0, {"type": "assert"}) assert_item.set_icon(0, icon) assert_item.set_custom_bg_color(1, _col_1_bg_color) @@ -145,12 +160,12 @@ func _add_assert_item(text, icon, parent_item): func _add_test_tree_item(test_name, test_json, script_item): # print(' * adding test ', test_name) var no_orphans_to_show = !_show_orphans or (_show_orphans and test_json.orphans == 0) - if(_hide_passing and test_json['status'] == 'pass' and no_orphans_to_show): + if _hide_passing and test_json["status"] == "pass" and no_orphans_to_show: return var item = _ctrls.tree.create_item(script_item) - var status = test_json['status'] - var meta = {"type":"test", "json":test_json} + var status = test_json["status"] + var meta = {"type": "test", "json": test_json} item.set_text(0, test_name) item.set_text(1, status) @@ -160,40 +175,39 @@ func _add_test_tree_item(test_name, test_json, script_item): item.set_metadata(0, meta) item.set_icon_max_width(0, _max_icon_width) - var orphan_text = 'orphans' - if(test_json.orphans == 1): - orphan_text = 'orphan' - orphan_text = str(test_json.orphans, ' ', orphan_text) + var orphan_text = "orphans" + if test_json.orphans == 1: + orphan_text = "orphan" + orphan_text = str(test_json.orphans, " ", orphan_text) - - if(status == 'pass' and no_orphans_to_show): + if status == "pass" and no_orphans_to_show: item.set_icon(0, _icons.green) - elif(status == 'pass' and !no_orphans_to_show): + elif status == "pass" and !no_orphans_to_show: item.set_icon(0, _icons.yellow) item.set_text(1, orphan_text) - elif(status == 'fail'): + elif status == "fail": item.set_icon(0, _icons.red) else: item.set_icon(0, _icons.yellow) - if(!_hide_passing): + if !_hide_passing: for passing in test_json.passing: - _add_assert_item('pass: ' + passing, _icons.green, item) + _add_assert_item("pass: " + passing, _icons.green, item) for failure in test_json.failing: - _add_assert_item("fail: " + failure.replace("\n", ''), _icons.red, item) + _add_assert_item("fail: " + failure.replace("\n", ""), _icons.red, item) for pending in test_json.pending: - _add_assert_item("pending: " + pending.replace("\n", ''), _icons.yellow, item) + _add_assert_item("pending: " + pending.replace("\n", ""), _icons.yellow, item) - if(status != 'pass' and !no_orphans_to_show): + if status != "pass" and !no_orphans_to_show: _add_assert_item(orphan_text, _icons.yellow, item) return item func _load_result_tree(j): - var scripts = j['test_scripts']['scripts'] + var scripts = j["test_scripts"]["scripts"] var script_keys = scripts.keys() # if we made it here, the json is valid and we did something, otherwise the # 'nothing to see here' should be visible. @@ -201,30 +215,30 @@ func _load_result_tree(j): var _last_script_item = null for key in script_keys: - var tests = scripts[key]['tests'] + var tests = scripts[key]["tests"] var test_keys = tests.keys() var s_item = _add_script_tree_item(key, scripts[key]) var bad_count = 0 for test_key in test_keys: var t_item = _add_test_tree_item(test_key, tests[test_key], s_item) - if(tests[test_key].status != 'pass'): + if tests[test_key].status != "pass": bad_count += 1 - elif(t_item != null): + elif t_item != null: t_item.collapsed = true # get_children returns the first child or null. its a dumb name. - if(s_item.get_children() == null): + if s_item.get_children() == null: # var m = s_item.get_metadata(0) # print('!! Deleting ', m.path, ' ', m.inner_class) s_item.free() else: - var total_text = str(test_keys.size(), ' passed') + var total_text = str(test_keys.size(), " passed") # s_item.set_text_alignment(1, s_item.ALIGN_LEFT) - if(bad_count == 0): + if bad_count == 0: s_item.collapsed = true else: - total_text = str(test_keys.size() - bad_count, ' of ', test_keys.size(), ' passed') + total_text = str(test_keys.size() - bad_count, " of ", test_keys.size(), " passed") s_item.set_text(1, total_text) _free_childless_scripts() @@ -235,7 +249,7 @@ func _free_childless_scripts(): var items = _root.get_children() for item in items: var next_item = item.get_next() - if(item.get_children() == null): + if item.get_children() == null: item.free() item = next_item @@ -245,9 +259,9 @@ func _find_script_item_with_path(path): var to_return = null var idx = 0 - while(idx < items.size() and to_return == null): + while idx < items.size() and to_return == null: var item = items[idx] - if(item.get_metadata(0).path == path): + if item.get_metadata(0).path == path: to_return = item else: idx += 1 @@ -257,21 +271,18 @@ func _find_script_item_with_path(path): func _get_line_number_from_assert_msg(msg): var line = -1 - if(msg.find('at line') > 0): + if msg.find("at line") > 0: line = msg.split("at line")[-1].split(" ")[-1].to_int() return line func _get_path_and_inner_class_name_from_test_path(path): - var to_return = { - path = '', - inner_class = '' - } + var to_return = {path = "", inner_class = ""} to_return.path = path - if !path.ends_with('.gd'): - var loc = path.find('.gd') - to_return.inner_class = path.split('.')[-1] + if !path.ends_with(".gd"): + var loc = path.find(".gd") + to_return.inner_class = path.split(".")[-1] to_return.path = path.substr(0, loc + 3) return to_return @@ -279,37 +290,37 @@ func _get_path_and_inner_class_name_from_test_path(path): func _handle_tree_item_select(item, force_scroll): var item_type = item.get_metadata(0).type - var path = ''; - var line = -1; - var method_name = '' - var inner_class = '' + var path = "" + var line = -1 + var method_name = "" + var inner_class = "" - if(item_type == 'test'): + if item_type == "test": var s_item = item.get_parent() - path = s_item.get_metadata(0)['path'] - inner_class = s_item.get_metadata(0)['inner_class'] + path = s_item.get_metadata(0)["path"] + inner_class = s_item.get_metadata(0)["inner_class"] line = -1 method_name = item.get_text(0) - elif(item_type == 'assert'): + elif item_type == "assert": var s_item = item.get_parent().get_parent() - path = s_item.get_metadata(0)['path'] - inner_class = s_item.get_metadata(0)['inner_class'] + path = s_item.get_metadata(0)["path"] + inner_class = s_item.get_metadata(0)["inner_class"] line = _get_line_number_from_assert_msg(item.get_text(0)) method_name = item.get_parent().get_text(0) - elif(item_type == 'script'): - path = item.get_metadata(0)['path'] - if(item.get_parent() != _root): + elif item_type == "script": + path = item.get_metadata(0)["path"] + if item.get_parent() != _root: inner_class = item.get_text(0) line = -1 - method_name = '' + method_name = "" else: return var path_info = _get_path_and_inner_class_name_from_test_path(path) - if(force_scroll or _ctrls.toolbar.show_script.pressed): + if force_scroll or _ctrls.toolbar.show_script.pressed: _goto_code(path, line, method_name, inner_class) - if(force_scroll or _ctrls.toolbar.scroll_output.pressed): + if force_scroll or _ctrls.toolbar.scroll_output.pressed: _goto_output(path, method_name, inner_class) @@ -327,9 +338,9 @@ func _get_line_number_for_seq_search(search_strings, te): var i = 0 var string_found = true - while(i < search_strings.size() and string_found): + while i < search_strings.size() and string_found: result = te.search(search_strings[i], s_flags, line.y, line.x) - if(result.x != -1): + if result.x != -1: line = result else: string_found = false @@ -338,55 +349,56 @@ func _get_line_number_for_seq_search(search_strings, te): return line.y -func _goto_code(path, line, method_name='', inner_class =''): - if(_interface == null): - print('going to ', [path, line, method_name, inner_class]) +func _goto_code(path, line, method_name = "", inner_class = ""): + if _interface == null: + print("going to ", [path, line, method_name, inner_class]) return _open_file(path, line) - if(line == -1): + if line == -1: var search_strings = [] - if(inner_class != ''): + if inner_class != "": search_strings.append(inner_class) - if(method_name != ''): + if method_name != "": search_strings.append(method_name) line = _get_line_number_for_seq_search(search_strings, _editors.get_current_text_edit()) - if(line != -1): + if line != -1: _interface.get_script_editor().goto_line(line) func _goto_output(path, method_name, inner_class): - if(_output_control == null): + if _output_control == null: return var search_strings = [path] - if(inner_class != ''): + if inner_class != "": search_strings.append(inner_class) - if(method_name != ''): + if method_name != "": search_strings.append(method_name) var line = _get_line_number_for_seq_search(search_strings, _output_control.get_rich_text_edit()) - if(line != -1): + if line != -1: _output_control.scroll_to_line(line) func _show_all_passed(): - if(_root.get_children() == null): - add_centered_text('Everything passed!') + if _root.get_children() == null: + add_centered_text("Everything passed!") func _set_collapsed_on_all(item, value): - if(item == _root): + if item == _root: var node = _root.get_children() - while(node != null): - node.call_recursive('set_collapsed', value) + while node != null: + node.call_recursive("set_collapsed", value) node = node.get_next() else: - item.call_recursive('set_collapsed', value) + item.call_recursive("set_collapsed", value) + # -------------- # Events @@ -396,16 +408,17 @@ func _on_Tree_item_selected(): var item = _ctrls.tree.get_selected() _handle_tree_item_select(item, false) # it just looks better if the left is always selected. - if(item.is_selected(1)): + if item.is_selected(1): item.deselect(1) item.select(0) func _on_Tree_item_activated(): # force scroll - print('double clicked') + print("double clicked") _handle_tree_item_select(_ctrls.tree.get_selected(), true) + func _on_Collapse_pressed(): collapse_selected() @@ -425,29 +438,39 @@ func _on_ExpandAll_pressed(): func _on_Hide_Passing_pressed(): _hide_passing = _ctrls.toolbar.hide_passing.button_pressed + # -------------- # Public # -------------- func load_json_file(path): var text = _utils.get_file_as_text(path) - if(text != ''): + if text != "": var test_json_conv = JSON.new() test_json_conv.parse(text) var result = test_json_conv.get_data() - if(result.error != OK): - add_centered_text(str(path, " has invalid json in it \n", - 'Error ', result.error, "@", result.error_line, "\n", - result.error_string)) + if result.error != OK: + add_centered_text( + str( + path, + " has invalid json in it \n", + "Error ", + result.error, + "@", + result.error_line, + "\n", + result.error_string + ) + ) return load_json_results(result.result) else: - add_centered_text(str(path, ' was empty or does not exist.')) + add_centered_text(str(path, " was empty or does not exist.")) func load_json_results(j): clear() - add_centered_text('Nothing Here') + add_centered_text("Nothing Here") _load_result_tree(j) @@ -456,7 +479,7 @@ func add_centered_text(t): func clear_centered_text(): - _ctrls.lbl_overlay.text = '' + _ctrls.lbl_overlay.text = "" func clear(): @@ -483,12 +506,13 @@ func expand_all(): func collapse_selected(): var item = _ctrls.tree.get_selected() - if(item != null): + if item != null: _set_collapsed_on_all(item, true) + func expand_selected(): var item = _ctrls.tree.get_selected() - if(item != null): + if item != null: _set_collapsed_on_all(item, false) @@ -498,6 +522,8 @@ func set_show_orphans(should): func set_font(font_name, size): pass + + # var dyn_font = FontFile.new() # var font_data = FontFile.new() # font_data.font_path = 'res://addons/gut/fonts/' + font_name + '-Regular.ttf' diff --git a/addons/gut/gui/ShortcutButton.gd b/addons/gut/gui/ShortcutButton.gd index 94fe720..73e08d0 100644 --- a/addons/gut/gui/ShortcutButton.gd +++ b/addons/gut/gui/ShortcutButton.gd @@ -1,7 +1,6 @@ @tool extends Control - @onready var _ctrls = { shortcut_label = $Layout/lblShortcut, set_button = $Layout/SetButton, @@ -14,7 +13,7 @@ signal changed signal start_edit signal end_edit -const NO_SHORTCUT = '' +const NO_SHORTCUT = "" var _source_event = InputEventKey.new() var _pre_edit_event = null @@ -22,28 +21,39 @@ var _key_disp = NO_SHORTCUT var _modifier_keys = [KEY_ALT, KEY_CTRL, KEY_META, KEY_SHIFT] + # Called when the node enters the scene tree for the first time. func _ready(): set_process_unhandled_key_input(false) func _display_shortcut(): - if(_key_disp == ''): + if _key_disp == "": _key_disp = NO_SHORTCUT _ctrls.shortcut_label.text = _key_disp func _is_shift_only_modifier(): - return _source_event.shift_pressed and \ - !(_source_event.alt_pressed or _source_event.command_pressed or \ - _source_event.ctrl_pressed or _source_event.meta_pressed) and \ - !_is_modifier(_source_event.keycode) + return ( + _source_event.shift_pressed + and !( + _source_event.alt_pressed + or _source_event.command_pressed + or _source_event.ctrl_pressed + or _source_event.meta_pressed + ) + and !_is_modifier(_source_event.keycode) + ) func _has_modifier(event): - return event.alt_pressed or event.command_pressed or \ - event.ctrl_pressed or event.meta_pressed or \ - event.shift_pressed + return ( + event.alt_pressed + or event.command_pressed + or event.ctrl_pressed + or event.meta_pressed + or event.shift_pressed + ) func _is_modifier(keycode): @@ -58,23 +68,24 @@ func _edit_mode(should): _ctrls.cancel_button.visible = should _ctrls.clear_button.visible = !should - if(should and to_s() == ''): - _ctrls.shortcut_label.text = 'press buttons' + if should and to_s() == "": + _ctrls.shortcut_label.text = "press buttons" else: _ctrls.shortcut_label.text = to_s() - if(should): + if should: emit_signal("start_edit") else: emit_signal("end_edit") + # --------------- # Events # --------------- func _unhandled_key_input(event): - if(event is InputEventKey): - if(event.pressed): - if(_has_modifier(event) and !_is_modifier(event.get_keycode_with_modifiers())): + if event is InputEventKey: + if event.pressed: + if _has_modifier(event) and !_is_modifier(event.get_keycode_with_modifiers()): _source_event = event _key_disp = OS.get_keycode_string(event.get_keycode_with_modifiers()) else: @@ -92,7 +103,7 @@ func _on_SetButton_pressed(): func _on_SaveButton_pressed(): _edit_mode(false) _pre_edit_event = null - emit_signal('changed') + emit_signal("changed") func _on_CancelButton_pressed(): @@ -105,6 +116,7 @@ func _on_CancelButton_pressed(): func _on_ClearButton_pressed(): clear_shortcut() + # --------------- # Public # --------------- @@ -123,7 +135,7 @@ func get_shortcut(): func set_shortcut(sc): - if(sc == null or sc.events == null || sc.events.size() <= 0): + if sc == null or sc.events == null || sc.events.size() <= 0: clear_shortcut() else: _source_event = sc.events[0] @@ -140,5 +152,6 @@ func clear_shortcut(): func disable_set(should): _ctrls.set_button.disabled = should + func disable_clear(should): _ctrls.clear_button.disabled = should diff --git a/addons/gut/gui/gut_config_gui.gd b/addons/gut/gui/gut_config_gui.gd index a0df83c..b280e0f 100644 --- a/addons/gut/gui/gut_config_gui.gd +++ b/addons/gut/gui/gut_config_gui.gd @@ -3,7 +3,7 @@ class DirectoryCtrl: extends HBoxContainer - var text = '': + var text = "": get: return _txt_path.text set(val): @@ -14,35 +14,33 @@ class DirectoryCtrl: var _dialog = FileDialog.new() func _init(): - _btn_dir.text = '...' - _btn_dir.connect('pressed',Callable(self,'_on_dir_button_pressed')) + _btn_dir.text = "..." + _btn_dir.connect("pressed", Callable(self, "_on_dir_button_pressed")) _txt_path.size_flags_horizontal = _txt_path.SIZE_EXPAND_FILL _dialog.mode = _dialog.FILE_MODE_OPEN_DIR _dialog.unresizable = false - _dialog.connect("dir_selected",Callable(self,'_on_selected')) - _dialog.connect("file_selected",Callable(self,'_on_selected')) + _dialog.connect("dir_selected", Callable(self, "_on_selected")) + _dialog.connect("file_selected", Callable(self, "_on_selected")) _dialog.size = Vector2(1000, 700) func _on_selected(path): text = path - func _on_dir_button_pressed(): _dialog.current_dir = _txt_path.text _dialog.popup_centered() - func _ready(): add_child(_txt_path) add_child(_btn_dir) add_child(_dialog) - func get_line_edit(): return _txt_path + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ class FileCtrl: @@ -51,17 +49,18 @@ class FileCtrl: func _init(): _dialog.mode = _dialog.FILE_MODE_OPEN_FILE + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ class Vector2Ctrl: extends VBoxContainer - var value = Vector2(-1, -1) : + var value = Vector2(-1, -1): get: return get_value() set(val): set_value(val) - var disabled = false : + var disabled = false: get: return get_disabled() set(val): @@ -70,8 +69,8 @@ class Vector2Ctrl: var y_spin = SpinBox.new() func _init(): - add_child(_make_one('x: ', x_spin)) - add_child(_make_one('y: ', y_spin)) + add_child(_make_one("x: ", x_spin)) + add_child(_make_one("y: ", y_spin)) func _make_one(txt, spinner): var hbox = HBoxContainer.new() @@ -85,7 +84,7 @@ class Vector2Ctrl: return hbox func set_value(v): - if(v != null): + if v != null: x_spin.value = v[0] y_spin.value = v[1] @@ -103,14 +102,13 @@ class Vector2Ctrl: pass - # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ var _base_container = null var _base_control = null const DIRS_TO_LIST = 6 var _cfg_ctrls = {} -var _avail_fonts = ['AnonymousPro', 'CourierPrime', 'LobsterTwo', 'Default'] +var _avail_fonts = ["AnonymousPro", "CourierPrime", "LobsterTwo", "Default"] func _init(cont): @@ -158,10 +156,10 @@ func _add_title(text): # lbl.align = Label.ALIGNMENT_CENTER _base_container.add_child(row) - row.connect('draw', _on_title_cell_draw.bind(row)) + row.connect("draw", _on_title_cell_draw.bind(row)) -func _add_number(key, value, disp_text, v_min, v_max, hint=''): +func _add_number(key, value, disp_text, v_min, v_max, hint = ""): var value_ctrl = SpinBox.new() value_ctrl.value = value value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL @@ -172,12 +170,12 @@ func _add_number(key, value, disp_text, v_min, v_max, hint=''): _new_row(key, disp_text, value_ctrl, hint) -func _add_select(key, value, values, disp_text, hint=''): +func _add_select(key, value, values, disp_text, hint = ""): var value_ctrl = OptionButton.new() var select_idx = 0 for i in range(values.size()): value_ctrl.add_item(values[i]) - if(value == values[i]): + if value == values[i]: select_idx = i value_ctrl.selected = select_idx value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL @@ -185,7 +183,7 @@ func _add_select(key, value, values, disp_text, hint=''): _new_row(key, disp_text, value_ctrl, hint) -func _add_value(key, value, disp_text, hint=''): +func _add_value(key, value, disp_text, hint = ""): var value_ctrl = LineEdit.new() value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL value_ctrl.text = value @@ -194,14 +192,14 @@ func _add_value(key, value, disp_text, hint=''): _new_row(key, disp_text, value_ctrl, hint) -func _add_boolean(key, value, disp_text, hint=''): +func _add_boolean(key, value, disp_text, hint = ""): var value_ctrl = CheckBox.new() value_ctrl.button_pressed = value _new_row(key, disp_text, value_ctrl, hint) -func _add_directory(key, value, disp_text, hint=''): +func _add_directory(key, value, disp_text, hint = ""): var value_ctrl = DirectoryCtrl.new() value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL value_ctrl.text = value @@ -210,7 +208,7 @@ func _add_directory(key, value, disp_text, hint=''): _new_row(key, disp_text, value_ctrl, hint) -func _add_file(key, value, disp_text, hint=''): +func _add_file(key, value, disp_text, hint = ""): var value_ctrl = FileCtrl.new() value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL value_ctrl.text = value @@ -219,7 +217,7 @@ func _add_file(key, value, disp_text, hint=''): _new_row(key, disp_text, value_ctrl, hint) -func _add_color(key, value, disp_text, hint=''): +func _add_color(key, value, disp_text, hint = ""): var value_ctrl = ColorPickerButton.new() value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL value_ctrl.color = value @@ -227,7 +225,7 @@ func _add_color(key, value, disp_text, hint=''): _new_row(key, disp_text, value_ctrl, hint) -func _add_vector2(key, value, disp_text, hint=''): +func _add_vector2(key, value, disp_text, hint = ""): var value_ctrl = Vector2Ctrl.new() value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL value_ctrl.value = value @@ -235,6 +233,8 @@ func _add_vector2(key, value, disp_text, hint=''): _wire_select_on_focus(value_ctrl.y_spin.get_line_edit()) _new_row(key, disp_text, value_ctrl, hint) + + # ----------------------------- @@ -243,17 +243,17 @@ func _add_vector2(key, value, disp_text, hint=''): # ------------------ func _wire_select_on_focus(which): pass - which.connect('focus_entered', _on_ctrl_focus_highlight.bind(which)) - which.connect('focus_exited', _on_ctrl_focus_unhighlight.bind(which)) + which.connect("focus_entered", _on_ctrl_focus_highlight.bind(which)) + which.connect("focus_exited", _on_ctrl_focus_unhighlight.bind(which)) func _on_ctrl_focus_highlight(which): - if(which.has_method('select_all')): - which.call_deferred('select_all') + if which.has_method("select_all"): + which.call_deferred("select_all") func _on_ctrl_focus_unhighlight(which): - if(which.has_method('select')): + if which.has_method("select"): which.select(0, 0) @@ -269,17 +269,17 @@ func get_config_issues(): var has_directory = false for i in range(DIRS_TO_LIST): - var key = str('directory_', i) + var key = str("directory_", i) var path = _cfg_ctrls[key].text - if(path != null and path != ''): + if path != null and path != "": has_directory = true - if(!DirAccess.dir_exists(path)): - to_return.append(str('Test directory ', path, ' does not exist.')) + if !DirAccess.dir_exists(path): + to_return.append(str("Test directory ", path, " does not exist.")) - if(!has_directory): - to_return.append('You do not have any directories set.') + if !has_directory: + to_return.append("You do not have any directories set.") - if(!_cfg_ctrls['suffix'].text.ends_with('.gd')): + if !_cfg_ctrls["suffix"].text.ends_with(".gd"): to_return.append("Script suffix must end in '.gd'") return to_return @@ -287,90 +287,186 @@ func get_config_issues(): func set_options(options): _add_title("Settings") - _add_number("log_level", options.log_level, "Log Level", 0, 3, - "Detail level for log messages.\n" + \ - "\t0: Errors and failures only.\n" + \ - "\t1: Adds all test names + warnings + info\n" + \ - "\t2: Shows all asserts\n" + \ - "\t3: Adds more stuff probably, maybe not.") - _add_boolean('ignore_pause', options.ignore_pause, 'Ignore Pause', - "Ignore calls to pause_before_teardown") - _add_boolean('hide_orphans', options.hide_orphans, 'Hide Orphans', - 'Do not display orphan counts in output.') - _add_boolean('should_exit', options.should_exit, 'Exit on Finish', - "Exit when tests finished.") - _add_boolean('should_exit_on_success', options.should_exit_on_success, 'Exit on Success', - "Exit if there are no failures. Does nothing if 'Exit on Finish' is enabled.") - + _add_number( + "log_level", + options.log_level, + "Log Level", + 0, + 3, + ( + "Detail level for log messages.\n" + + "\t0: Errors and failures only.\n" + + "\t1: Adds all test names + warnings + info\n" + + "\t2: Shows all asserts\n" + + "\t3: Adds more stuff probably, maybe not." + ) + ) + _add_boolean( + "ignore_pause", + options.ignore_pause, + "Ignore Pause", + "Ignore calls to pause_before_teardown" + ) + _add_boolean( + "hide_orphans", + options.hide_orphans, + "Hide Orphans", + "Do not display orphan counts in output." + ) + _add_boolean("should_exit", options.should_exit, "Exit on Finish", "Exit when tests finished.") + _add_boolean( + "should_exit_on_success", + options.should_exit_on_success, + "Exit on Success", + "Exit if there are no failures. Does nothing if 'Exit on Finish' is enabled." + ) _add_title("Panel Output") - _add_select('output_font_name', options.panel_options.font_name, _avail_fonts, 'Font', - "The name of the font to use when running tests and in the output panel to the left.") - _add_number('output_font_size', options.panel_options.font_size, 'Font Size', 5, 100, - "The font size to use when running tests and in the output panel to the left.") + _add_select( + "output_font_name", + options.panel_options.font_name, + _avail_fonts, + "Font", + "The name of the font to use when running tests and in the output panel to the left." + ) + _add_number( + "output_font_size", + options.panel_options.font_size, + "Font Size", + 5, + 100, + "The font size to use when running tests and in the output panel to the left." + ) + _add_title("Runner Window") + _add_boolean( + "gut_on_top", + options.gut_on_top, + "On Top", + "The GUT Runner appears above children added during tests." + ) + _add_number( + "opacity", options.opacity, "Opacity", 0, 100, "The opacity of GUT when tests are running." + ) + _add_boolean( + "should_maximize", + options.should_maximize, + "Maximize", + "Maximize GUT when tests are being run." + ) + _add_boolean( + "compact_mode", + options.compact_mode, + "Compact Mode", + "The runner will be in compact mode. This overrides Maximize." + ) - _add_title('Runner Window') - _add_boolean("gut_on_top", options.gut_on_top, "On Top", - "The GUT Runner appears above children added during tests.") - _add_number('opacity', options.opacity, 'Opacity', 0, 100, - "The opacity of GUT when tests are running.") - _add_boolean('should_maximize', options.should_maximize, 'Maximize', - "Maximize GUT when tests are being run.") - _add_boolean('compact_mode', options.compact_mode, 'Compact Mode', - 'The runner will be in compact mode. This overrides Maximize.') + _add_title("Runner Appearance") + _add_select( + "font_name", + options.font_name, + _avail_fonts, + "Font", + "The font to use for text output in the Gut Runner." + ) + _add_number( + "font_size", + options.font_size, + "Font Size", + 5, + 100, + "The font size for text output in the Gut Runner." + ) + _add_color( + "font_color", + options.font_color, + "Font Color", + "The font color for text output in the Gut Runner." + ) + _add_color( + "background_color", + options.background_color, + "Background Color", + "The background color for text output in the Gut Runner." + ) + _add_boolean( + "disable_colors", + options.disable_colors, + "Disable Formatting", + "Disable formatting and colors used in the Runner. Does not affect panel output." + ) - _add_title('Runner Appearance') - _add_select('font_name', options.font_name, _avail_fonts, 'Font', - "The font to use for text output in the Gut Runner.") - _add_number('font_size', options.font_size, 'Font Size', 5, 100, - "The font size for text output in the Gut Runner.") - _add_color('font_color', options.font_color, 'Font Color', - "The font color for text output in the Gut Runner.") - _add_color('background_color', options.background_color, 'Background Color', - "The background color for text output in the Gut Runner.") - _add_boolean('disable_colors', options.disable_colors, 'Disable Formatting', - 'Disable formatting and colors used in the Runner. Does not affect panel output.') - - _add_title('Test Directories') - _add_boolean('include_subdirs', options.include_subdirs, 'Include Subdirs', - "Include subdirectories of the directories configured below.") + _add_title("Test Directories") + _add_boolean( + "include_subdirs", + options.include_subdirs, + "Include Subdirs", + "Include subdirectories of the directories configured below." + ) for i in range(DIRS_TO_LIST): - var value = '' - if(options.dirs.size() > i): + var value = "" + if options.dirs.size() > i: value = options.dirs[i] - _add_directory(str('directory_', i), value, str('Directory ', i)) + _add_directory(str("directory_", i), value, str("Directory ", i)) _add_title("XML Output") - _add_value("junit_xml_file", options.junit_xml_file, "Output Path3D", - "Path3D and filename where GUT should create a JUnit compliant XML file. " + - "This file will contain the results of the last test run. To avoid " + - "overriding the file use Include Timestamp.") - _add_boolean("junit_xml_timestamp", options.junit_xml_timestamp, "Include Timestamp", - "Include a timestamp in the filename so that each run gets its own xml file.") + _add_value( + "junit_xml_file", + options.junit_xml_file, + "Output Path3D", + ( + "Path3D and filename where GUT should create a JUnit compliant XML file. " + + "This file will contain the results of the last test run. To avoid " + + "overriding the file use Include Timestamp." + ) + ) + _add_boolean( + "junit_xml_timestamp", + options.junit_xml_timestamp, + "Include Timestamp", + "Include a timestamp in the filename so that each run gets its own xml file." + ) + _add_title("Hooks") + _add_file( + "pre_run_script", + options.pre_run_script, + "Pre-Run Hook", + "This script will be run by GUT before any tests are run." + ) + _add_file( + "post_run_script", + options.post_run_script, + "Post-Run Hook", + "This script will be run by GUT after all tests are run." + ) - _add_title('Hooks') - _add_file('pre_run_script', options.pre_run_script, 'Pre-Run Hook', - 'This script will be run by GUT before any tests are run.') - _add_file('post_run_script', options.post_run_script, 'Post-Run Hook', - 'This script will be run by GUT after all tests are run.') - - - _add_title('Misc') - _add_value('prefix', options.prefix, 'Script Prefix', - "The filename prefix for all test scripts.") - _add_value('suffix', options.suffix, 'Script Suffix', - "Script suffix, including .gd extension. For example '_foo.gd'.") - _add_number('paint_after', options.paint_after, 'Paint After', 0.0, 1.0, - "How long GUT will wait before pausing for 1 frame to paint the screen. 0 is never.") + _add_title("Misc") + _add_value( + "prefix", options.prefix, "Script Prefix", "The filename prefix for all test scripts." + ) + _add_value( + "suffix", + options.suffix, + "Script Suffix", + "Script suffix, including .gd extension. For example '_foo.gd'." + ) + _add_number( + "paint_after", + options.paint_after, + "Paint After", + 0.0, + 1.0, + "How long GUT will wait before pausing for 1 frame to paint the screen. 0 is never." + ) # since _add_number doesn't set step property, it will default to a step of # 1 and cast values to int. Give it a .5 step and re-set the value. _cfg_ctrls.paint_after.step = .05 _cfg_ctrls.paint_after.value = options.paint_after - print('paint after = ', options.paint_after) + print("paint after = ", options.paint_after) + func get_options(base_opts): var to_return = base_opts.duplicate() @@ -383,13 +479,13 @@ func get_options(base_opts): to_return.should_exit_on_success = _cfg_ctrls.should_exit_on_success.button_pressed #Output - to_return.panel_options.font_name = _cfg_ctrls.output_font_name.get_item_text( - _cfg_ctrls.output_font_name.selected) + to_return.panel_options.font_name = ( + _cfg_ctrls . output_font_name . get_item_text(_cfg_ctrls.output_font_name.selected) + ) to_return.panel_options.font_size = _cfg_ctrls.output_font_size.value # Runner Appearance - to_return.font_name = _cfg_ctrls.font_name.get_item_text( - _cfg_ctrls.font_name.selected) + to_return.font_name = _cfg_ctrls.font_name.get_item_text(_cfg_ctrls.font_name.selected) to_return.font_size = _cfg_ctrls.font_size.value to_return.should_maximize = _cfg_ctrls.should_maximize.button_pressed to_return.compact_mode = _cfg_ctrls.compact_mode.button_pressed @@ -400,14 +496,13 @@ func get_options(base_opts): to_return.gut_on_top = _cfg_ctrls.gut_on_top.button_pressed to_return.paint_after = _cfg_ctrls.paint_after.value - # Directories to_return.include_subdirs = _cfg_ctrls.include_subdirs.button_pressed var dirs = [] for i in range(DIRS_TO_LIST): - var key = str('directory_', i) + var key = str("directory_", i) var val = _cfg_ctrls[key].text - if(val != '' and val != null): + if val != "" and val != null: dirs.append(val) to_return.dirs = dirs diff --git a/addons/gut/gui/script_text_editor_controls.gd b/addons/gut/gui/script_text_editor_controls.gd index 88eb8e2..34cffcc 100644 --- a/addons/gut/gui/script_text_editor_controls.gd +++ b/addons/gut/gui/script_text_editor_controls.gd @@ -11,57 +11,52 @@ class ScriptEditorControlRef: _script_editor = weakref(script_edit) _populate_controls() - func _populate_controls(): # who knows if the tree will change so get the first instance of each # type of control we care about. Chances are there won't be more than # one of these in the future, but their position in the tree may change. - _code_editor = weakref(_get_first_child_named('CodeTextEditor', _script_editor.get_ref())) + _code_editor = weakref(_get_first_child_named("CodeTextEditor", _script_editor.get_ref())) _text_edit = weakref(_get_first_child_named("CodeEdit", _code_editor.get_ref())) - func _get_first_child_named(obj_name, parent_obj): - if(parent_obj == null): + if parent_obj == null: return null var kids = parent_obj.get_children() var index = 0 var to_return = null - while(index < kids.size() and to_return == null): - if(str(kids[index]).find(str("[", obj_name)) != -1): + while index < kids.size() and to_return == null: + if str(kids[index]).find(str("[", obj_name)) != -1: to_return = kids[index] else: to_return = _get_first_child_named(obj_name, kids[index]) - if(to_return == null): + if to_return == null: index += 1 return to_return - func get_script_text_edit(): return _script_editor.get_ref() - func get_text_edit(): # ScriptTextEditors that are loaded when the project is opened # do not have their children populated yet. So if we may have to # _populate_controls again if we don't have one. - if(_text_edit == null): + if _text_edit == null: _populate_controls() return _text_edit.get_ref() - func get_script_editor(): return _script_editor - func is_visible(): var to_return = false - if(_script_editor.get_ref()): + if _script_editor.get_ref(): to_return = _script_editor.get_ref().visible return to_return + # ############################################################################## # # ############################################################################## @@ -74,8 +69,9 @@ var _script_editor = null # and related controls at the time of the last refresh. var _script_editor_controls = [] -var _method_prefix = 'test_' -var _inner_class_prefix = 'Test' +var _method_prefix = "test_" +var _inner_class_prefix = "Test" + func _init(script_edit): _script_editor = script_edit @@ -83,7 +79,7 @@ func _init(script_edit): func _is_script_editor(obj): - return str(obj).find('[ScriptTextEditor') != -1 + return str(obj).find("[ScriptTextEditor") != -1 # Find the first ScriptTextEditor and then get its parent. Done this way @@ -91,36 +87,37 @@ func _is_script_editor(obj): # future proofed. func _find_script_editors_parent(): var _first_editor = _get_first_child_of_type_name("ScriptTextEditor", _script_editor) - if(_first_editor != null): + if _first_editor != null: _script_editors_parent = _first_editor.get_parent() func _populate_editors(): - if(_script_editors_parent == null): + if _script_editors_parent == null: return _script_editor_controls.clear() for child in _script_editors_parent.get_children(): - if(_is_script_editor(child)): + if _is_script_editor(child): var ref = ScriptEditorControlRef.new(child) _script_editor_controls.append(ref) + # Yes, this is the same as the one above but with a different name. This was # easier than trying to find a place where it could be used by both. func _get_first_child_of_type_name(obj_name, parent_obj): - if(parent_obj == null): + if parent_obj == null: return null var kids = parent_obj.get_children() var index = 0 var to_return = null - while(index < kids.size() and to_return == null): - if(str(kids[index]).find(str("[", obj_name)) != -1): + while index < kids.size() and to_return == null: + if str(kids[index]).find(str("[", obj_name)) != -1: to_return = kids[index] else: to_return = _get_first_child_of_type_name(obj_name, kids[index]) - if(to_return == null): + if to_return == null: index += 1 return to_return @@ -139,11 +136,12 @@ func _get_class_name_from_line(text): var the_name = right.rstrip(":") return the_name + func refresh(): - if(_script_editors_parent == null): + if _script_editors_parent == null: _find_script_editors_parent() - if(_script_editors_parent != null): + if _script_editors_parent != null: _populate_editors() @@ -151,14 +149,14 @@ func get_current_text_edit(): var cur_script_editor = null var idx = 0 - while(idx < _script_editor_controls.size() and cur_script_editor == null): - if(_script_editor_controls[idx].is_visible()): + while idx < _script_editor_controls.size() and cur_script_editor == null: + if _script_editor_controls[idx].is_visible(): cur_script_editor = _script_editor_controls[idx] else: idx += 1 var to_return = null - if(cur_script_editor != null): + if cur_script_editor != null: to_return = cur_script_editor.get_text_edit() return to_return @@ -174,36 +172,32 @@ func get_script_editor_controls(): func get_line_info(): var editor = get_current_text_edit() - if(editor == null): + if editor == null: return - var info = { - script = null, - inner_class = null, - test_method = null - } + var info = {script = null, inner_class = null, test_method = null} var line = editor.get_caret_line() var done_func = false var done_inner = false - while(line > 0 and (!done_func or !done_inner)): - if(editor.can_fold_line(line)): + while line > 0 and (!done_func or !done_inner): + if editor.can_fold_line(line): var text = editor.get_line(line) - var strip_text = text.strip_edges(true, false) # only left + var strip_text = text.strip_edges(true, false) # only left - if(!done_func and strip_text.begins_with("func ")): + if !done_func and strip_text.begins_with("func "): var func_name = _get_func_name_from_line(text) - if(func_name.begins_with(_method_prefix)): + if func_name.begins_with(_method_prefix): info.test_method = func_name done_func = true # If the func line is left justified then there won't be any # inner classes above it. - if(strip_text == text): + if strip_text == text: done_inner = true - if(!done_inner and strip_text.begins_with("class")): + if !done_inner and strip_text.begins_with("class"): var inner_name = _get_class_name_from_line(text) - if(inner_name.begins_with(_inner_class_prefix)): + if inner_name.begins_with(_inner_class_prefix): info.inner_class = inner_name done_inner = true # if we found an inner class then we are already past diff --git a/addons/gut/gut.gd b/addons/gut/gut.gd index e067411..72ce0b6 100644 --- a/addons/gut/gut.gd +++ b/addons/gut/gut.gd @@ -29,7 +29,7 @@ # View the readme at https://github.com/bitwes/Gut/blob/master/README.md for usage details. # You should also check out the github wiki at: https://github.com/bitwes/Gut/wiki # ############################################################################## -extends 'res://addons/gut/gut_to_move.gd' +extends "res://addons/gut/gut_to_move.gd" # ########################### # Constants @@ -37,9 +37,9 @@ extends 'res://addons/gut/gut_to_move.gd' const LOG_LEVEL_FAIL_ONLY = 0 const LOG_LEVEL_TEST_AND_FAILURES = 1 const LOG_LEVEL_ALL_ASSERTS = 2 -const WAITING_MESSAGE = '/# waiting #/' -const PAUSE_MESSAGE = '/# Pausing. Press continue button...#/' -const COMPLETED = 'completed' +const WAITING_MESSAGE = "/# waiting #/" +const PAUSE_MESSAGE = "/# Pausing. Press continue button...#/" +const COMPLETED = "completed" # ########################### # Signals @@ -54,7 +54,6 @@ signal end_script signal start_test(test_name) signal end_test - # ########################### # Settings # @@ -62,111 +61,138 @@ signal end_test # gutconfig. # ########################### -var _inner_class_name = '' +var _inner_class_name = "" ## When set, GUT will only run Inner-Test-Classes that contain this string. -var inner_class_name = _inner_class_name : - get: return _inner_class_name - set(val): _inner_class_name = val +var inner_class_name = _inner_class_name: + get: + return _inner_class_name + set(val): + _inner_class_name = val var _ignore_pause_before_teardown = false ## For batch processing purposes, you may want to ignore any calls to ## pause_before_teardown that you forgot to remove_at. -var ignore_pause_before_teardown = _ignore_pause_before_teardown : - get: return _ignore_pause_before_teardown - set(val): _ignore_pause_before_teardown = val +var ignore_pause_before_teardown = _ignore_pause_before_teardown: + get: + return _ignore_pause_before_teardown + set(val): + _ignore_pause_before_teardown = val # TODO remove this -var _temp_directory = 'user://gut_temp_directory' +var _temp_directory = "user://gut_temp_directory" ## The directory where GUT stores any temporary information during a run. -var temp_directory = _temp_directory : - get: return _temp_directory - set(val): _temp_directory = val - +var temp_directory = _temp_directory: + get: + return _temp_directory + set(val): + _temp_directory = val var _log_level = 1 ## The log detail level. Valid values are 0 - 2. Larger values do not matter. var log_level = 1: - get: return _log_level - set(val): _set_log_level(val) + get: + return _log_level + set(val): + _set_log_level(val) # TODO 4.0 # This appears to not be used anymore. Going to wait for more tests to be # ported before removing. var _disable_strict_datatype_checks = false -var disable_strict_datatype_checks = false : - get: return _disable_strict_datatype_checks - set(val): _disable_strict_datatype_checks = val +var disable_strict_datatype_checks = false: + get: + return _disable_strict_datatype_checks + set(val): + _disable_strict_datatype_checks = val -var _export_path = '' +var _export_path = "" ## Path to file that GUT will create which holds a list of all test scripts so ## that GUT can run tests when a project is exported. -var export_path = '' : - get: return _export_path - set(val): _export_path = val +var export_path = "": + get: + return _export_path + set(val): + _export_path = val var _include_subdirectories = false ## Setting this to true will make GUT search all subdirectories of any directory ## you have configured GUT to search for tests in. -var include_subdirectories = _include_subdirectories : - get: return _include_subdirectories - set(val): _include_subdirectories = val +var include_subdirectories = _include_subdirectories: + get: + return _include_subdirectories + set(val): + _include_subdirectories = val var _double_strategy = 1 ## TODO rework what this is and then document it here. -var double_strategy = 1 : - get: return _double_strategy +var double_strategy = 1: + get: + return _double_strategy set(val): _double_strategy = val _doubler.set_strategy(double_strategy) -var _pre_run_script = '' +var _pre_run_script = "" ## Path to the script that will be run before all tests are run. This script ## must extend GutHookScript -var pre_run_script = _pre_run_script : - get: return _pre_run_script - set(val): _pre_run_script = val +var pre_run_script = _pre_run_script: + get: + return _pre_run_script + set(val): + _pre_run_script = val -var _post_run_script = '' +var _post_run_script = "" ## Path to the script that will run after all tests have run. The script ## must extend GutHookScript -var post_run_script = _post_run_script : - get: return _post_run_script - set(val): _post_run_script = val +var post_run_script = _post_run_script: + get: + return _post_run_script + set(val): + _post_run_script = val var _color_output = false ## Flag to color output at the command line and in the GUT GUI. -var color_output = false : - get: return _color_output +var color_output = false: + get: + return _color_output set(val): _color_output = val _lgr.disable_formatting(!_color_output) -var _junit_xml_file = '' +var _junit_xml_file = "" ## The full path to where GUT should write a JUnit compliant XML file to which ## contains the results of all tests run. -var junit_xml_file = '' : - get: return _junit_xml_file - set(val): _junit_xml_file = val +var junit_xml_file = "": + get: + return _junit_xml_file + set(val): + _junit_xml_file = val var _junit_xml_timestamp = false ## When true and junit_xml_file is set, the file name will include a ## timestamp so that previous files are not overwritten. -var junit_xml_timestamp = false : - get: return _junit_xml_timestamp - set(val): _junit_xml_timestamp = val +var junit_xml_timestamp = false: + get: + return _junit_xml_timestamp + set(val): + _junit_xml_timestamp = val ## The minimum amout of time GUT will wait before pausing for 1 frame to allow ## the screen to paint. GUT checkes after each test to see if enough time has ## passed. var paint_after = .1: - get: return paint_after - set(val): paint_after = val + get: + return paint_after + set(val): + paint_after = val -var _unit_test_name = '' +var _unit_test_name = "" ## When set GUT will only run tests that contain this string. -var unit_test_name = _unit_test_name : - get: return _unit_test_name - set(val): _unit_test_name = val +var unit_test_name = _unit_test_name: + get: + return _unit_test_name + set(val): + _unit_test_name = val # ########################### # Public Properties @@ -176,8 +202,9 @@ var _parameter_handler = null # This is populated by test.gd each time a paramterized test is encountered # for the first time. ## FOR INTERNAL USE ONLY -var parameter_handler = _parameter_handler : - get: return _parameter_handler +var parameter_handler = _parameter_handler: + get: + return _parameter_handler set(val): _parameter_handler = val _parameter_handler.set_logger(_lgr) @@ -185,8 +212,9 @@ var parameter_handler = _parameter_handler : var _lgr = _utils.get_logger() # Local reference for the common logger. ## FOR INERNAL USE ONLY -var logger = _lgr : - get: return _lgr +var logger = _lgr: + get: + return _lgr set(val): _lgr = val _lgr.set_gut(self) @@ -196,43 +224,65 @@ var _add_children_to = self # default is self, but can be set to other objects so that GUT is not obscured # by the objects added during tests. ## FOR INERNAL USE ONLY -var add_children_to = self : - get: return _add_children_to - set(val): _add_children_to = val - +var add_children_to = self: + get: + return _add_children_to + set(val): + _add_children_to = val # ------------ # Read only # ------------ var _test_collector = _utils.TestCollector.new() + + func get_test_collector(): return _test_collector + # var version = null : func get_version(): return _utils.version -var _orphan_counter = _utils.OrphanCounter.new() + +var _orphan_counter = _utils.OrphanCounter.new() + + func get_orphan_counter(): return _orphan_counter + var _autofree = _utils.AutoFree.new() + + func get_autofree(): return _autofree + var _stubber = _utils.Stubber.new() + + func get_stubber(): return _stubber + var _doubler = _utils.Doubler.new() + + func get_doubler(): return _doubler + var _spy = _utils.Spy.new() + + func get_spy(): return _spy + var _is_running = false + + func is_running(): return _is_running @@ -240,21 +290,21 @@ func is_running(): # ########################### # Private # ########################### -var _should_print_versions = true # used to cut down on output in tests. +var _should_print_versions = true # used to cut down on output in tests. var _should_print_summary = true -var _test_prefix = 'test_' -var _file_prefix = 'test_' -var _inner_class_prefix = 'Test' +var _test_prefix = "test_" +var _file_prefix = "test_" +var _inner_class_prefix = "Test" -var _select_script = '' +var _select_script = "" var _last_paint_time = 0.0 var _strutils = _utils.Strutils.new() # The instance that is created from _pre_run_script. Accessible from # get_pre_run_script_instance. var _pre_run_script_instance = null -var _post_run_script_instance = null # This is not used except in tests. +var _post_run_script_instance = null # This is not used except in tests. var _script_name = null @@ -270,11 +320,9 @@ var _start_time = 0.0 var _current_test = null var _pause_before_teardown = false - var _awaiter = _utils.Awaiter.new() var _new_summary = null - # Used to cancel importing scripts if an error has occurred in the setup. This # prevents tests from being run if they were exported and ensures that the # error displayed is seen since importing generates a lot of text. @@ -284,16 +332,16 @@ var _new_summary = null var _cancel_import = false # Used for proper assert tracking and printing during before_all -var _before_all_test_obj = load('res://addons/gut/test_collector.gd').Test.new() +var _before_all_test_obj = load("res://addons/gut/test_collector.gd").Test.new() # Used for proper assert tracking and printing during after_all -var _after_all_test_obj = load('res://addons/gut/test_collector.gd').Test.new() +var _after_all_test_obj = load("res://addons/gut/test_collector.gd").Test.new() # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func _init(): - _before_all_test_obj.name = 'before_all' - _after_all_test_obj.name = 'after_all' + _before_all_test_obj.name = "before_all" + _after_all_test_obj.name = "after_all" # When running tests for GUT itself, _utils has been setup to always return # a new logger so this does not set the gut instance on the base logger # when creating test instances of GUT. @@ -310,52 +358,50 @@ func _init(): _test_collector.set_logger(_lgr) - # ------------------------------------------------------------------------------ # Initialize controls # ------------------------------------------------------------------------------ func _ready(): - if(!_utils.is_version_ok()): + if !_utils.is_version_ok(): _print_versions() push_error(_utils.get_bad_version_text()) - print('Error: ', _utils.get_bad_version_text()) + print("Error: ", _utils.get_bad_version_text()) get_tree().quit() return - if(_should_print_versions): - _lgr.info(str('using [', OS.get_user_data_dir(), '] for temporary output.')) + if _should_print_versions: + _lgr.info(str("using [", OS.get_user_data_dir(), "] for temporary output.")) add_child(_awaiter) - if(_select_script != null): + if _select_script != null: select_script(_select_script) _print_versions() + # ------------------------------------------------------------------------------ # Runs right before free is called. Can't override `free`. # ------------------------------------------------------------------------------ func _notification(what): - if(what == NOTIFICATION_PREDELETE): + if what == NOTIFICATION_PREDELETE: for test_script in _test_script_objects: - if(is_instance_valid(test_script)): + if is_instance_valid(test_script): test_script.free() _test_script_objects = [] func _print_versions(send_all = true): - if(!_should_print_versions): + if !_should_print_versions: return var info = _utils.get_version_text() - if(send_all): + if send_all: p(info) else: - _lgr.get_printer('gui').send(info + "\n") - - + _lgr.get_printer("gui").send(info + "\n") # #################### @@ -387,6 +433,7 @@ func _set_log_level(level): _lgr.set_type_enabled(_lgr.types.info, level > 1) _lgr.set_type_enabled(_lgr.types.debug, level > 1) + # #################### # # Events @@ -397,90 +444,98 @@ func end_teardown_pause(): _waiting = false end_pause_before_teardown.emit() + ##################### # # Private # ##################### + func _log_test_children_warning(test_script): - if(!_lgr.is_type_enabled(_lgr.types.orphan)): + if !_lgr.is_type_enabled(_lgr.types.orphan): return var kids = test_script.get_children() - if(kids.size() > 0): - var msg = '' - if(_log_level == 2): + if kids.size() > 0: + var msg = "" + if _log_level == 2: msg = "Test script still has children when all tests finisehd.\n" for i in range(kids.size()): msg += str(" ", _strutils.type2str(kids[i]), "\n") msg += "You can use autofree, autoqfree, add_child_autofree, or add_child_autoqfree to automatically free objects." else: - msg = str("Test script has ", kids.size(), " unfreed children. Increase log level for more details.") - + msg = str( + "Test script has ", + kids.size(), + " unfreed children. Increase log level for more details." + ) _lgr.warn(msg) + # ------------------------------------------------------------------------------ # Convert the _summary dictionary into text # ------------------------------------------------------------------------------ func _print_summary(): - if(!_should_print_summary): + if !_should_print_summary: return _lgr.log("\n\n\n") - _lgr.log('==============================================', _lgr.fmts.yellow) + _lgr.log("==============================================", _lgr.fmts.yellow) _lgr.log("= Run Summary", _lgr.fmts.yellow) - _lgr.log('==============================================', _lgr.fmts.yellow) + _lgr.log("==============================================", _lgr.fmts.yellow) _new_summary.log_summary_text(_lgr) - var logger_text = '' - if(_lgr.get_errors().size() > 0): - logger_text += str("\n* ", _lgr.get_errors().size(), ' Errors.') - if(_lgr.get_warnings().size() > 0): - logger_text += str("\n* ", _lgr.get_warnings().size(), ' Warnings.') - if(_lgr.get_deprecated().size() > 0): - logger_text += str("\n* ", _lgr.get_deprecated().size(), ' Deprecated calls.') - if(logger_text != ''): + var logger_text = "" + if _lgr.get_errors().size() > 0: + logger_text += str("\n* ", _lgr.get_errors().size(), " Errors.") + if _lgr.get_warnings().size() > 0: + logger_text += str("\n* ", _lgr.get_warnings().size(), " Warnings.") + if _lgr.get_deprecated().size() > 0: + logger_text += str("\n* ", _lgr.get_deprecated().size(), " Deprecated calls.") + if logger_text != "": logger_text = "\nWarnings/Errors:" + logger_text + "\n\n" _lgr.log(logger_text) - if(_new_summary.get_totals().tests > 0): + if _new_summary.get_totals().tests > 0: var fmt = _lgr.fmts.green - var msg = str(_new_summary.get_totals().passing_tests) + ' passed ' + str(_new_summary.get_totals().failing_tests) + ' failed. ' + \ - str("Tests finished in ", get_elapsed_time(), 's') - if(_new_summary.get_totals().failing > 0): + var msg = ( + str(_new_summary.get_totals().passing_tests) + + " passed " + + str(_new_summary.get_totals().failing_tests) + + " failed. " + + str("Tests finished in ", get_elapsed_time(), "s") + ) + if _new_summary.get_totals().failing > 0: fmt = _lgr.fmts.red - elif(_new_summary.get_totals().pending > 0): + elif _new_summary.get_totals().pending > 0: fmt = _lgr.fmts.yellow _lgr.log(msg, fmt) else: - _lgr.log('No tests ran', _lgr.fmts.red) + _lgr.log("No tests ran", _lgr.fmts.red) func _validate_hook_script(path): - var result = { - valid = true, - instance = null - } + var result = {valid = true, instance = null} # empty path is valid but will have a null instance - if(path == ''): + if path == "": return result - if(FileAccess.file_exists(path)): + if FileAccess.file_exists(path): var inst = load(path).new() - if(inst and inst is _utils.HookScript): + if inst and inst is _utils.HookScript: result.instance = inst result.valid = true else: result.valid = false - _lgr.error('The hook script [' + path + '] does not extend GutHookScript') + _lgr.error("The hook script [" + path + "] does not extend GutHookScript") else: result.valid = false - _lgr.error('The hook script [' + path + '] does not exist.') + _lgr.error("The hook script [" + path + "] does not exist.") return result @@ -490,11 +545,12 @@ func _validate_hook_script(path): # res://addons/gut/hook_script.gd # ------------------------------------------------------------------------------ func _run_hook_script(inst): - if(inst != null): + if inst != null: inst.gut = self inst.run() return inst + # ------------------------------------------------------------------------------ # Initialize variables for each run of a single test script. # ------------------------------------------------------------------------------ @@ -509,9 +565,9 @@ func _init_run(): var pre_hook_result = _validate_hook_script(_pre_run_script) _pre_run_script_instance = pre_hook_result.instance var post_hook_result = _validate_hook_script(_post_run_script) - _post_run_script_instance = post_hook_result.instance + _post_run_script_instance = post_hook_result.instance - valid = pre_hook_result.valid and post_hook_result.valid + valid = pre_hook_result.valid and post_hook_result.valid return valid @@ -526,18 +582,18 @@ func _end_run(): # Do not count any of the _test_script_objects since these will be released # when GUT is released. _orphan_counter._counters.total += _test_script_objects.size() - if(_orphan_counter.get_counter('total') > 0 and _lgr.is_type_enabled('orphan')): - _orphan_counter.print_orphans('total', _lgr) + if _orphan_counter.get_counter("total") > 0 and _lgr.is_type_enabled("orphan"): + _orphan_counter.print_orphans("total", _lgr) p("Note: This count does not include GUT objects that will be freed upon exit.") p(" It also does not include any orphans created by global scripts") p(" loaded before tests were ran.") p(str("Total orphans = ", _orphan_counter.orphan_count())) - if(!_utils.is_null_or_empty(_select_script)): + if !_utils.is_null_or_empty(_select_script): p('Ran Scripts matching "' + _select_script + '"') - if(!_utils.is_null_or_empty(_unit_test_name)): + if !_utils.is_null_or_empty(_unit_test_name): p('Ran Tests matching "' + _unit_test_name + '"') - if(!_utils.is_null_or_empty(_inner_class_name)): + if !_utils.is_null_or_empty(_inner_class_name): p('Ran Inner Classes matching "' + _inner_class_name + '"') _is_running = false @@ -548,32 +604,32 @@ func _end_run(): if _utils.should_display_latest_version: p("") - p(str("GUT version ",_utils.latest_version," is now available.")) + p(str("GUT version ", _utils.latest_version, " is now available.")) # ------------------------------------------------------------------------------ # Add additional export types here. # ------------------------------------------------------------------------------ func _export_results(): - if(_junit_xml_file != ''): + if _junit_xml_file != "": _export_junit_xml() + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func _export_junit_xml(): var exporter = _utils.JunitXmlExport.new() var output_file = _junit_xml_file - if(_junit_xml_timestamp): + if _junit_xml_timestamp: var ext = "." + output_file.get_extension() output_file = output_file.replace(ext, str("_", Time.get_unix_time_from_system(), ext)) var f_result = exporter.write_file(self, output_file) - if(f_result == OK): + if f_result == OK: p(str("Results saved to ", output_file)) - # ------------------------------------------------------------------------------ # Checks the passed in thing to see if it is a "function state" object that gets # returned when a function yields. @@ -587,19 +643,20 @@ func _is_function_state(script_result): # script_result is GDScriptFunctionState and \ # script_result.is_valid() + # ------------------------------------------------------------------------------ # Print out the heading for a new script # ------------------------------------------------------------------------------ func _print_script_heading(script): - if(_does_class_name_match(_inner_class_name, script.inner_class_name)): + if _does_class_name_match(_inner_class_name, script.inner_class_name): var fmt = _lgr.fmts.underline - var divider = '-----------------------------------------' + var divider = "-----------------------------------------" - var text = '' - if(script.inner_class_name == null): + var text = "" + if script.inner_class_name == null: text = script.path else: - text = str(script.path, '.', script.inner_class_name) + text = str(script.path, ".", script.inner_class_name) _lgr.log("\n\n" + text, fmt) @@ -607,8 +664,11 @@ func _print_script_heading(script): # Yes if the class name is null or the script's class name includes class_name # ------------------------------------------------------------------------------ func _does_class_name_match(the_class_name, script_class_name): - return (the_class_name == null or the_class_name == '') or \ - (script_class_name != null and str(script_class_name).findn(the_class_name) != -1) + return ( + (the_class_name == null or the_class_name == "") + or (script_class_name != null and str(script_class_name).findn(the_class_name) != -1) + ) + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ @@ -631,21 +691,23 @@ func _wait_for_continue_button(): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func _get_indexes_matching_script_name(name): - var indexes = [] # empty runs all + var indexes = [] # empty runs all for i in range(_test_collector.scripts.size()): - if(_test_collector.scripts[i].get_filename().find(name) != -1): + if _test_collector.scripts[i].get_filename().find(name) != -1: indexes.append(i) return indexes + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func _get_indexes_matching_path(path): var indexes = [] for i in range(_test_collector.scripts.size()): - if(_test_collector.scripts[i].path == path): + if _test_collector.scripts[i].path == path: indexes.append(i) return indexes + # ------------------------------------------------------------------------------ # Execute all calls of a parameterized test. # ------------------------------------------------------------------------------ @@ -658,14 +720,26 @@ func _run_parameterized_test(test_script, test_name): # await script_result.COMPLETED # ---- - if(_current_test.assert_count == 0 and !_current_test.pending): - _lgr.warn('Test did not assert') + if _current_test.assert_count == 0 and !_current_test.pending: + _lgr.warn("Test did not assert") - if(_parameter_handler == null): - _lgr.error(str('Parameterized test ', _current_test.name, ' did not call use_parameters for the default value of the parameter.')) - _fail(str('Parameterized test ', _current_test.name, ' did not call use_parameters for the default value of the parameter.')) + if _parameter_handler == null: + _lgr.error( + str( + "Parameterized test ", + _current_test.name, + " did not call use_parameters for the default value of the parameter." + ) + ) + _fail( + str( + "Parameterized test ", + _current_test.name, + " did not call use_parameters for the default value of the parameter." + ) + ) else: - while(!_parameter_handler.is_done()): + while !_parameter_handler.is_done(): var cur_assert_count = _current_test.assert_count await _run_test(test_script, test_name) # TODO 4.0 GDScriptFunctionState? ---- @@ -674,8 +748,8 @@ func _run_parameterized_test(test_script, test_name): # # _run_tests does _wait_for_done so just wait on it to complete # await script_result.COMPLETED # ---- - if(_current_test.assert_count == cur_assert_count and !_current_test.pending): - _lgr.warn('Test did not assert') + if _current_test.assert_count == cur_assert_count and !_current_test.pending: + _lgr.warn("Test did not assert") _parameter_handler = null @@ -686,7 +760,7 @@ func _run_parameterized_test(test_script, test_name): func _run_test(script_inst, test_name): _lgr.log_test_name() _lgr.set_indent_level(1) - _orphan_counter.add_counter('test') + _orphan_counter.add_counter("test") var script_result = null await script_inst.before_each() @@ -705,7 +779,7 @@ func _run_test(script_inst, test_name): # await _wait_for_done(script_result) # ---- var test_summary = _new_summary.add_test(test_name) - if(test_summary == null): + if test_summary == null: var msg = "Summary was null. This has been seen to happen when a test \n" msg += "calls unreference. Adding 'await get_tree().process_frame' somewhere between\n" msg += "instantiation and calling unreference, in your test, may fix this issue.\n" @@ -715,7 +789,7 @@ func _run_test(script_inst, test_name): # if the test called pause_before_teardown then await until # the continue button is pressed. - if(_pause_before_teardown and !_ignore_pause_before_teardown): + if _pause_before_teardown and !_ignore_pause_before_teardown: start_pause_before_teardown.emit() await _wait_for_continue_button().end_pause_before_teardown @@ -734,15 +808,16 @@ func _run_test(script_inst, test_name): # free and are not found by the orphan counter. var aqf_count = _autofree.get_queue_free_count() _autofree.free_all() - if(aqf_count > 0): + if aqf_count > 0: await get_tree().create_timer(.25).timeout - test_summary.orphans = _orphan_counter.get_counter('test') - if(_log_level > 0): - _orphan_counter.print_orphans('test', _lgr) + test_summary.orphans = _orphan_counter.get_counter("test") + if _log_level > 0: + _orphan_counter.print_orphans("test", _lgr) _doubler.get_ignored_methods().clear() + # ------------------------------------------------------------------------------ # Calls after_all on the passed in test script and takes care of settings so all # logger output appears indented and with a proper heading @@ -755,8 +830,8 @@ func _call_before_all(test_script): _lgr.inc_indent() # Next 3 lines can be removed when prerun_setup removed. - _current_test.name = 'prerun_setup' - _current_test.name = 'before_all' + _current_test.name = "prerun_setup" + _current_test.name = "before_all" await test_script.before_all() # TODO 4.0 GDScriptFunctionState? ---- @@ -768,6 +843,7 @@ func _call_before_all(test_script): _lgr.dec_indent() _current_test = null + # ------------------------------------------------------------------------------ # Calls after_all on the passed in test script and takes care of settings so all # logger output appears indented and with a proper heading @@ -780,9 +856,8 @@ func _call_after_all(test_script): _lgr.inc_indent() # Next 3 lines can be removed when postrun_teardown removed. - _current_test.name = 'postrun_teardown' - _current_test.name = 'after_all' - + _current_test.name = "postrun_teardown" + _current_test.name = "after_all" await test_script.after_all() # TODO 4.0 GDScriptFunctionState? ---- @@ -794,21 +869,22 @@ func _call_after_all(test_script): _lgr.dec_indent() _current_test = null + # ------------------------------------------------------------------------------ # Run all tests in a script. This is the core logic for running tests. # ------------------------------------------------------------------------------ -func _test_the_scripts(indexes=[]): - _orphan_counter.add_counter('total') +func _test_the_scripts(indexes = []): + _orphan_counter.add_counter("total") _print_versions(false) var is_valid = _init_run() - if(!is_valid): - _lgr.error('Something went wrong and the run was aborted.') + if !is_valid: + _lgr.error("Something went wrong and the run was aborted.") return _run_hook_script(_pre_run_script_instance) - if(_pre_run_script_instance!= null and _pre_run_script_instance.should_abort()): - _lgr.error('pre-run abort') + if _pre_run_script_instance != null and _pre_run_script_instance.should_abort(): + _lgr.error("pre-run abort") end_run.emit() return @@ -817,24 +893,23 @@ func _test_the_scripts(indexes=[]): _last_paint_time = _start_time var indexes_to_run = [] - if(indexes.size()==0): + if indexes.size() == 0: for i in range(_test_collector.scripts.size()): indexes_to_run.append(i) else: indexes_to_run = indexes - # loop through scripts for test_indexes in range(indexes_to_run.size()): var the_script = _test_collector.scripts[indexes_to_run[test_indexes]] - _orphan_counter.add_counter('script') + _orphan_counter.add_counter("script") - if(the_script.tests.size() > 0): + if the_script.tests.size() > 0: _lgr.set_indent_level(0) _print_script_heading(the_script) _new_summary.add_script(the_script.get_full_name()) - if(!the_script.is_loaded): + if !the_script.is_loaded: break start_script.emit(the_script) @@ -844,9 +919,9 @@ func _test_the_scripts(indexes=[]): # ---- # SHORTCIRCUIT # skip_script logic - var skip_script = test_script.get('skip_script') - if(skip_script != null): - var msg = str('- [Script skipped]: ', skip_script) + var skip_script = test_script.get("skip_script") + if skip_script != null: + var msg = str("- [Script skipped]: ", skip_script) _lgr.inc_indent() _lgr.log(msg, _lgr.fmts.yellow) _lgr.dec_indent() @@ -864,7 +939,7 @@ func _test_the_scripts(indexes=[]): # inner class is set and we do not have a match then empty the tests # for the current test. # !!! - if(!_does_class_name_match(_inner_class_name, the_script.inner_class_name)): + if !_does_class_name_match(_inner_class_name, the_script.inner_class_name): the_script.tests = [] else: await _call_before_all(test_script) @@ -875,9 +950,8 @@ func _test_the_scripts(indexes=[]): # await before_all_result.COMPLETED # ---- - # Each test in the script - var skip_suffix = '_skip__' + var skip_suffix = "_skip__" the_script.mark_tests_to_skip_with_suffix(skip_suffix) for i in range(the_script.tests.size()): _stubber.clear() @@ -887,18 +961,28 @@ func _test_the_scripts(indexes=[]): # ------------------ # SHORTCIRCUI - if(_current_test.should_skip): - _new_summary.add_pending(_current_test.name, 'SKIPPED because it ends with ' + skip_suffix) + if _current_test.should_skip: + _new_summary.add_pending( + _current_test.name, "SKIPPED because it ends with " + skip_suffix + ) continue # ------------------ - if((_unit_test_name != '' and _current_test.name.find(_unit_test_name) > -1) or - (_unit_test_name == '')): - - if(_current_test.arg_count > 1): - _lgr.error(str('Parameterized test ', _current_test.name, - ' has too many parameters: ', _current_test.arg_count, '.')) - elif(_current_test.arg_count == 1): + if ( + (_unit_test_name != "" and _current_test.name.find(_unit_test_name) > -1) + or (_unit_test_name == "") + ): + if _current_test.arg_count > 1: + _lgr.error( + str( + "Parameterized test ", + _current_test.name, + " has too many parameters: ", + _current_test.arg_count, + "." + ) + ) + elif _current_test.arg_count == 1: script_result = await _run_parameterized_test(test_script, _current_test.name) else: script_result = await _run_test(test_script, _current_test.name) @@ -909,26 +993,26 @@ func _test_the_scripts(indexes=[]): # await script_result.COMPLETED # ---- - if(!_current_test.did_assert()): - _lgr.warn('Test did not assert') + if !_current_test.did_assert(): + _lgr.warn("Test did not assert") _current_test.has_printed_name = false end_test.emit() # After each test, check to see if we shoudl wait a frame to # paint based on how much time has elapsed since we last 'painted' - if(paint_after > 0.0): + if paint_after > 0.0: var now = Time.get_ticks_msec() var time_since = (now - _last_paint_time) / 1000.0 - if(time_since > paint_after): + if time_since > paint_after: _last_paint_time = now await get_tree().process_frame _current_test = null _lgr.dec_indent() - _orphan_counter.print_orphans('script', _lgr) + _orphan_counter.print_orphans("script", _lgr) - if(_does_class_name_match(_inner_class_name, the_script.inner_class_name)): + if _does_class_name_match(_inner_class_name, the_script.inner_class_name): await _call_after_all(test_script) # TODO 4.0 GDScriptFunctionState? ---- # var after_all_result = await _call_after_all(test_script) @@ -937,7 +1021,6 @@ func _test_the_scripts(indexes=[]): # await after_all_result.COMPLETED # ---- - _log_test_children_warning(test_script) # This might end up being very resource intensive if the scripts # don't clean up after themselves. Might have to consolidate output @@ -946,8 +1029,10 @@ func _test_the_scripts(indexes=[]): _add_children_to.remove_child(test_script) _lgr.set_indent_level(0) - if(test_script.get_assert_count() > 0): - var script_sum = str(test_script.get_pass_count(), '/', test_script.get_assert_count(), ' passed.') + if test_script.get_assert_count() > 0: + var script_sum = str( + test_script.get_pass_count(), "/", test_script.get_assert_count(), " passed." + ) _lgr.log(script_sum, _lgr.fmts.bold) end_script.emit() @@ -959,34 +1044,34 @@ func _test_the_scripts(indexes=[]): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func _pass(text=''): - if(_current_test): +func _pass(text = ""): + if _current_test: _current_test.assert_count += 1 _new_summary.add_pass(_current_test.name, text) else: - if(_new_summary != null): # b/c of tests. - _new_summary.add_pass('script level', text) + if _new_summary != null: # b/c of tests. + _new_summary.add_pass("script level", text) # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func _fail(text=''): - if(_current_test != null): +func _fail(text = ""): + if _current_test != null: var line_number = _extract_line_number(_current_test) - var line_text = ' at line ' + str(line_number) + var line_text = " at line " + str(line_number) p(line_text, LOG_LEVEL_FAIL_ONLY) # format for summary - line_text = "\n " + line_text - var call_count_text = '' - if(_parameter_handler != null): - call_count_text = str('(call #', _parameter_handler.get_call_count(), ') ') + line_text = "\n " + line_text + var call_count_text = "" + if _parameter_handler != null: + call_count_text = str("(call #", _parameter_handler.get_call_count(), ") ") _new_summary.add_fail(_current_test.name, call_count_text + text + line_text) _current_test.passed = false _current_test.assert_count += 1 _current_test.line_number = line_number else: - if(_new_summary != null): # b/c of tests. - _new_summary.add_fail('script level', text) + if _new_summary != null: # b/c of tests. + _new_summary.add_fail("script level", text) # ------------------------------------------------------------------------------ @@ -996,7 +1081,7 @@ func _extract_line_number(current_test): var line_number = -1 # if stack trace available than extraxt the test case line number var stackTrace = get_stack() - if(stackTrace!=null): + if stackTrace != null: for index in stackTrace.size(): var line = stackTrace[index] var function = line.get("function") @@ -1007,8 +1092,8 @@ func _extract_line_number(current_test): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func _pending(text=''): - if(_current_test): +func _pending(text = ""): + if _current_test: _current_test.pending = true _new_summary.add_pending(_current_test.name, text) @@ -1021,26 +1106,26 @@ func _get_files(path, prefix, suffix): var files = [] var directories = [] # ignore addons/gut per issue 294 - if(path == 'res://addons/gut'): - return []; + if path == "res://addons/gut": + return [] var d = DirAccess.open(path) # true parameter tells list_dir_begin not to include "." and ".." directories. - d.list_dir_begin() # TODO 4.0 fill missing arguments https://github.com/godotengine/godot/pull/40547 + d.list_dir_begin() # TODO 4.0 fill missing arguments https://github.com/godotengine/godot/pull/40547 # Traversing a directory is kinda odd. You have to start the process of listing # the contents of a directory with list_dir_begin then use get_next until it # returns an empty string. Then I guess you should end it. var fs_item = d.get_next() - var full_path = '' - while(fs_item != ''): + var full_path = "" + while fs_item != "": full_path = path.path_join(fs_item) #file_exists returns fasle for directories - if(d.file_exists(full_path)): - if(fs_item.begins_with(prefix) and fs_item.ends_with(suffix)): + if d.file_exists(full_path): + if fs_item.begins_with(prefix) and fs_item.ends_with(suffix): files.append(full_path) - elif(include_subdirectories and d.dir_exists(full_path)): + elif include_subdirectories and d.dir_exists(full_path): directories.append(full_path) fs_item = d.get_next() @@ -1062,12 +1147,13 @@ func _get_files(path, prefix, suffix): ######################### func get_elapsed_time(): var to_return = 0.0 - if(_start_time != 0.0): + if _start_time != 0.0: to_return = Time.get_ticks_msec() - _start_time to_return = to_return / 1000.0 return to_return + # ------------------------------------------------------------------------------ # Conditionally prints the text to the console/results variable based on the # current log level and what level is passed in. Whenever currently in a test, @@ -1077,37 +1163,45 @@ func get_elapsed_time(): # The first time output is generated when in a test, the test name will be # printed. # ------------------------------------------------------------------------------ -func p(text, level=0): +func p(text, level = 0): var str_text = str(text) - if(level <= _utils.nvl(_log_level, 0)): + if level <= _utils.nvl(_log_level, 0): _lgr.log(str_text) + ################ # # RUN TESTS/ADD SCRIPTS # ################ + # ------------------------------------------------------------------------------ # Runs all the scripts that were added using add_script # ------------------------------------------------------------------------------ -func test_scripts(run_rest=false): +func test_scripts(run_rest = false): clear_text() - if(_script_name != null and _script_name != ''): + if _script_name != null and _script_name != "": var indexes = _get_indexes_matching_script_name(_script_name) - if(indexes == []): - _lgr.error(str( - "Could not find script matching '", _script_name, "'.\n", - "Check your directory settings and Script Prefix/Suffix settings.")) + if indexes == []: + _lgr.error( + str( + "Could not find script matching '", + _script_name, + "'.\n", + "Check your directory settings and Script Prefix/Suffix settings." + ) + ) else: _test_the_scripts(indexes) else: _test_the_scripts([]) + # alias -func run_tests(run_rest=false): +func run_tests(run_rest = false): test_scripts(run_rest) @@ -1125,7 +1219,7 @@ func test_script(script): # Adds a script to be run when test_scripts called. # ------------------------------------------------------------------------------ func add_script(script): - if(!Engine.is_editor_hint()): + if !Engine.is_editor_hint(): _test_collector.set_test_class_prefix(_inner_class_prefix) _test_collector.add_script(script) @@ -1135,23 +1229,26 @@ func add_script(script): # with the suffix. Does not look in sub directories. Can be called multiple # times. # ------------------------------------------------------------------------------ -func add_directory(path, prefix=_file_prefix, suffix=".gd"): +func add_directory(path, prefix = _file_prefix, suffix = ".gd"): # check for '' b/c the calls to addin the exported directories 1-6 will pass # '' if the field has not been populated. This will cause res:// to be # processed which will include all files if include_subdirectories is true. - if(path == '' or path == null): + if path == "" or path == null: return var dir = DirAccess.open(path) - if(dir == null): - _lgr.error(str('The path [', path, '] does not exist.')) + if dir == null: + _lgr.error(str("The path [", path, "] does not exist.")) # !4.0 exit code does not exist anymore # OS.exit_code = 1 else: var files = _get_files(path, prefix, suffix) for i in range(files.size()): - if(_script_name == null or _script_name == '' or \ - (_script_name != null and files[i].findn(_script_name) != -1)): + if ( + _script_name == null + or _script_name == "" + or (_script_name != null and files[i].findn(_script_name) != -1) + ): add_script(files[i]) @@ -1170,25 +1267,25 @@ func select_script(script_name): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func export_tests(path=_export_path): - if(path == null): - _lgr.error('You must pass a path or set the export_path before calling export_tests') +func export_tests(path = _export_path): + if path == null: + _lgr.error("You must pass a path or set the export_path before calling export_tests") else: var result = _test_collector.export_tests(path) - if(result): + if result: _lgr.info(_test_collector.to_s()) _lgr.info("Exported to " + path) # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func import_tests(path=_export_path): - if(!_utils.file_exists(path)): - _lgr.error(str('Cannot import tests: the path [', path, '] does not exist.')) +func import_tests(path = _export_path): + if !_utils.file_exists(path): + _lgr.error(str("Cannot import tests: the path [", path, "] does not exist.")) else: _test_collector.clear() var result = _test_collector.import_tests(path) - if(result): + if result: _lgr.info(_test_collector.to_s()) _lgr.info("Importd from " + path) @@ -1196,16 +1293,17 @@ func import_tests(path=_export_path): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func import_tests_if_none_found(): - if(!_cancel_import and _test_collector.scripts.size() == 0): + if !_cancel_import and _test_collector.scripts.size() == 0: import_tests() # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func export_if_tests_found(): - if(_test_collector.scripts.size() > 0): + if _test_collector.scripts.size() > 0: export_tests() + ################ # # MISC @@ -1216,14 +1314,14 @@ func export_if_tests_found(): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func maximize(): - _lgr.deprecated('gut.maximize') + _lgr.deprecated("gut.maximize") # ------------------------------------------------------------------------------ # Clears the text of the text box. This resets all counters. # ------------------------------------------------------------------------------ func clear_text(): - _lgr.deprecated('gut.clear_text') + _lgr.deprecated("gut.clear_text") # ------------------------------------------------------------------------------ @@ -1232,6 +1330,7 @@ func clear_text(): func get_test_count(): return _new_summary.get_totals().tests + # ------------------------------------------------------------------------------ # Get the number of assertions that were made # ------------------------------------------------------------------------------ @@ -1239,18 +1338,21 @@ func get_assert_count(): var t = _new_summary.get_totals() return t.passing + t.failing + # ------------------------------------------------------------------------------ # Get the number of assertions that passed # ------------------------------------------------------------------------------ func get_pass_count(): return _new_summary.get_totals().passing + # ------------------------------------------------------------------------------ # Get the number of assertions that failed # ------------------------------------------------------------------------------ func get_fail_count(): return _new_summary.get_totals().failing + # ------------------------------------------------------------------------------ # Get the number of tests flagged as pending # ------------------------------------------------------------------------------ @@ -1263,34 +1365,36 @@ func get_pending_count(): # anything that you have rendered to the screen. # ------------------------------------------------------------------------------ func pause_before_teardown(): - _pause_before_teardown = true; + _pause_before_teardown = true # ------------------------------------------------------------------------------ # Uses the awaiter to wait for x amount of time. The signal emitted when the # time has expired is returned (_awaiter.timeout). # ------------------------------------------------------------------------------ -func set_wait_time(time, text=''): +func set_wait_time(time, text = ""): _awaiter.wait_for(time) - _lgr.yield_msg(str('-- Awaiting ', time, ' second(s) -- ', text)) + _lgr.yield_msg(str("-- Awaiting ", time, " second(s) -- ", text)) return _awaiter.timeout # ------------------------------------------------------------------------------ # Uses the awaiter to wait for x frames. The signal emitted is returned. # ------------------------------------------------------------------------------ -func set_wait_frames(frames, text=''): +func set_wait_frames(frames, text = ""): _awaiter.wait_frames(frames) - _lgr.yield_msg(str('-- Awaiting ', frames, ' frame(s) -- ', text)) + _lgr.yield_msg(str("-- Awaiting ", frames, " frame(s) -- ", text)) return _awaiter.timeout # ------------------------------------------------------------------------------ # Wait for a signal or a maximum amount of time. The signal emitted is returned. # ------------------------------------------------------------------------------ -func set_wait_for_signal_or_time(obj, signal_name, max_wait, text=''): +func set_wait_for_signal_or_time(obj, signal_name, max_wait, text = ""): _awaiter.wait_for_signal(Signal(obj, signal_name), max_wait) - _lgr.yield_msg(str('-- Awaiting signal "', signal_name, '" or for ', max_wait, ' second(s) -- ', text)) + _lgr.yield_msg( + str('-- Awaiting signal "', signal_name, '" or for ', max_wait, " second(s) -- ", text) + ) return _awaiter.timeout @@ -1299,7 +1403,7 @@ func set_wait_for_signal_or_time(obj, signal_name, max_wait, text=''): # ------------------------------------------------------------------------------ func get_current_script_object(): var to_return = null - if(_test_script_objects.size() > 0): + if _test_script_objects.size() > 0: to_return = _test_script_objects[-1] return to_return @@ -1315,18 +1419,20 @@ func get_current_test_object(): func get_summary(): return _new_summary + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func get_pre_run_script_instance(): return _pre_run_script_instance + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func get_post_run_script_instance(): return _post_run_script_instance + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func show_orphans(should): _lgr.set_type_enabled(_lgr.types.orphan, should) - diff --git a/addons/gut/gut_cmdln.gd b/addons/gut/gut_cmdln.gd index 38f20fe..fcd615c 100644 --- a/addons/gut/gut_cmdln.gd +++ b/addons/gut/gut_cmdln.gd @@ -39,12 +39,13 @@ # ############################################################################## extends SceneTree -var Optparse = load('res://addons/gut/optparse.gd') -var Gut = load('res://addons/gut/gut.gd') -var GutRunner = load('res://addons/gut/gui/GutRunner.tscn') +var Optparse = load("res://addons/gut/optparse.gd") +var Gut = load("res://addons/gut/gut.gd") +var GutRunner = load("res://addons/gut/gui/GutRunner.tscn") var json = JSON.new() + # ------------------------------------------------------------------------------ # Helper class to resolve the various different places where an option can # be set. Using the get_value method will enforce the order of precedence of: @@ -61,7 +62,6 @@ class OptionResolver: var cmd_opts = {} var config_opts = {} - func get_value(key): return _nvl(cmd_opts[key], _nvl(config_opts[key], base_opts[key])) @@ -78,21 +78,31 @@ class OptionResolver: return new_hash func _nvl(a, b): - if(a == null): + if a == null: return b else: return a + func _string_it(h): - var to_return = '' + var to_return = "" for key in h: - to_return += str('(',key, ':', _nvl(h[key], 'NULL'), ')') + to_return += str("(", key, ":", _nvl(h[key], "NULL"), ")") return to_return func to_s(): - return str("base:\n", _string_it(base_opts), "\n", \ - "config:\n", _string_it(config_opts), "\n", \ - "cmd:\n", _string_it(cmd_opts), "\n", \ - "resolved:\n", _string_it(get_resolved_values())) + return str( + "base:\n", + _string_it(base_opts), + "\n", + "config:\n", + _string_it(config_opts), + "\n", + "cmd:\n", + _string_it(cmd_opts), + "\n", + "resolved:\n", + _string_it(get_resolved_values()) + ) func get_resolved_values(): var to_return = {} @@ -101,23 +111,24 @@ class OptionResolver: return to_return func to_s_verbose(): - var to_return = '' + var to_return = "" var resolved = get_resolved_values() for key in base_opts: to_return += str(key, "\n") - to_return += str(' default: ', _nvl(base_opts[key], 'NULL'), "\n") - to_return += str(' config: ', _nvl(config_opts[key], ' --'), "\n") - to_return += str(' cmd: ', _nvl(cmd_opts[key], ' --'), "\n") - to_return += str(' final: ', _nvl(resolved[key], 'NULL'), "\n") + to_return += str(" default: ", _nvl(base_opts[key], "NULL"), "\n") + to_return += str(" config: ", _nvl(config_opts[key], " --"), "\n") + to_return += str(" cmd: ", _nvl(cmd_opts[key], " --"), "\n") + to_return += str(" final: ", _nvl(resolved[key], "NULL"), "\n") return to_return + # ------------------------------------------------------------------------------ # Here starts the actual script that uses the Options class to kick off Gut # and run your tests. # ------------------------------------------------------------------------------ -var _utils = load('res://addons/gut/utils.gd').get_instance() -var _gut_config = load('res://addons/gut/gut_config.gd').new() +var _utils = load("res://addons/gut/utils.gd").get_instance() +var _gut_config = load("res://addons/gut/gut_config.gd").new() # instance of gut var _tester = null # array of command line options specified @@ -126,87 +137,156 @@ var _final_opts = [] func setup_options(options, font_names): var opts = Optparse.new() - opts.set_banner(('This is the command line interface for the unit testing tool Gut. With this ' + - 'interface you can run one or more test scripts from the command line. In order ' + - 'for the Gut options to not clash with any other godot options, each option starts ' + - 'with a "g". Also, any option that requires a value will take the form of ' + - '"-g=". There cannot be any spaces between the option, the "=", or ' + - 'inside a specified value or godot will think you are trying to run a scene.')) + opts.set_banner( + ( + "This is the command line interface for the unit testing tool Gut. With this " + + "interface you can run one or more test scripts from the command line. In order " + + "for the Gut options to not clash with any other godot options, each option starts " + + 'with a "g". Also, any option that requires a value will take the form of ' + + '"-g=". There cannot be any spaces between the option, the "=", or ' + + "inside a specified value or godot will think you are trying to run a scene." + ) + ) - opts.add('-gtest', [], 'Comma delimited list of full paths to test scripts to run.') - opts.add('-gdir', options.dirs, 'Comma delimited list of directories to add tests from.') - opts.add('-gprefix', options.prefix, 'Prefix used to find tests when specifying -gdir. Default "[default]".') - opts.add('-gsuffix', options.suffix, 'Test script suffix, including .gd extension. Default "[default]".') - opts.add('-ghide_orphans', false, 'Display orphan counts for tests and scripts. Default "[default]".') - opts.add('-gmaximize', false, 'Maximizes test runner window to fit the viewport.') - opts.add('-gcompact_mode', false, 'The runner will be in compact mode. This overrides -gmaximize.') - opts.add('-gexit', false, 'Exit after running tests. If not specified you have to manually close the window.') - opts.add('-gexit_on_success', false, 'Only exit if all tests pass.') - opts.add('-glog', options.log_level, 'Log level. Default [default]') - opts.add('-gignore_pause', false, 'Ignores any calls to gut.pause_before_teardown.') - opts.add('-gselect', '', ('Select a script to run initially. The first script that ' + - 'was loaded using -gtest or -gdir that contains the specified ' + - 'string will be executed. You may run others by interacting ' + - 'with the GUI.')) - opts.add('-gunit_test_name', '', ('Name of a test to run. Any test that contains the specified ' + - 'text will be run, all others will be skipped.')) - opts.add('-gh', false, 'Print this help, then quit') - opts.add('-gconfig', 'res://.gutconfig.json', 'A config file that contains configuration information. Default is res://.gutconfig.json') - opts.add('-ginner_class', '', 'Only run inner classes that contain this string') - opts.add('-gopacity', options.opacity, 'Set opacity of test runner window. Use range 0 - 100. 0 = transparent, 100 = opaque.') - opts.add('-gpo', false, 'Print option values from all sources and the value used, then quit.') - opts.add('-ginclude_subdirs', false, 'Include subdirectories of -gdir.') - opts.add('-gdouble_strategy', 'partial', 'Default strategy to use when doubling. Valid values are [partial, full]. Default "[default]"') - opts.add('-gdisable_colors', false, 'Disable command line colors.') - opts.add('-gpre_run_script', '', 'pre-run hook script path') - opts.add('-gpost_run_script', '', 'post-run hook script path') - opts.add('-gprint_gutconfig_sample', false, 'Print out json that can be used to make a gutconfig file then quit.') + opts.add("-gtest", [], "Comma delimited list of full paths to test scripts to run.") + opts.add("-gdir", options.dirs, "Comma delimited list of directories to add tests from.") + opts.add( + "-gprefix", + options.prefix, + 'Prefix used to find tests when specifying -gdir. Default "[default]".' + ) + opts.add( + "-gsuffix", + options.suffix, + 'Test script suffix, including .gd extension. Default "[default]".' + ) + opts.add( + "-ghide_orphans", + false, + 'Display orphan counts for tests and scripts. Default "[default]".' + ) + opts.add("-gmaximize", false, "Maximizes test runner window to fit the viewport.") + opts.add( + "-gcompact_mode", false, "The runner will be in compact mode. This overrides -gmaximize." + ) + opts.add( + "-gexit", + false, + "Exit after running tests. If not specified you have to manually close the window." + ) + opts.add("-gexit_on_success", false, "Only exit if all tests pass.") + opts.add("-glog", options.log_level, "Log level. Default [default]") + opts.add("-gignore_pause", false, "Ignores any calls to gut.pause_before_teardown.") + opts.add( + "-gselect", + "", + ( + "Select a script to run initially. The first script that " + + "was loaded using -gtest or -gdir that contains the specified " + + "string will be executed. You may run others by interacting " + + "with the GUI." + ) + ) + opts.add( + "-gunit_test_name", + "", + ( + "Name of a test to run. Any test that contains the specified " + + "text will be run, all others will be skipped." + ) + ) + opts.add("-gh", false, "Print this help, then quit") + opts.add( + "-gconfig", + "res://.gutconfig.json", + "A config file that contains configuration information. Default is res://.gutconfig.json" + ) + opts.add("-ginner_class", "", "Only run inner classes that contain this string") + opts.add( + "-gopacity", + options.opacity, + "Set opacity of test runner window. Use range 0 - 100. 0 = transparent, 100 = opaque." + ) + opts.add("-gpo", false, "Print option values from all sources and the value used, then quit.") + opts.add("-ginclude_subdirs", false, "Include subdirectories of -gdir.") + opts.add( + "-gdouble_strategy", + "partial", + 'Default strategy to use when doubling. Valid values are [partial, full]. Default "[default]"' + ) + opts.add("-gdisable_colors", false, "Disable command line colors.") + opts.add("-gpre_run_script", "", "pre-run hook script path") + opts.add("-gpost_run_script", "", "post-run hook script path") + opts.add( + "-gprint_gutconfig_sample", + false, + "Print out json that can be used to make a gutconfig file then quit." + ) - opts.add('-gfont_name', options.font_name, str('Valid values are: ', font_names, '. Default "[default]"')) - opts.add('-gfont_size', options.font_size, 'Font size, default "[default]"') - opts.add('-gbackground_color', options.background_color, 'Background color as an html color, default "[default]"') - opts.add('-gfont_color',options.font_color, 'Font color as an html color, default "[default]"') - opts.add('-gpaint_after', options.paint_after, 'Delay before GUT will add a 1 frame pause to paint the screen/GUI. default [default]') + opts.add( + "-gfont_name", + options.font_name, + str("Valid values are: ", font_names, '. Default "[default]"') + ) + opts.add("-gfont_size", options.font_size, 'Font size, default "[default]"') + opts.add( + "-gbackground_color", + options.background_color, + 'Background color as an html color, default "[default]"' + ) + opts.add("-gfont_color", options.font_color, 'Font color as an html color, default "[default]"') + opts.add( + "-gpaint_after", + options.paint_after, + "Delay before GUT will add a 1 frame pause to paint the screen/GUI. default [default]" + ) - opts.add('-gjunit_xml_file', options.junit_xml_file, 'Export results of run to this file in the Junit XML format.') - opts.add('-gjunit_xml_timestamp', options.junit_xml_timestamp, 'Include a timestamp in the -gjunit_xml_file, default [default]') + opts.add( + "-gjunit_xml_file", + options.junit_xml_file, + "Export results of run to this file in the Junit XML format." + ) + opts.add( + "-gjunit_xml_timestamp", + options.junit_xml_timestamp, + "Include a timestamp in the -gjunit_xml_file, default [default]" + ) return opts # Parses options, applying them to the _tester or setting values # in the options struct. func extract_command_line_options(from, to): - to.config_file = from.get_value('-gconfig') - to.dirs = from.get_value('-gdir') - to.disable_colors = from.get_value('-gdisable_colors') - to.double_strategy = from.get_value('-gdouble_strategy') - to.ignore_pause = from.get_value('-gignore_pause') - to.include_subdirs = from.get_value('-ginclude_subdirs') - to.inner_class = from.get_value('-ginner_class') - to.log_level = from.get_value('-glog') - to.opacity = from.get_value('-gopacity') - to.post_run_script = from.get_value('-gpost_run_script') - to.pre_run_script = from.get_value('-gpre_run_script') - to.prefix = from.get_value('-gprefix') - to.selected = from.get_value('-gselect') - to.should_exit = from.get_value('-gexit') - to.should_exit_on_success = from.get_value('-gexit_on_success') - to.should_maximize = from.get_value('-gmaximize') - to.compact_mode = from.get_value('-gcompact_mode') - to.hide_orphans = from.get_value('-ghide_orphans') - to.suffix = from.get_value('-gsuffix') - to.tests = from.get_value('-gtest') - to.unit_test_name = from.get_value('-gunit_test_name') + to.config_file = from.get_value("-gconfig") + to.dirs = from.get_value("-gdir") + to.disable_colors = from.get_value("-gdisable_colors") + to.double_strategy = from.get_value("-gdouble_strategy") + to.ignore_pause = from.get_value("-gignore_pause") + to.include_subdirs = from.get_value("-ginclude_subdirs") + to.inner_class = from.get_value("-ginner_class") + to.log_level = from.get_value("-glog") + to.opacity = from.get_value("-gopacity") + to.post_run_script = from.get_value("-gpost_run_script") + to.pre_run_script = from.get_value("-gpre_run_script") + to.prefix = from.get_value("-gprefix") + to.selected = from.get_value("-gselect") + to.should_exit = from.get_value("-gexit") + to.should_exit_on_success = from.get_value("-gexit_on_success") + to.should_maximize = from.get_value("-gmaximize") + to.compact_mode = from.get_value("-gcompact_mode") + to.hide_orphans = from.get_value("-ghide_orphans") + to.suffix = from.get_value("-gsuffix") + to.tests = from.get_value("-gtest") + to.unit_test_name = from.get_value("-gunit_test_name") - to.font_size = from.get_value('-gfont_size') - to.font_name = from.get_value('-gfont_name') - to.background_color = from.get_value('-gbackground_color') - to.font_color = from.get_value('-gfont_color') - to.paint_after = from.get_value('-gpaint_after') - - to.junit_xml_file = from.get_value('-gjunit_xml_file') - to.junit_xml_timestamp = from.get_value('-gjunit_xml_timestamp') + to.font_size = from.get_value("-gfont_size") + to.font_name = from.get_value("-gfont_name") + to.background_color = from.get_value("-gbackground_color") + to.font_color = from.get_value("-gfont_color") + to.paint_after = from.get_value("-gpaint_after") + to.junit_xml_file = from.get_value("-gjunit_xml_file") + to.junit_xml_timestamp = from.get_value("-gjunit_xml_timestamp") func _print_gutconfigs(values): @@ -214,21 +294,23 @@ func _print_gutconfigs(values): You do not need to specify all values in your own file. The values supplied in this sample are what would be used if you ran gut w/o the -gprint_gutconfig_sample option (option priority: command-line, super.gutconfig, default).""" - print("\n", header.replace("\n", ' '), "\n\n") + print("\n", header.replace("\n", " "), "\n\n") var resolved = values # remove_at some options that don't make sense to be in config resolved.erase("config_file") resolved.erase("show_help") - print("Here's a config with all the properties set based off of your current command and config.") - print(json.stringify(resolved, ' ')) + print( + "Here's a config with all the properties set based off of your current command and config." + ) + print(json.stringify(resolved, " ")) for key in resolved: resolved[key] = null print("\n\nAnd here's an empty config for you fill in what you want.") - print(json.stringify(resolved, ' ')) + print(json.stringify(resolved, " ")) # parse options and run Gut @@ -236,36 +318,40 @@ func _run_gut(): var opt_resolver = OptionResolver.new() opt_resolver.set_base_opts(_gut_config.default_options) - print("\n\n", ' --- Gut ---') + print("\n\n", " --- Gut ---") var o = setup_options(_gut_config.default_options, _gut_config.valid_fonts) var all_options_valid = o.parse() extract_command_line_options(o, opt_resolver.cmd_opts) - var load_result = _gut_config.load_options_no_defaults( - opt_resolver.get_value('config_file')) + var load_result = _gut_config.load_options_no_defaults(opt_resolver.get_value("config_file")) # SHORTCIRCUIT - if(!all_options_valid or load_result == -1): + if !all_options_valid or load_result == -1: quit(1) else: opt_resolver.config_opts = _gut_config.options - if(o.get_value('-gh')): + if o.get_value("-gh"): print(_utils.get_version_text()) o.print_help() quit() - elif(o.get_value('-gpo')): - print('All command line options and where they are specified. ' + - 'The "final" value shows which value will actually be used ' + - 'based on order of precedence (default < super.gutconfig < cmd line).' + "\n") + elif o.get_value("-gpo"): + print( + ( + "All command line options and where they are specified. " + + 'The "final" value shows which value will actually be used ' + + "based on order of precedence (default < super.gutconfig < cmd line)." + + "\n" + ) + ) print(opt_resolver.to_s_verbose()) quit() - elif(o.get_value('-gprint_gutconfig_sample')): + elif o.get_value("-gprint_gutconfig_sample"): _print_gutconfigs(opt_resolver.get_resolved_values()) quit() else: - _final_opts = opt_resolver.get_resolved_values(); + _final_opts = opt_resolver.get_resolved_values() _gut_config.options = _final_opts var runner = GutRunner.instantiate() @@ -275,31 +361,40 @@ func _run_gut(): get_root().add_child(runner) _tester = runner.get_gut() - _tester.connect('end_run', Callable(self,'_on_tests_finished').bind(_final_opts.should_exit, _final_opts.should_exit_on_success)) + _tester.connect( + "end_run", + ( + Callable(self, "_on_tests_finished") + . bind(_final_opts.should_exit, _final_opts.should_exit_on_success) + ) + ) runner.run_tests() # exit if option is set. func _on_tests_finished(should_exit, should_exit_on_success): - if(_final_opts.dirs.size() == 0): - if(_tester.get_summary().get_totals().scripts == 0): + if _final_opts.dirs.size() == 0: + if _tester.get_summary().get_totals().scripts == 0: var lgr = _tester.get_logger() - lgr.error('No directories configured. Add directories with options or a super.gutconfig.json file. Use the -gh option for more information.') + lgr.error( + "No directories configured. Add directories with options or a super.gutconfig.json file. Use the -gh option for more information." + ) - if(_tester.get_fail_count()): + if _tester.get_fail_count(): set_exit_code(1) # Overwrite the exit code with the post_script var post_inst = _tester.get_post_run_script_instance() - if(post_inst != null and post_inst.get_exit_code() != null): + if post_inst != null and post_inst.get_exit_code() != null: set_exit_code(post_inst.get_exit_code()) - if(should_exit or (should_exit_on_success and _tester.get_fail_count() == 0)): + if should_exit or (should_exit_on_success and _tester.get_fail_count() == 0): quit() else: print("Tests finished, exit manually") + func set_exit_code(val): pass # OS.exit_code doesn't exist anymore, but when we find a solution it just @@ -310,7 +405,7 @@ func set_exit_code(val): # MAIN # ------------------------------------------------------------------------------ func _init(): - if(!_utils.is_version_ok()): + if !_utils.is_version_ok(): print("\n\n", _utils.get_version_text()) push_error(_utils.get_bad_version_text()) set_exit_code(1) diff --git a/addons/gut/gut_config.gd b/addons/gut/gut_config.gd index 13b9c58..3a121b1 100644 --- a/addons/gut/gut_config.gd +++ b/addons/gut/gut_config.gd @@ -1,51 +1,46 @@ -var Gut = load('res://addons/gut/gut.gd') +var Gut = load("res://addons/gut/gut.gd") # Do not want a ref to _utils here due to use by editor plugin. # _utils needs to be split so that constants and what not do not # have to rely on the weird singleton thing I made. -enum DOUBLE_STRATEGY{ - FULL, - PARTIAL -} +enum DOUBLE_STRATEGY { FULL, PARTIAL } - -var valid_fonts = ['AnonymousPro', 'CourierPro', 'LobsterTwo', 'Default'] +var valid_fonts = ["AnonymousPro", "CourierPro", "LobsterTwo", "Default"] var default_options = { background_color = Color(.15, .15, .15, 1).to_html(), - config_file = 'res://.gutconfig.json', + config_file = "res://.gutconfig.json", dirs = [], disable_colors = false, - double_strategy = 'partial', + double_strategy = "partial", font_color = Color(.8, .8, .8, 1).to_html(), - font_name = 'CourierPrime', + font_name = "CourierPrime", font_size = 16, hide_orphans = false, ignore_pause = false, include_subdirs = false, - inner_class = '', - junit_xml_file = '', + inner_class = "", + junit_xml_file = "", junit_xml_timestamp = false, log_level = 1, opacity = 100, paint_after = .1, - post_run_script = '', - pre_run_script = '', - prefix = 'test_', - selected = '', + post_run_script = "", + pre_run_script = "", + prefix = "test_", + selected = "", should_exit = false, should_exit_on_success = false, should_maximize = false, compact_mode = false, show_help = false, - suffix = '.gd', + suffix = ".gd", tests = [], - unit_test_name = '', - + unit_test_name = "", gut_on_top = true, } var default_panel_options = { - font_name = 'CourierPrime', + font_name = "CourierPrime", font_size = 30, hide_result_tree = false, hide_output_text = false, @@ -67,30 +62,30 @@ func _null_copy(h): func _load_options_from_config_file(file_path, into): # SHORTCIRCUIT - if(!FileAccess.file_exists(file_path)): - if(file_path != 'res://.gutconfig.json'): + if !FileAccess.file_exists(file_path): + if file_path != "res://.gutconfig.json": print('ERROR: Config File "', file_path, '" does not exist.') return -1 else: return 1 var f = FileAccess.open(file_path, FileAccess.READ) - if(f == null): + if f == null: var result = FileAccess.get_open_error() - push_error(str("Could not load data ", file_path, ' ', result)) + push_error(str("Could not load data ", file_path, " ", result)) return result var json = f.get_as_text() - f = null # close file + f = null # close file var test_json_conv = JSON.new() test_json_conv.parse(json) var results = test_json_conv.get_data() # SHORTCIRCUIT - if(results == null): - print("\n\n",'!! ERROR parsing file: ', file_path) - print(' at line ', results.error_line, ':') - print(' ', results.error_string) + if results == null: + print("\n\n", "!! ERROR parsing file: ", file_path) + print(" at line ", results.error_line, ":") + print(" ", results.error_string) return -1 # Get all the options out of the config file using the option name. The @@ -99,28 +94,27 @@ func _load_options_from_config_file(file_path, into): return 1 + func _load_dict_into(source, dest): for key in dest: - if(source.has(key)): - if(source[key] != null): - if(typeof(source[key]) == TYPE_DICTIONARY): + if source.has(key): + if source[key] != null: + if typeof(source[key]) == TYPE_DICTIONARY: _load_dict_into(source[key], dest[key]) else: dest[key] = source[key] - - func write_options(path): - var content = json.stringify(options, ' ') + var content = json.stringify(options, " ") var f = FileAccess.open(path, FileAccess.WRITE) var result = FileAccess.get_open_error() - if(f != null): + if f != null: f.store_string(content) f.close() else: - print('ERROR: could not open file ', path, ' ', result) + print("ERROR: could not open file ", path, " ", result) return result @@ -129,12 +123,12 @@ func write_options(path): func _apply_options(opts, _tester): _tester.include_subdirectories = opts.include_subdirs - if(opts.inner_class != ''): + if opts.inner_class != "": _tester.inner_class_name = opts.inner_class _tester.log_level = opts.log_level _tester.ignore_pause_before_teardown = opts.ignore_pause - if(opts.selected != ''): + if opts.selected != "": _tester.select_script(opts.selected) for i in range(opts.dirs.size()): @@ -143,9 +137,9 @@ func _apply_options(opts, _tester): for i in range(opts.tests.size()): _tester.add_script(opts.tests[i]) - if(opts.double_strategy == 'include super'): + if opts.double_strategy == "include super": _tester.double_strategy = DOUBLE_STRATEGY.FULL - elif(opts.double_strategy == 'script only'): + elif opts.double_strategy == "script only": _tester.double_strategy = DOUBLE_STRATEGY.PARTIAL _tester.unit_test_name = opts.unit_test_name @@ -167,13 +161,16 @@ func config_gut(gut): func load_options(path): return _load_options_from_config_file(path, options) + func load_panel_options(path): - options['panel_options'] = default_panel_options.duplicate() + options["panel_options"] = default_panel_options.duplicate() return _load_options_from_config_file(path, options) + func load_options_no_defaults(path): options = _null_copy(default_options) return _load_options_from_config_file(path, options) + func apply_options(gut): _apply_options(options, gut) diff --git a/addons/gut/gut_plugin.gd b/addons/gut/gut_plugin.gd index 40e8d51..c04f910 100644 --- a/addons/gut/gut_plugin.gd +++ b/addons/gut/gut_plugin.gd @@ -5,9 +5,9 @@ var _bottom_panel = null func _enter_tree(): - _bottom_panel = preload('res://addons/gut/gui/GutBottomPanel.tscn').instantiate() + _bottom_panel = preload("res://addons/gut/gui/GutBottomPanel.tscn").instantiate() - var button = add_control_to_bottom_panel(_bottom_panel, 'GUT') + var button = add_control_to_bottom_panel(_bottom_panel, "GUT") button.shortcut_in_tooltip = true await get_tree().create_timer(3).timeout diff --git a/addons/gut/gut_to_move.gd b/addons/gut/gut_to_move.gd index 4841681..0102584 100644 --- a/addons/gut/gut_to_move.gd +++ b/addons/gut/gut_to_move.gd @@ -1,7 +1,8 @@ # Temporary base script for gut.gd to hold the things to be remvoed and added # to some utility somewhere. extends Node -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() + # ------------------------------------------------------------------------------ # deletes all files in a given directory @@ -10,32 +11,34 @@ func directory_delete_files(path): var d = DirAccess.open(path) # SHORTCIRCUIT - if(d == null): + if d == null: return # Traversing a directory is kinda odd. You have to start the process of listing # the contents of a directory with list_dir_begin then use get_next until it # returns an empty string. Then I guess you should end it. - d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547 - var thing = d.get_next() # could be a dir or a file or something else maybe? - var full_path = '' - while(thing != ''): + d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547 + var thing = d.get_next() # could be a dir or a file or something else maybe? + var full_path = "" + while thing != "": full_path = path + "/" + thing #file_exists returns fasle for directories - if(d.file_exists(full_path)): + if d.file_exists(full_path): d.remove(full_path) thing = d.get_next() d.list_dir_end() + # ------------------------------------------------------------------------------ # deletes the file at the specified path # ------------------------------------------------------------------------------ func file_delete(path): var d = DirAccess.open(path.get_base_dir()) - if(d != null): + if d != null: d.remove(path) + # ------------------------------------------------------------------------------ # Checks to see if the passed in file has any data in it. # ------------------------------------------------------------------------------ @@ -43,22 +46,25 @@ func is_file_empty(path): var f = FileAccess.open(path, FileAccess.READ) var result = FileAccess.get_open_error() var empty = true - if(result == OK): + if result == OK: empty = f.get_length() == 0 f = null return empty + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func get_file_as_text(path): return _utils.get_file_as_text(path) + # ------------------------------------------------------------------------------ # Creates an empty file at the specified path # ------------------------------------------------------------------------------ func file_touch(path): FileAccess.open(path, FileAccess.WRITE) + # ------------------------------------------------------------------------------ # Call _process or _fixed_process, if they exist, on obj and all it's children # and their children and so and so forth. Delta will be passed through to all @@ -66,9 +72,9 @@ func file_touch(path): # ------------------------------------------------------------------------------ func simulate(obj, times, delta): for _i in range(times): - if(obj.has_method("_process")): + if obj.has_method("_process"): obj._process(delta) - if(obj.has_method("_physics_process")): + if obj.has_method("_physics_process"): obj._physics_process(delta) for kid in obj.get_children(): diff --git a/addons/gut/hook_script.gd b/addons/gut/hook_script.gd index 9597d0b..85fd6dc 100644 --- a/addons/gut/hook_script.gd +++ b/addons/gut/hook_script.gd @@ -5,37 +5,47 @@ class_name GutHookScript # # To use, inherit from this script and then implement the run method. # ------------------------------------------------------------------------------ -var JunitXmlExport = load('res://addons/gut/junit_xml_export.gd') +var JunitXmlExport = load("res://addons/gut/junit_xml_export.gd") # This is the instance of GUT that is running the tests. You can get # information about the run from this object. This is set by GUT when the # script is instantiated. -var gut = null +var gut = null # the exit code to be used by gut_cmdln. See set method. var _exit_code = null -var _should_abort = false +var _should_abort = false + # Virtual method that will be called by GUT after instantiating # this script. func run(): - gut.logger.error("Run method not overloaded. Create a 'run()' method in your hook script to run your code.") + ( + gut + . logger + . error( + "Run method not overloaded. Create a 'run()' method in your hook script to run your code." + ) + ) # Set the exit code when running from the command line. If not set then the # default exit code will be returned (0 when no tests fail, 1 when any tests # fail). func set_exit_code(code): - _exit_code = code + _exit_code = code + func get_exit_code(): return _exit_code + # Usable by pre-run script to cause the run to end AFTER the run() method # finishes. post-run script will not be ran. func abort(): _should_abort = true + func should_abort(): return _should_abort diff --git a/addons/gut/inner_class_registry.gd b/addons/gut/inner_class_registry.gd index 9262bbb..bdfe958 100644 --- a/addons/gut/inner_class_registry.gd +++ b/addons/gut/inner_class_registry.gd @@ -3,23 +3,24 @@ var _registry = {} func _create_reg_entry(base_path, subpath): var to_return = { - "base_path":base_path, - "subpath":subpath, - "base_resource":load(base_path), - "full_path":str("'", base_path, "'", subpath) + "base_path": base_path, + "subpath": subpath, + "base_resource": load(base_path), + "full_path": str("'", base_path, "'", subpath) } return to_return -func _register_inners(base_path, obj, prev_inner = ''): + +func _register_inners(base_path, obj, prev_inner = ""): var const_map = obj.get_script_constant_map() var consts = const_map.keys() var const_idx = 0 - while(const_idx < consts.size()): + while const_idx < consts.size(): var key = consts[const_idx] var thing = const_map[key] - if(typeof(thing) == TYPE_OBJECT): + if typeof(thing) == TYPE_OBJECT: var cur_inner = str(prev_inner, ".", key) _registry[thing] = _create_reg_entry(base_path, cur_inner) _register_inners(base_path, thing, cur_inner) @@ -33,21 +34,23 @@ func register(base_script): func get_extends_path(inner_class): - if(_registry.has(inner_class)): + if _registry.has(inner_class): return _registry[inner_class].full_path else: return null + # returns the subpath for the inner class. This includes the leading "." in # the path. func get_subpath(inner_class): - if(_registry.has(inner_class)): + if _registry.has(inner_class): return _registry[inner_class].subpath else: - return '' + return "" + func get_base_path(inner_class): - if(_registry.has(inner_class)): + if _registry.has(inner_class): return _registry[inner_class].base_path @@ -56,7 +59,7 @@ func has(inner_class): func get_base_resource(inner_class): - if(_registry.has(inner_class)): + if _registry.has(inner_class): return _registry[inner_class].base_resource diff --git a/addons/gut/input_factory.gd b/addons/gut/input_factory.gd index 46744e5..075a4a6 100644 --- a/addons/gut/input_factory.gd +++ b/addons/gut/input_factory.gd @@ -30,7 +30,6 @@ # ----------- # ############################################################################## - # Implemented InputEvent* convenience methods # InputEventAction # InputEventKey @@ -46,10 +45,9 @@ # InputEventScreenDrag # InputEventScreenTouch - static func _to_scancode(which): var key_code = which - if(typeof(key_code) == TYPE_STRING): + if typeof(key_code) == TYPE_STRING: key_code = key_code.to_upper().to_ascii_buffer()[0] return key_code @@ -57,7 +55,7 @@ static func _to_scancode(which): static func new_mouse_button_event(position, global_position, pressed, button_index): var event = InputEventMouseButton.new() event.position = position - if(global_position != null): + if global_position != null: event.global_position = global_position event.pressed = pressed event.button_index = button_index @@ -79,58 +77,58 @@ static func key_down(which): return event -static func action_up(which, strength=1.0): - var event = InputEventAction.new() +static func action_up(which, strength = 1.0): + var event = InputEventAction.new() event.action = which event.strength = strength return event -static func action_down(which, strength=1.0): - var event = InputEventAction.new() +static func action_down(which, strength = 1.0): + var event = InputEventAction.new() event.action = which event.strength = strength event.pressed = true return event -static func mouse_left_button_down(position, global_position=null): +static func mouse_left_button_down(position, global_position = null): var event = new_mouse_button_event(position, global_position, true, MOUSE_BUTTON_LEFT) return event -static func mouse_left_button_up(position, global_position=null): +static func mouse_left_button_up(position, global_position = null): var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_LEFT) return event -static func mouse_double_click(position, global_position=null): +static func mouse_double_click(position, global_position = null): var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_LEFT) event.double_click = true return event -static func mouse_right_button_down(position, global_position=null): +static func mouse_right_button_down(position, global_position = null): var event = new_mouse_button_event(position, global_position, true, MOUSE_BUTTON_RIGHT) return event -static func mouse_right_button_up(position, global_position=null): +static func mouse_right_button_up(position, global_position = null): var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_RIGHT) return event -static func mouse_motion(position, global_position=null): +static func mouse_motion(position, global_position = null): var event = InputEventMouseMotion.new() event.position = position - if(global_position != null): + if global_position != null: event.global_position = global_position return event -static func mouse_relative_motion(offset, last_motion_event=null, speed=Vector2(0, 0)): +static func mouse_relative_motion(offset, last_motion_event = null, speed = Vector2(0, 0)): var event = null - if(last_motion_event == null): + if last_motion_event == null: event = mouse_motion(offset) event.velocity = speed else: diff --git a/addons/gut/input_sender.gd b/addons/gut/input_sender.gd index 0f0046f..9c3c4da 100644 --- a/addons/gut/input_sender.gd +++ b/addons/gut/input_sender.gd @@ -66,12 +66,12 @@ class InputQueueItem: # TODO should this be done in _physics_process instead or should it be # configurable? func _physics_process(delta): - if(frame_delay > 0 and _delay_started): + if frame_delay > 0 and _delay_started: _waited_frames += 1 - if(_waited_frames >= frame_delay): + if _waited_frames >= frame_delay: emit_signal("event_ready") - func _init(t_delay,f_delay): + func _init(t_delay, f_delay): time_delay = t_delay frame_delay = f_delay _is_ready = time_delay == 0 and frame_delay == 0 @@ -88,18 +88,18 @@ class InputQueueItem: func start(): _delay_started = true - if(time_delay > 0): + if time_delay > 0: var t = _delay_timer(time_delay) - t.connect("timeout",Callable(self,"_on_time_timeout")) + t.connect("timeout", Callable(self, "_on_time_timeout")) # ############################################################################## # # ############################################################################## -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var InputFactory = load("res://addons/gut/input_factory.gd") -const INPUT_WARN = 'If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use hold_for(...) to automatically release after some duration.' +const INPUT_WARN = "If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use hold_for(...) to automatically release after some duration." var _lgr = _utils.get_logger() var _receivers = [] @@ -122,44 +122,65 @@ var _auto_flush_input = false signal idle -func _init(r=null): - if(r != null): +func _init(r = null): + if r != null: add_receiver(r) func _send_event(event): - if(event is InputEventKey): - if((event.pressed and !event.echo) and is_key_pressed(event.keycode)): - _lgr.warn(str("InputSender: key_down called for ", event.as_text(), " when that key is already pressed. ", INPUT_WARN)) + if event is InputEventKey: + if (event.pressed and !event.echo) and is_key_pressed(event.keycode): + _lgr.warn( + str( + "InputSender: key_down called for ", + event.as_text(), + " when that key is already pressed. ", + INPUT_WARN + ) + ) _pressed_keys[event.keycode] = event.pressed - elif(event is InputEventAction): - if(event.pressed and is_action_pressed(event.action)): - _lgr.warn(str("InputSender: action_down called for ", event.action, " when that action is already pressed. ", INPUT_WARN)) + elif event is InputEventAction: + if event.pressed and is_action_pressed(event.action): + _lgr.warn( + str( + "InputSender: action_down called for ", + event.action, + " when that action is already pressed. ", + INPUT_WARN + ) + ) _pressed_actions[event.action] = event.pressed - elif(event is InputEventMouseButton): - if(event.pressed and is_mouse_button_pressed(event.button_index)): - _lgr.warn(str("InputSender: mouse_button_down called for ", event.button_index, " when that mouse button is already pressed. ", INPUT_WARN)) + elif event is InputEventMouseButton: + if event.pressed and is_mouse_button_pressed(event.button_index): + _lgr.warn( + str( + "InputSender: mouse_button_down called for ", + event.button_index, + " when that mouse button is already pressed. ", + INPUT_WARN + ) + ) _pressed_mouse_buttons[event.button_index] = event for r in _receivers: - if(r == Input): + if r == Input: Input.parse_input_event(event) - if(_auto_flush_input): + if _auto_flush_input: Input.flush_buffered_events() else: - if(r.has_method("_input")): + if r.has_method("_input"): r._input(event) - if(r.has_method("_gui_input")): + if r.has_method("_gui_input"): r._gui_input(event) - if(r.has_method("_unhandled_input")): + if r.has_method("_unhandled_input"): r._unhandled_input(event) func _send_or_record_event(event): _last_event = event - if(_next_queue_item != null): + if _next_queue_item != null: _next_queue_item.events.append(event) else: _send_event(event) @@ -172,7 +193,7 @@ func _on_queue_item_ready(item): var done_event = _input_queue.pop_front() done_event.queue_free() - if(_input_queue.size() == 0): + if _input_queue.size() == 0: _next_queue_item = null emit_signal("idle") else: @@ -184,7 +205,7 @@ func _add_queue_item(item): _next_queue_item = item _input_queue.append(item) Engine.get_main_loop().root.add_child(item) - if(_input_queue.size() == 1): + if _input_queue.size() == 1: item.start() @@ -197,13 +218,13 @@ func get_receivers(): func wait(t): - if(typeof(t) == TYPE_STRING): - var suffix = t.substr(t.length() -1, 1) - var val = t.rstrip('s').rstrip('f').to_float() + if typeof(t) == TYPE_STRING: + var suffix = t.substr(t.length() - 1, 1) + var val = t.rstrip("s").rstrip("f").to_float() - if(suffix.to_lower() == 's'): + if suffix.to_lower() == "s": wait_secs(val) - elif(suffix.to_lower() == 'f'): + elif suffix.to_lower() == "f": wait_frames(val) else: wait_secs(t) @@ -239,71 +260,71 @@ func key_down(which): func key_echo(): - if(_last_event != null and _last_event is InputEventKey): + if _last_event != null and _last_event is InputEventKey: var new_key = _last_event.duplicate() new_key.echo = true _send_or_record_event(new_key) return self -func action_up(which, strength=1.0): - var event = InputFactory.action_up(which, strength) +func action_up(which, strength = 1.0): + var event = InputFactory.action_up(which, strength) _send_or_record_event(event) return self -func action_down(which, strength=1.0): - var event = InputFactory.action_down(which, strength) +func action_down(which, strength = 1.0): + var event = InputFactory.action_down(which, strength) _send_or_record_event(event) return self -func mouse_left_button_down(position, global_position=null): +func mouse_left_button_down(position, global_position = null): var event = InputFactory.mouse_left_button_down(position, global_position) _send_or_record_event(event) return self -func mouse_left_button_up(position, global_position=null): +func mouse_left_button_up(position, global_position = null): var event = InputFactory.mouse_left_button_up(position, global_position) _send_or_record_event(event) return self -func mouse_double_click(position, global_position=null): +func mouse_double_click(position, global_position = null): var event = InputFactory.mouse_double_click(position, global_position) event.double_click = true _send_or_record_event(event) return self -func mouse_right_button_down(position, global_position=null): +func mouse_right_button_down(position, global_position = null): var event = InputFactory.mouse_right_button_down(position, global_position) _send_or_record_event(event) return self -func mouse_right_button_up(position, global_position=null): +func mouse_right_button_up(position, global_position = null): var event = InputFactory.mouse_right_button_up(position, global_position) _send_or_record_event(event) return self -func mouse_motion(position, global_position=null): +func mouse_motion(position, global_position = null): var event = InputFactory.mouse_motion(position, global_position) _last_mouse_motion = event _send_or_record_event(event) return self -func mouse_relative_motion(offset, speed=Vector2(0, 0)): +func mouse_relative_motion(offset, speed = Vector2(0, 0)): var event = InputFactory.mouse_relative_motion(offset, _last_mouse_motion, speed) _last_mouse_motion = event _send_or_record_event(event) return self -func mouse_set_position(position, global_position=null): +func mouse_set_position(position, global_position = null): _last_mouse_motion = InputFactory.mouse_motion(position, global_position) return self @@ -315,25 +336,25 @@ func send_event(event): func release_all(): for key in _pressed_keys: - if(_pressed_keys[key]): + if _pressed_keys[key]: _send_event(InputFactory.key_up(key)) _pressed_keys.clear() for key in _pressed_actions: - if(_pressed_actions[key]): + if _pressed_actions[key]: _send_event(InputFactory.action_up(key)) _pressed_actions.clear() for key in _pressed_mouse_buttons: var event = _pressed_mouse_buttons[key].duplicate() - if(event.pressed): + if event.pressed: event.pressed = false _send_event(event) _pressed_mouse_buttons.clear() func hold_for(duration): - if(_last_event != null and _last_event.pressed): + if _last_event != null and _last_event.pressed: var next_event = _last_event.duplicate() next_event.pressed = false wait(duration) @@ -356,16 +377,20 @@ func clear(): _pressed_actions.clear() _pressed_mouse_buttons.clear() + func is_idle(): return _input_queue.size() == 0 + func is_key_pressed(which): var event = InputFactory.key_up(which) return _pressed_keys.has(event.keycode) and _pressed_keys[event.keycode] + func is_action_pressed(which): return _pressed_actions.has(which) and _pressed_actions[which] + func is_mouse_button_pressed(which): return _pressed_mouse_buttons.has(which) and _pressed_mouse_buttons[which] diff --git a/addons/gut/junit_xml_export.gd b/addons/gut/junit_xml_export.gd index 116cfdf..ff52615 100644 --- a/addons/gut/junit_xml_export.gd +++ b/addons/gut/junit_xml_export.gd @@ -1,10 +1,11 @@ # ------------------------------------------------------------------------------ # Creates an export of a test run in the JUnit XML format. # ------------------------------------------------------------------------------ -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _exporter = _utils.ResultExporter.new() + func indent(s, ind): var to_return = ind + s to_return = to_return.replace("\n", "\n" + ind) @@ -14,16 +15,17 @@ func indent(s, ind): func add_attr(name, value): return str(name, '="', value, '" ') + func _export_test_result(test): - var to_return = '' + var to_return = "" # Right now the pending and failure messages won't fit in the message # attribute because they can span multiple lines and need to be escaped. - if(test.status == 'pending'): - var skip_tag = str("", test.pending[0], "") + if test.status == "pending": + var skip_tag = str('', test.pending[0], "") to_return += skip_tag - elif(test.status == 'fail'): - var fail_tag = str("", test.failing[0], "") + elif test.status == "fail": + var fail_tag = str('', test.failing[0], "") to_return += fail_tag return to_return @@ -70,15 +72,15 @@ func _export_scripts(exp_results): func get_results_xml(gut): var exp_results = _exporter.get_results_dictionary(gut) var to_return = '' + "\n" - to_return += '= 0 and type_flag < _supported_defaults.size() and _supported_defaults[type_flag] != null + return ( + type_flag >= 0 + and type_flag < _supported_defaults.size() + and _supported_defaults[type_flag] != null + ) func _make_stub_default(method, index): - return str('__gutdbl.default_val("', method, '",', index, ')') + return str('__gutdbl.default_val("', method, '",', index, ")") + func _make_arg_array(method_meta, override_size): var to_return = [] @@ -128,14 +135,14 @@ func _make_arg_array(method_meta, override_size): to_return.append(CallParameters.new(PARAM_PREFIX + pname, dflt_text)) # Add in extra parameters from stub settings. - if(override_size != null): + if override_size != null: for i in range(method_meta.args.size(), override_size): - var pname = str(PARAM_PREFIX, 'arg', i) - print('-------- ', i, ' ', pname) + var pname = str(PARAM_PREFIX, "arg", i) + print("-------- ", i, " ", pname) var dflt_text = _make_stub_default(method_meta.name, i) to_return.append(CallParameters.new(pname, dflt_text)) - return [has_unsupported_defaults, to_return]; + return [has_unsupported_defaults, to_return] # Creates a list of parameters with defaults of null unless a default value is @@ -145,37 +152,37 @@ func _make_arg_array(method_meta, override_size): # If a default is found that we don't know how to handle then this method will # return null. func _get_arg_text(arg_array): - var text = '' + var text = "" for i in range(arg_array.size()): - text += str(arg_array[i].p_name, '=', arg_array[i].default) - if(i != arg_array.size() -1): - text += ', ' + text += str(arg_array[i].p_name, "=", arg_array[i].default) + if i != arg_array.size() - 1: + text += ", " return text # creates a call to the function in meta in the super's class. -func _get_super_call_text(method_name, args, super_name=""): - var params = '' +func _get_super_call_text(method_name, args, super_name = ""): + var params = "" for i in range(args.size()): params += args[i].p_name - if(i != args.size() -1): - params += ', ' + if i != args.size() - 1: + params += ", " - return str(super_name, 'await super(', params, ')') + return str(super_name, "await super(", params, ")") func _get_spy_call_parameters_text(args): - var called_with = 'null' + var called_with = "null" - if(args.size() > 0): - called_with = '[' + if args.size() > 0: + called_with = "[" for i in range(args.size()): called_with += args[i].p_name - if(i < args.size() - 1): - called_with += ', ' - called_with += ']' + if i < args.size() - 1: + called_with += ", " + called_with += "]" return called_with @@ -184,24 +191,26 @@ func _get_spy_call_parameters_text(args): # Public # ############### + func _get_init_text(meta, args, method_params, param_array): var text = null - var decleration = str('func ', meta.name, '(', method_params, ')') - var super_params = '' - if(args.size() > 0): + var decleration = str("func ", meta.name, "(", method_params, ")") + var super_params = "" + if args.size() > 0: for i in range(args.size()): super_params += args[i].p_name - if(i != args.size() -1): - super_params += ', ' + if i != args.size() - 1: + super_params += ", " - - text = _init_text.format({ - "func_decleration":decleration, - "super_params":super_params, - "param_array":param_array, - "method_name":meta.name - }) + text = _init_text.format( + { + "func_decleration": decleration, + "super_params": super_params, + "param_array": param_array, + "method_name": meta.name + } + ) return text @@ -212,47 +221,48 @@ func _get_init_text(meta, args, method_params, param_array): # printed and the declaration will return null. # # path is no longer used -func get_function_text(meta, path=null, override_size=null, super_name=""): - var method_params = '' +func get_function_text(meta, path = null, override_size = null, super_name = ""): + var method_params = "" var text = null - if(override_size != null): - print('!!!!!! ', override_size) + if override_size != null: + print("!!!!!! ", override_size) var result = _make_arg_array(meta, override_size) var has_unsupported = result[0] var args = result[1] var param_array = _get_spy_call_parameters_text(args) - if(has_unsupported): + if has_unsupported: # This will cause a runtime error. This is the most convenient way to # to stop running before the error gets more obscure. _make_arg_array # generates a gut error when unsupported defaults are found. method_params = null else: - method_params = _get_arg_text(args); + method_params = _get_arg_text(args) - if(param_array == 'null'): - param_array = '[]' + if param_array == "null": + param_array = "[]" - if(method_params != null): - if(meta.name == '_init'): - text = _get_init_text(meta, args, method_params, param_array) + if method_params != null: + if meta.name == "_init": + text = _get_init_text(meta, args, method_params, param_array) else: - var decleration = str('func ', meta.name, '(', method_params, '):') + var decleration = str("func ", meta.name, "(", method_params, "):") # decleration = str('# ', meta, "\n", decleration) - text = _func_text.format({ - "func_decleration":decleration, - "method_name":meta.name, - "param_array":param_array, - "super_call":_get_super_call_text(meta.name, args, super_name) - }) + text = _func_text.format( + { + "func_decleration": decleration, + "method_name": meta.name, + "param_array": param_array, + "super_call": _get_super_call_text(meta.name, args, super_name) + } + ) return text - - func get_logger(): return _lgr + func set_logger(logger): _lgr = logger diff --git a/addons/gut/one_to_many.gd b/addons/gut/one_to_many.gd index 6a0f818..9c0b6df 100644 --- a/addons/gut/one_to_many.gd +++ b/addons/gut/one_to_many.gd @@ -5,34 +5,39 @@ # ------------------------------------------------------------------------------ var _items = {} + # return the size of _items or the size of an element in _items if "one" was # specified. -func size(one=null): +func size(one = null): var to_return = 0 - if(one == null): + if one == null: to_return = _items.size() - elif(_items.has(one)): + elif _items.has(one): to_return = _items[one].size() return to_return + # Add an element to "one" if it does not already exist func add(one, many_item): - if(_items.has(one) and !_items[one].has(many_item)): + if _items.has(one) and !_items[one].has(many_item): _items[one].append(many_item) else: _items[one] = [many_item] + func clear(): _items.clear() + func has(one, many_item): var to_return = false - if(_items.has(one)): + if _items.has(one): to_return = _items[one].has(many_item) return to_return + func to_s(): - var to_return = '' + var to_return = "" for key in _items: to_return += str(key, ": ", _items[key], "\n") return to_return diff --git a/addons/gut/optparse.gd b/addons/gut/optparse.gd index f54988e..be1c7eb 100644 --- a/addons/gut/optparse.gd +++ b/addons/gut/optparse.gd @@ -52,7 +52,7 @@ class CmdLineParser: func _init(): for i in range(OS.get_cmdline_args().size()): - var opt_val = OS.get_cmdline_args()[i].split('=') + var opt_val = OS.get_cmdline_args()[i].split("=") _opts.append(opt_val) # Parse out multiple comma delimited values from a command line @@ -60,13 +60,13 @@ class CmdLineParser: # additional values are comma separated. func _parse_array_value(full_option): var value = _parse_option_value(full_option) - var split = value.split(',') + var split = value.split(",") return split # Parse out the value of an option. Values are separated from # the option name with "=" func _parse_option_value(full_option): - if(full_option.size() > 1): + if full_option.size() > 1: return full_option[1] else: return null @@ -77,13 +77,13 @@ class CmdLineParser: var found = false var idx = 0 - while(idx < _opts.size() and !found): - if(_opts[idx][0] == name): + while idx < _opts.size() and !found: + if _opts[idx][0] == name: found = true else: idx += 1 - if(found): + if found: return idx else: return -1 @@ -92,7 +92,7 @@ class CmdLineParser: _used_options.append(option) var to_return = [] var opt_loc = find_option(option) - if(opt_loc != -1): + if opt_loc != -1: to_return = _parse_array_value(_opts[opt_loc]) _opts.remove_at(opt_loc) @@ -105,7 +105,7 @@ class CmdLineParser: _used_options.append(option) var to_return = null var opt_loc = find_option(option) - if(opt_loc != -1): + if opt_loc != -1: to_return = _parse_option_value(_opts[opt_loc]) _opts.remove_at(opt_loc) @@ -133,42 +133,44 @@ class CmdLineParser: to_return.remove_at(script_option + 1) to_return.remove_at(script_option) - while(_used_options.size() > 0): + while _used_options.size() > 0: var index = to_return.find(_used_options[0].split("=")[0]) - if(index != -1): + if index != -1: to_return.remove_at(index) _used_options.remove_at(0) return to_return + #------------------------------------------------------------------------------- # Simple class to hold a command line option #------------------------------------------------------------------------------- class Option: var value = null - var option_name = '' + var option_name = "" var default = null - var description = '' + var description = "" - func _init(name,default_value,desc=''): + func _init(name, default_value, desc = ""): option_name = name default = default_value description = desc - value = null#default_value + value = null #default_value - func pad(to_pad, size, pad_with=' '): + func pad(to_pad, size, pad_with = " "): var to_return = to_pad for _i in range(to_pad.length(), size): to_return += pad_with return to_return - func to_s(min_space=0): + func to_s(min_space = 0): var subbed_desc = description - if(subbed_desc.find('[default]') != -1): - subbed_desc = subbed_desc.replace('[default]', str(default)) + if subbed_desc.find("[default]") != -1: + subbed_desc = subbed_desc.replace("[default]", str(default)) return pad(option_name, min_space) + subbed_desc + #------------------------------------------------------------------------------- # The high level interface between this script and the command line options # supplied. Uses Option class and CmdLineParser to extract information from @@ -176,47 +178,53 @@ class Option: #------------------------------------------------------------------------------- var options = [] var _opts = [] -var _banner = '' +var _banner = "" + func add(name, default, desc): options.append(Option.new(name, default, desc)) + func get_value(name): var found = false var idx = 0 - while(idx < options.size() and !found): - if(options[idx].option_name == name): + while idx < options.size() and !found: + if options[idx].option_name == name: found = true else: idx += 1 - if(found): + if found: return options[idx].value else: print("COULD NOT FIND OPTION " + name) return null + func set_banner(banner): _banner = banner + func print_help(): var longest = 0 for i in range(options.size()): - if(options[i].option_name.length() > longest): + if options[i].option_name.length() > longest: longest = options[i].option_name.length() - print('---------------------------------------------------------') + print("---------------------------------------------------------") print(_banner) print("\nOptions\n-------") for i in range(options.size()): - print(' ' + options[i].to_s(longest + 2)) - print('---------------------------------------------------------') + print(" " + options[i].to_s(longest + 2)) + print("---------------------------------------------------------") + func print_options(): for i in range(options.size()): - print(options[i].option_name + '=' + str(options[i].value)) + print(options[i].option_name + "=" + str(options[i].value)) + func parse(): var parser = CmdLineParser.new() @@ -228,24 +236,30 @@ func parse(): # Without this check, you can't tell the difference between the # defaults and what was specified, so you can't punch through # higher level options. - if(parser.was_specified(options[i].option_name)): - if(t == TYPE_INT): + if parser.was_specified(options[i].option_name): + if t == TYPE_INT: options[i].value = int(parser.get_value(options[i].option_name)) - elif(t == TYPE_STRING): + elif t == TYPE_STRING: options[i].value = parser.get_value(options[i].option_name) - elif(t == TYPE_ARRAY): + elif t == TYPE_ARRAY: options[i].value = parser.get_array_value(options[i].option_name) - elif(t == TYPE_BOOL): + elif t == TYPE_BOOL: options[i].value = parser.was_specified(options[i].option_name) - elif(t == TYPE_FLOAT): + elif t == TYPE_FLOAT: options[i].value = parser.get_value(options[i].option_name) - elif(t == TYPE_NIL): - print(options[i].option_name + ' cannot be processed, it has a nil datatype') + elif t == TYPE_NIL: + print(options[i].option_name + " cannot be processed, it has a nil datatype") else: - print(options[i].option_name + ' cannot be processed, it has unknown datatype:' + str(t)) + print( + ( + options[i].option_name + + " cannot be processed, it has unknown datatype:" + + str(t) + ) + ) var unused = parser.get_unused_options() - if(unused.size() > 0): + if unused.size() > 0: print("Unrecognized options: ", unused) return false diff --git a/addons/gut/orphan_counter.gd b/addons/gut/orphan_counter.gd index b31e2b6..2aa248a 100644 --- a/addons/gut/orphan_counter.gd +++ b/addons/gut/orphan_counter.gd @@ -33,23 +33,27 @@ # ############################################################################## var _counters = {} + func orphan_count(): return Performance.get_monitor(Performance.OBJECT_ORPHAN_NODE_COUNT) + func add_counter(name): _counters[name] = orphan_count() + # Returns the number of orphans created since add_counter was last called for # the name. Returns -1 to avoid blowing up with an invalid name but still # be somewhat visible that we've done something wrong. func get_counter(name): return orphan_count() - _counters[name] if _counters.has(name) else -1 + func print_orphans(name, lgr): var count = get_counter(name) - if(count > 0): - var o = 'orphan' - if(count > 1): - o = 'orphans' - lgr.orphan(str(count, ' new ', o, ' in ', name, '.')) + if count > 0: + var o = "orphan" + if count > 1: + o = "orphans" + lgr.orphan(str(count, " new ", o, " in ", name, ".")) diff --git a/addons/gut/parameter_factory.gd b/addons/gut/parameter_factory.gd index 6bffe4c..be10aec 100644 --- a/addons/gut/parameter_factory.gd +++ b/addons/gut/parameter_factory.gd @@ -56,11 +56,11 @@ static func named_parameters(names, values): var entry = {} var parray = values[i] - if(typeof(parray) != TYPE_ARRAY): + if typeof(parray) != TYPE_ARRAY: parray = [values[i]] for j in range(names.size()): - if(j >= parray.size()): + if j >= parray.size(): entry[names[j]] = null else: entry[names[j]] = parray[j] diff --git a/addons/gut/parameter_handler.gd b/addons/gut/parameter_handler.gd index 6b37e82..5934b3d 100644 --- a/addons/gut/parameter_handler.gd +++ b/addons/gut/parameter_handler.gd @@ -1,37 +1,44 @@ -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _params = null var _call_count = 0 var _logger = null -func _init(params=null): + +func _init(params = null): _params = params _logger = _utils.get_logger() - if(typeof(_params) != TYPE_ARRAY): - _logger.error('You must pass an array to parameter_handler constructor.') + if typeof(_params) != TYPE_ARRAY: + _logger.error("You must pass an array to parameter_handler constructor.") _params = null func next_parameters(): _call_count += 1 - return _params[_call_count -1] + return _params[_call_count - 1] + func get_current_parameters(): return _params[_call_count] + func is_done(): var done = true - if(_params != null): + if _params != null: done = _call_count == _params.size() return done + func get_logger(): return _logger + func set_logger(logger): _logger = logger + func get_call_count(): return _call_count + func get_parameter_count(): return _params.size() diff --git a/addons/gut/printers.gd b/addons/gut/printers.gd index 9843fd0..6ac9866 100644 --- a/addons/gut/printers.gd +++ b/addons/gut/printers.gd @@ -4,8 +4,8 @@ class Printer: var _format_enabled = true var _disabled = false - var _printer_name = 'NOT SET' - var _show_name = false # used for debugging, set manually + var _printer_name = "NOT SET" + var _show_name = false # used for debugging, set manually func get_format_enabled(): return _format_enabled @@ -13,16 +13,16 @@ class Printer: func set_format_enabled(format_enabled): _format_enabled = format_enabled - func send(text, fmt=null): - if(_disabled): + func send(text, fmt = null): + if _disabled: return var formatted = text - if(fmt != null and _format_enabled): + if fmt != null and _format_enabled: formatted = format_text(text, fmt) - if(_show_name): - formatted = str('(', _printer_name, ')') + formatted + if _show_name: + formatted = str("(", _printer_name, ")") + formatted _output(formatted) @@ -41,6 +41,7 @@ class Printer: func format_text(text, fmt): return text + # ------------------------------------------------------------------------------ # Responsible for sending text to a GUT gui. # ------------------------------------------------------------------------------ @@ -48,20 +49,16 @@ class GutGuiPrinter: extends Printer var _textbox = null - var _colors = { - red = Color.RED, - yellow = Color.YELLOW, - green = Color.GREEN - } + var _colors = {red = Color.RED, yellow = Color.YELLOW, green = Color.GREEN} func _init(): - _printer_name = 'gui' + _printer_name = "gui" func _wrap_with_tag(text, tag): - return str('[', tag, ']', text, '[/', tag, ']') + return str("[", tag, "]", text, "[/", tag, "]") func _color_text(text, c_word): - return '[color=' + c_word + ']' + text + '[/color]' + return "[color=" + c_word + "]" + text + "[/color]" # Remember, we have to use push and pop because the output from the tests # can contain [] in it which can mess up the formatting. There is no way @@ -80,14 +77,14 @@ class GutGuiPrinter: # are in the output. Good luck, and I hope I typed enough to not go too # far that rabbit hole before finding out it's not worth it. func format_text(text, fmt): - if(_textbox == null): + if _textbox == null: return - if(fmt == 'bold'): + if fmt == "bold": _textbox.push_bold() - elif(fmt == 'underline'): + elif fmt == "underline": _textbox.push_underline() - elif(_colors.has(fmt)): + elif _colors.has(fmt): _textbox.push_color(_colors[fmt]) else: # just pushing something to pop. @@ -96,10 +93,10 @@ class GutGuiPrinter: _textbox.add_text(text) _textbox.pop() - return '' + return "" func _output(text): - if(_textbox == null): + if _textbox == null: return _textbox.add_text(text) @@ -121,6 +118,7 @@ class GutGuiPrinter: func get_disabled(): return _disabled and _textbox != null + # ------------------------------------------------------------------------------ # This AND TerminalPrinter should not be enabled at the same time since it will # result in duplicate output. printraw does not print to the console so i had @@ -128,20 +126,21 @@ class GutGuiPrinter: # ------------------------------------------------------------------------------ class ConsolePrinter: extends Printer - var _buffer = '' + var _buffer = "" func _init(): - _printer_name = 'console' + _printer_name = "console" # suppresses output until it encounters a newline to keep things # inline as much as possible. func _output(text): - if(text.ends_with("\n")): - print(_buffer + text.left(text.length() -1)) - _buffer = '' + if text.ends_with("\n"): + print(_buffer + text.left(text.length() - 1)) + _buffer = "" else: _buffer += text + # ------------------------------------------------------------------------------ # Prints text to terminal, formats some words. # ------------------------------------------------------------------------------ @@ -149,21 +148,18 @@ class TerminalPrinter: extends Printer var escape = PackedByteArray([0x1b]).get_string_from_ascii() - var cmd_colors = { - red = escape + '[31m', - yellow = escape + '[33m', - green = escape + '[32m', - - underline = escape + '[4m', - bold = escape + '[1m', - - default = escape + '[0m', - - clear_line = escape + '[2K' + var cmd_colors = { + red = escape + "[31m", + yellow = escape + "[33m", + green = escape + "[32m", + underline = escape + "[4m", + bold = escape + "[1m", + default = escape + "[0m", + clear_line = escape + "[2K" } func _init(): - _printer_name = 'terminal' + _printer_name = "terminal" func _output(text): # Note, printraw does not print to the console. @@ -176,7 +172,7 @@ class TerminalPrinter: send(cmd_colors.clear_line) func back(n): - send(escape + str('[', n, 'D')) + send(escape + str("[", n, "D")) func forward(n): - send(escape + str('[', n, 'C')) + send(escape + str("[", n, "C")) diff --git a/addons/gut/result_exporter.gd b/addons/gut/result_exporter.gd index 891f4f5..50f71f4 100644 --- a/addons/gut/result_exporter.gd +++ b/addons/gut/result_exporter.gd @@ -4,56 +4,62 @@ # of a run and exporting it in a specific format. This can also serve as a # unofficial GUT export format. # ------------------------------------------------------------------------------ -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var json = JSON.new() + func _export_tests(summary_script): var to_return = {} var tests = summary_script.get_tests() for key in tests.keys(): to_return[key] = { - "status":tests[key].get_status(), - "passing":tests[key].pass_texts, - "failing":tests[key].fail_texts, - "pending":tests[key].pending_texts, - "orphans":tests[key].orphans + "status": tests[key].get_status(), + "passing": tests[key].pass_texts, + "failing": tests[key].fail_texts, + "pending": tests[key].pending_texts, + "orphans": tests[key].orphans } return to_return + # TODO # errors func _export_scripts(summary): - if(summary == null): + if summary == null: return {} var scripts = {} for s in summary.get_scripts(): scripts[s.name] = { - 'props':{ - "tests":s._tests.size(), - "pending":s.get_pending_count(), - "failures":s.get_fail_count(), + "props": + { + "tests": s._tests.size(), + "pending": s.get_pending_count(), + "failures": s.get_fail_count(), }, - "tests":_export_tests(s) + "tests": _export_tests(s) } return scripts + func _make_results_dict(): - var result = { - 'test_scripts':{ - "props":{ - "pending":0, - "failures":0, - "passing":0, - "tests":0, - "time":0, - "orphans":0, - "errors":0, - "warnings":0 + var result = { + "test_scripts": + { + "props": + { + "pending": 0, + "failures": 0, + "passing": 0, + "tests": 0, + "time": 0, + "orphans": 0, + "errors": 0, + "warnings": 0 }, - "scripts":[] + "scripts": [] } } return result @@ -62,15 +68,15 @@ func _make_results_dict(): # TODO # time # errors -func get_results_dictionary(gut, include_scripts=true): +func get_results_dictionary(gut, include_scripts = true): var summary = gut.get_summary() var scripts = [] - if(include_scripts): + if include_scripts: scripts = _export_scripts(summary) - var result = _make_results_dict() - if(summary != null): + var result = _make_results_dict() + if summary != null: var totals = summary.get_totals() var props = result.test_scripts.props @@ -80,8 +86,8 @@ func get_results_dictionary(gut, include_scripts=true): props.tests = totals.tests props.errors = gut.logger.get_errors().size() props.warnings = gut.logger.get_warnings().size() - props.time = gut.get_elapsed_time() - props.orphans = gut.get_orphan_counter().get_counter('total') + props.time = gut.get_elapsed_time() + props.orphans = gut.get_orphan_counter().get_counter("total") result.test_scripts.scripts = scripts return result @@ -89,23 +95,22 @@ func get_results_dictionary(gut, include_scripts=true): func write_json_file(gut, path): var dict = get_results_dictionary(gut) - var json_text = json.stringify(dict, ' ') + var json_text = json.stringify(dict, " ") var f_result = _utils.write_file(path, json_text) - if(f_result != OK): + if f_result != OK: var msg = str("Error: ", f_result, ". Could not create export file ", path) _utils.get_logger().error(msg) return f_result - func write_summary_file(gut, path): var dict = get_results_dictionary(gut, false) - var json_text = json.stringify(dict, ' ') + var json_text = json.stringify(dict, " ") var f_result = _utils.write_file(path, json_text) - if(f_result != OK): + if f_result != OK: var msg = str("Error: ", f_result, ". Could not create export file ", path) _utils.get_logger().error(msg) diff --git a/addons/gut/script_parser.gd b/addons/gut/script_parser.gd index 4b21931..faa4075 100644 --- a/addons/gut/script_parser.gd +++ b/addons/gut/script_parser.gd @@ -4,27 +4,26 @@ # overloaded or do not have a "super" equivalent so we can't just pass # through. const BLACKLIST = [ - '_draw', - '_enter_tree', - '_exit_tree', - '_get_minimum_size', # Nonexistent function _get_minimum_size - '_get', # probably - '_input', - '_notification', - '_physics_process', - '_process', - '_set', - '_to_string', # nonexistant function super._to_string - '_unhandled_input', - '_unhandled_key_input', - 'draw_mesh', # issue with one parameter, value is `Null((..), (..), (..))`` - 'emit_signal', # can't handle extra parameters to be sent with signal. - 'get_path', - 'get_script', - 'get', - 'has_method', - - 'print_orphan_nodes' + "_draw", + "_enter_tree", + "_exit_tree", + "_get_minimum_size", # Nonexistent function _get_minimum_size + "_get", # probably + "_input", + "_notification", + "_physics_process", + "_process", + "_set", + "_to_string", # nonexistant function super._to_string + "_unhandled_input", + "_unhandled_key_input", + "draw_mesh", # issue with one parameter, value is `Null((..), (..), (..))`` + "emit_signal", # can't handle extra parameters to be sent with signal. + "get_path", + "get_script", + "get", + "has_method", + "print_orphan_nodes" ] @@ -36,14 +35,16 @@ const BLACKLIST = [ # ------------------------------------------------------------------------------ class ParsedMethod: var _meta = {} - var meta = _meta : - get: return _meta - set(val): return; + var meta = _meta: + get: + return _meta + set(val): + return var _parameters = [] var is_local = false - const NO_DEFAULT = '__no__default__' + const NO_DEFAULT = "__no__default__" func _init(metadata): _meta = metadata @@ -52,39 +53,35 @@ class ParsedMethod: var arg = _meta.args[i] # Add a "default" property to the metadata so we don't have to do # weird default position math again. - if(i >= start_default): - arg['default'] = _meta.default_args[start_default - i] + if i >= start_default: + arg["default"] = _meta.default_args[start_default - i] else: - arg['default'] = NO_DEFAULT + arg["default"] = NO_DEFAULT _parameters.append(arg) - func is_black_listed(): return BLACKLIST.find(_meta.name) != -1 - func to_s(): var s = _meta.name + "(" for i in range(_meta.args.size()): var arg = _meta.args[i] - if(str(arg.default) != NO_DEFAULT): + if str(arg.default) != NO_DEFAULT: var val = str(arg.default) - if(val == ''): + if val == "": val = '""' - s += str(arg.name, ' = ', val) + s += str(arg.name, " = ", val) else: s += str(arg.name) - if(i != _meta.args.size() -1): - s += ', ' + if i != _meta.args.size() - 1: + s += ", " s += ")" return s - - # ------------------------------------------------------------------------------ # Doesn't know if a method is local and in super, but not sure if that will # ever matter. @@ -92,111 +89,114 @@ class ParsedMethod: class ParsedScript: # All methods indexed by name. var _methods_by_name = {} - var _utils = load('res://addons/gut/utils.gd').get_instance() + var _utils = load("res://addons/gut/utils.gd").get_instance() var _script_path = null - var script_path = _script_path : - get: return _script_path - set(val): return; + var script_path = _script_path: + get: + return _script_path + set(val): + return var _subpath = null - var subpath = null : - get: return _subpath - set(val): return; + var subpath = null: + get: + return _subpath + set(val): + return var _resource = null - var resource = null : - get: return _resource - set(val): return; + var resource = null: + get: + return _resource + set(val): + return var _native_instance = null - var is_native = false : - get: return _native_instance != null - set(val): return; + var is_native = false: + get: + return _native_instance != null + set(val): + return func unreference(): - if(_native_instance != null): + if _native_instance != null: _native_instance.free() return super() - - func _init(script_or_inst, inner_class=null): + func _init(script_or_inst, inner_class = null): var to_load = script_or_inst - if(_utils.is_native_class(to_load)): + if _utils.is_native_class(to_load): _resource = to_load _native_instance = to_load.new() else: - if(!script_or_inst is Resource): + if !script_or_inst is Resource: to_load = load(script_or_inst.get_script().get_path()) _script_path = to_load.resource_path - if(inner_class != null): + if inner_class != null: _subpath = _find_subpath(to_load, inner_class) - if(inner_class == null): + if inner_class == null: _resource = to_load else: _resource = inner_class to_load = inner_class - _parse_methods(to_load) - func _has_flag_to_be_ignored(flags): return false # I think this is getting anything that has the 1 flag set...I think - return flags & (1 << 2) == 0 && \ - flags & (1 << 4) == 0 && \ - flags & (1 << 6) == 0 - + return flags & (1 << 2) == 0 && flags & (1 << 4) == 0 && flags & (1 << 6) == 0 func _print_flags(meta): - print(str(meta.name, ':').rpad(30), str(meta.flags).rpad(4), ' = ', _utils.dec2bistr(meta.flags, 10)) - + print( + str(meta.name, ":").rpad(30), + str(meta.flags).rpad(4), + " = ", + _utils.dec2bistr(meta.flags, 10) + ) func _get_native_methods(base_type): var to_return = [] - if(base_type != null): - var source = str('extends ', base_type) + if base_type != null: + var source = str("extends ", base_type) var inst = _utils.create_script_from_source(source).new() to_return = inst.get_method_list() - if(! inst is RefCounted): + if !inst is RefCounted: inst.free() return to_return - func _parse_methods(thing): var methods = [] - if(is_native): + if is_native: methods = _native_instance.get_method_list() else: var base_type = thing.get_instance_base_type() methods = _get_native_methods(base_type) for m in methods: - if(!_has_flag_to_be_ignored(m.flags)): + if !_has_flag_to_be_ignored(m.flags): var parsed = ParsedMethod.new(m) _methods_by_name[m.name] = parsed # _init must always be included so that we can initialize # double_tools - if(m.name == '_init'): + if m.name == "_init": parsed.is_local = true - # This loop will overwrite all entries in _methods_by_name with the local # method object so there is only ever one listing for a function with # the right "is_local" flag. - if(!is_native): + if !is_native: methods = thing.get_script_method_list() for m in methods: var parsed_method = ParsedMethod.new(m) parsed_method.is_local = true _methods_by_name[m.name] = parsed_method - func _find_subpath(parent_script, inner): var const_map = parent_script.get_script_constant_map() var consts = const_map.keys() @@ -204,115 +204,106 @@ class ParsedScript: var found = false var to_return = null - while(const_idx < consts.size() and !found): + while const_idx < consts.size() and !found: var key = consts[const_idx] var const_val = const_map[key] - if(typeof(const_val) == TYPE_OBJECT): - if(const_val == inner): + if typeof(const_val) == TYPE_OBJECT: + if const_val == inner: found = true to_return = key else: to_return = _find_subpath(const_val, inner) - if(to_return != null): - to_return = str(key, '.', to_return) + if to_return != null: + to_return = str(key, ".", to_return) found = true const_idx += 1 return to_return - func get_method(name): return _methods_by_name[name] - func is_method_blacklisted(m_name): - if(_methods_by_name.has(m_name)): + if _methods_by_name.has(m_name): return _methods_by_name[m_name].is_black_listed() - func get_super_method(name): var to_return = get_method(name) - if(to_return.is_local): + if to_return.is_local: to_return = null return to_return func get_local_method(name): var to_return = get_method(name) - if(!to_return.is_local): + if !to_return.is_local: to_return = null return to_return - func get_sorted_method_names(): var keys = _methods_by_name.keys() keys.sort() return keys - func get_local_method_names(): var names = [] for method in _methods_by_name: - if(_methods_by_name[method].is_local): + if _methods_by_name[method].is_local: names.append(method) return names - func get_super_method_names(): var names = [] for method in _methods_by_name: - if(!_methods_by_name[method].is_local): + if !_methods_by_name[method].is_local: names.append(method) return names - func get_local_methods(): var to_return = [] for key in _methods_by_name: var method = _methods_by_name[key] - if(method.is_local): + if method.is_local: to_return.append(method) return to_return - func get_super_methods(): var to_return = [] for key in _methods_by_name: var method = _methods_by_name[key] - if(!method.is_local): + if !method.is_local: to_return.append(method) return to_return - func get_extends_text(): var text = null - if(is_native): + if is_native: text = str("extends ", _native_instance.get_class()) else: text = str("extends '", _script_path, "'") - if(_subpath != null): - text += '.' + _subpath + if _subpath != null: + text += "." + _subpath return text # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ var scripts = {} -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() func _get_instance_id(thing): var inst_id = null - if(_utils.is_native_class(thing)): - var id_str = str(thing).replace("<", '').replace(">", '').split('#')[1] + if _utils.is_native_class(thing): + var id_str = str(thing).replace("<", "").replace(">", "").split("#")[1] inst_id = id_str.to_int() - elif(typeof(thing) == TYPE_STRING): - if(FileAccess.file_exists(thing)): + elif typeof(thing) == TYPE_STRING: + if FileAccess.file_exists(thing): inst_id = load(thing).get_instance_id() else: inst_id = thing.get_instance_id() @@ -320,27 +311,26 @@ func _get_instance_id(thing): return inst_id -func parse(thing, inner_thing=null): +func parse(thing, inner_thing = null): var key = -1 - if(inner_thing == null): + if inner_thing == null: key = _get_instance_id(thing) else: key = _get_instance_id(inner_thing) var parsed = null - if(key != null): - if(scripts.has(key)): + if key != null: + if scripts.has(key): parsed = scripts[key] else: var obj = instance_from_id(_get_instance_id(thing)) var inner = null - if(inner_thing != null): + if inner_thing != null: inner = instance_from_id(_get_instance_id(inner_thing)) - if(obj is Resource or _utils.is_native_class(obj)): + if obj is Resource or _utils.is_native_class(obj): parsed = ParsedScript.new(obj, inner) scripts[key] = parsed return parsed - diff --git a/addons/gut/signal_watcher.gd b/addons/gut/signal_watcher.gd index f7c11a7..d9193cd 100644 --- a/addons/gut/signal_watcher.gd +++ b/addons/gut/signal_watcher.gd @@ -26,7 +26,7 @@ # Some arbitrary string that should never show up by accident. If it does, then # shame on you. -const ARG_NOT_SET = '_*_argument_*_is_*_not_set_*_' +const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_" # This hash holds the objects that are being watched, the signals that are being # watched, and an array of arrays that contains arguments that were passed @@ -52,19 +52,21 @@ const ARG_NOT_SET = '_*_argument_*_is_*_not_set_*_' # - some_signal on ref2 was never emitted. # - other_signal on ref2 was emitted 3 times, each time with 3 parameters. var _watched_signals = {} -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _lgr = _utils.get_logger() + func _add_watched_signal(obj, name): # SHORTCIRCUIT - ignore dupes - if(_watched_signals.has(obj) and _watched_signals[obj].has(name)): + if _watched_signals.has(obj) and _watched_signals[obj].has(name): return - if(!_watched_signals.has(obj)): - _watched_signals[obj] = {name:[]} + if !_watched_signals.has(obj): + _watched_signals[obj] = {name: []} else: _watched_signals[obj][name] = [] - obj.connect(name,Callable(self,'_on_watched_signal').bind(obj,name)) + obj.connect(name, Callable(self, "_on_watched_signal").bind(obj, name)) + # This handles all the signals that are watched. It supports up to 9 parameters # which could be emitted by the signal and the two parameters used when it is @@ -75,39 +77,53 @@ func _add_watched_signal(obj, name): # Based on the documentation of emit_signal, it appears you can only pass up # to 4 parameters when firing a signal. I haven't verified this, but this should # future proof this some if the value ever grows. -func _on_watched_signal(arg1=ARG_NOT_SET, arg2=ARG_NOT_SET, arg3=ARG_NOT_SET, \ - arg4=ARG_NOT_SET, arg5=ARG_NOT_SET, arg6=ARG_NOT_SET, \ - arg7=ARG_NOT_SET, arg8=ARG_NOT_SET, arg9=ARG_NOT_SET, \ - arg10=ARG_NOT_SET, arg11=ARG_NOT_SET): +func _on_watched_signal( + arg1 = ARG_NOT_SET, + arg2 = ARG_NOT_SET, + arg3 = ARG_NOT_SET, + arg4 = ARG_NOT_SET, + arg5 = ARG_NOT_SET, + arg6 = ARG_NOT_SET, + arg7 = ARG_NOT_SET, + arg8 = ARG_NOT_SET, + arg9 = ARG_NOT_SET, + arg10 = ARG_NOT_SET, + arg11 = ARG_NOT_SET +): var args = [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11] # strip off any unused vars. - var idx = args.size() -1 - while(str(args[idx]) == ARG_NOT_SET): + var idx = args.size() - 1 + while str(args[idx]) == ARG_NOT_SET: args.remove_at(idx) idx -= 1 # retrieve object and signal name from the array and remove_at them. These # will always be at the end since they are added when the connect happens. - var signal_name = args[args.size() -1] + var signal_name = args[args.size() - 1] args.pop_back() - var object = args[args.size() -1] + var object = args[args.size() - 1] args.pop_back() - if(_watched_signals.has(object)): + if _watched_signals.has(object): _watched_signals[object][signal_name].append(args) else: - _lgr.error(str("signal_watcher._on_watched_signal: Got signal for unwatched object: ", object, '::', signal_name)) + _lgr.error( + str( + "signal_watcher._on_watched_signal: Got signal for unwatched object: ", + object, + "::", + signal_name + ) + ) + # This parameter stuff should go into test.gd not here. This thing works # just fine the way it is. -func _obj_name_pair(obj_or_signal, signal_name=null): - var to_return = { - 'object' : obj_or_signal, - 'signal_name' : signal_name - } - if(obj_or_signal is Signal): - to_return.object = obj_or_signal.get_object() +func _obj_name_pair(obj_or_signal, signal_name = null): + var to_return = {"object": obj_or_signal, "signal_name": signal_name} + if obj_or_signal is Signal: + to_return.object = obj_or_signal.get_object() to_return.signal_name = obj_or_signal.get_name() return to_return @@ -116,72 +132,82 @@ func _obj_name_pair(obj_or_signal, signal_name=null): func does_object_have_signal(object, signal_name): var signals = object.get_signal_list() for i in range(signals.size()): - if(signals[i]['name'] == signal_name): + if signals[i]["name"] == signal_name: return true return false + func watch_signals(object): var signals = object.get_signal_list() for i in range(signals.size()): - _add_watched_signal(object, signals[i]['name']) + _add_watched_signal(object, signals[i]["name"]) + func watch_signal(object, signal_name): var did = false - if(does_object_have_signal(object, signal_name)): + if does_object_have_signal(object, signal_name): _add_watched_signal(object, signal_name) did = true else: - _utils.get_logger().warn(str(object, ' does not have signal ', signal_name)) + _utils.get_logger().warn(str(object, " does not have signal ", signal_name)) return did + func get_emit_count(object, signal_name): var to_return = -1 - if(is_watching(object, signal_name)): + if is_watching(object, signal_name): to_return = _watched_signals[object][signal_name].size() return to_return -func did_emit(object, signal_name=null): + +func did_emit(object, signal_name = null): var vals = _obj_name_pair(object, signal_name) var did = false - if(is_watching(vals.object, vals.signal_name)): + if is_watching(vals.object, vals.signal_name): did = get_emit_count(vals.object, vals.signal_name) != 0 return did + func print_object_signals(object): var list = object.get_signal_list() for i in range(list.size()): print(list[i].name, "\n ", list[i]) -func get_signal_parameters(object, signal_name, index=-1): + +func get_signal_parameters(object, signal_name, index = -1): var params = null - if(is_watching(object, signal_name)): + if is_watching(object, signal_name): var all_params = _watched_signals[object][signal_name] - if(all_params.size() > 0): - if(index == -1): - index = all_params.size() -1 + if all_params.size() > 0: + if index == -1: + index = all_params.size() - 1 params = all_params[index] return params + func is_watching_object(object): return _watched_signals.has(object) + func is_watching(object, signal_name): return _watched_signals.has(object) and _watched_signals[object].has(signal_name) + func clear(): for obj in _watched_signals: - if(_utils.is_not_freed(obj)): + if _utils.is_not_freed(obj): for signal_name in _watched_signals[obj]: - obj.disconnect(signal_name, Callable(self,'_on_watched_signal')) + obj.disconnect(signal_name, Callable(self, "_on_watched_signal")) _watched_signals.clear() + # Returns a list of all the signal names that were emitted by the object. # If the object is not being watched then an empty list is returned. func get_signals_emitted(obj): var emitted = [] - if(is_watching_object(obj)): + if is_watching_object(obj): for signal_name in _watched_signals[obj]: - if(_watched_signals[obj][signal_name].size() > 0): + if _watched_signals[obj][signal_name].size() > 0: emitted.append(signal_name) return emitted diff --git a/addons/gut/spy.gd b/addons/gut/spy.gd index 2aef4ad..5c0d384 100644 --- a/addons/gut/spy.gd +++ b/addons/gut/spy.gd @@ -9,100 +9,119 @@ # }, # } var _calls = {} -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _lgr = _utils.get_logger() var _compare = _utils.Comparator.new() + func _find_parameters(call_params, params_to_find): var found = false var idx = 0 - while(idx < call_params.size() and !found): + while idx < call_params.size() and !found: var result = _compare.deep(call_params[idx], params_to_find) - if(result.are_equal): + if result.are_equal: found = true else: idx += 1 return found + func _get_params_as_string(params): - var to_return = '' - if(params == null): - return '' + var to_return = "" + if params == null: + return "" for i in range(params.size()): - if(params[i] == null): - to_return += 'null' + if params[i] == null: + to_return += "null" else: - if(typeof(params[i]) == TYPE_STRING): + if typeof(params[i]) == TYPE_STRING: to_return += str('"', params[i], '"') else: to_return += str(params[i]) - if(i != params.size() -1): - to_return += ', ' + if i != params.size() - 1: + to_return += ", " return to_return -func add_call(variant, method_name, parameters=null): - if(!_calls.has(variant)): + +func add_call(variant, method_name, parameters = null): + if !_calls.has(variant): _calls[variant] = {} - if(!_calls[variant].has(method_name)): + if !_calls[variant].has(method_name): _calls[variant][method_name] = [] _calls[variant][method_name].append(parameters) -func was_called(variant, method_name, parameters=null): + +func was_called(variant, method_name, parameters = null): var to_return = false - if(_calls.has(variant) and _calls[variant].has(method_name)): - if(parameters): + if _calls.has(variant) and _calls[variant].has(method_name): + if parameters: to_return = _find_parameters(_calls[variant][method_name], parameters) else: to_return = true return to_return -func get_call_parameters(variant, method_name, index=-1): + +func get_call_parameters(variant, method_name, index = -1): var to_return = null var get_index = -1 - if(_calls.has(variant) and _calls[variant].has(method_name)): + if _calls.has(variant) and _calls[variant].has(method_name): var call_size = _calls[variant][method_name].size() - if(index == -1): + if index == -1: # get the most recent call by default - get_index = call_size -1 + get_index = call_size - 1 else: get_index = index - if(get_index < call_size): + if get_index < call_size: to_return = _calls[variant][method_name][get_index] else: - _lgr.error(str('Specified index ', index, ' is outside range of the number of registered calls: ', call_size)) + _lgr.error( + str( + "Specified index ", + index, + " is outside range of the number of registered calls: ", + call_size + ) + ) return to_return -func call_count(instance, method_name, parameters=null): + +func call_count(instance, method_name, parameters = null): var to_return = 0 - if(was_called(instance, method_name)): - if(parameters): + if was_called(instance, method_name): + if parameters: for i in range(_calls[instance][method_name].size()): - if(_calls[instance][method_name][i] == parameters): + if _calls[instance][method_name][i] == parameters: to_return += 1 else: to_return = _calls[instance][method_name].size() return to_return + func clear(): _calls = {} + func get_call_list_as_string(instance): - var to_return = '' - if(_calls.has(instance)): + var to_return = "" + if _calls.has(instance): for method in _calls[instance]: for i in range(_calls[instance][method].size()): - to_return += str(method, '(', _get_params_as_string(_calls[instance][method][i]), ")\n") + to_return += str( + method, "(", _get_params_as_string(_calls[instance][method][i]), ")\n" + ) return to_return + func get_logger(): return _lgr + func set_logger(logger): _lgr = logger diff --git a/addons/gut/strutils.gd b/addons/gut/strutils.gd index cda12d1..2a3af8a 100644 --- a/addons/gut/strutils.gd +++ b/addons/gut/strutils.gd @@ -1,57 +1,59 @@ class_name GutStringUtils -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() # Hash containing all the built in types in Godot. This provides an English # name for the types that corosponds with the type constants defined in the # engine. var types = {} + func _init_types_dictionary(): - types[TYPE_NIL] = 'TYPE_NIL' - types[TYPE_BOOL] = 'Bool' - types[TYPE_INT] = 'Int' - types[TYPE_FLOAT] = 'Float/Real' - types[TYPE_STRING] = 'String' - types[TYPE_VECTOR2] = 'Vector2' - types[TYPE_RECT2] = 'Rect2' - types[TYPE_VECTOR3] = 'Vector3' + types[TYPE_NIL] = "TYPE_NIL" + types[TYPE_BOOL] = "Bool" + types[TYPE_INT] = "Int" + types[TYPE_FLOAT] = "Float/Real" + types[TYPE_STRING] = "String" + types[TYPE_VECTOR2] = "Vector2" + types[TYPE_RECT2] = "Rect2" + types[TYPE_VECTOR3] = "Vector3" #types[8] = 'Matrix32' - types[TYPE_PLANE] = 'Plane' - types[TYPE_QUATERNION] = 'QUAT' - types[TYPE_AABB] = 'AABB' + types[TYPE_PLANE] = "Plane" + types[TYPE_QUATERNION] = "QUAT" + types[TYPE_AABB] = "AABB" #types[12] = 'Matrix3' - types[TYPE_TRANSFORM3D] = 'Transform3D' - types[TYPE_COLOR] = 'Color' + types[TYPE_TRANSFORM3D] = "Transform3D" + types[TYPE_COLOR] = "Color" #types[15] = 'Image' - types[TYPE_NODE_PATH] = 'Node Path3D' - types[TYPE_RID] = 'RID' - types[TYPE_OBJECT] = 'TYPE_OBJECT' + types[TYPE_NODE_PATH] = "Node Path3D" + types[TYPE_RID] = "RID" + types[TYPE_OBJECT] = "TYPE_OBJECT" #types[19] = 'TYPE_INPUT_EVENT' - types[TYPE_DICTIONARY] = 'Dictionary' - types[TYPE_ARRAY] = 'Array' - types[TYPE_PACKED_BYTE_ARRAY] = 'TYPE_PACKED_BYTE_ARRAY' - types[TYPE_PACKED_INT32_ARRAY] = 'TYPE_PACKED_INT32_ARRAY' - types[TYPE_PACKED_FLOAT32_ARRAY] = 'TYPE_PACKED_FLOAT32_ARRAY' - types[TYPE_PACKED_STRING_ARRAY] = 'TYPE_PACKED_STRING_ARRAY' - types[TYPE_PACKED_VECTOR2_ARRAY] = 'TYPE_PACKED_VECTOR2_ARRAY' - types[TYPE_PACKED_VECTOR3_ARRAY] = 'TYPE_PACKED_VECTOR3_ARRAY' - types[TYPE_PACKED_COLOR_ARRAY] = 'TYPE_PACKED_COLOR_ARRAY' - types[TYPE_MAX] = 'TYPE_MAX' - types[TYPE_STRING_NAME] = 'TYPE_STRING_NAME' + types[TYPE_DICTIONARY] = "Dictionary" + types[TYPE_ARRAY] = "Array" + types[TYPE_PACKED_BYTE_ARRAY] = "TYPE_PACKED_BYTE_ARRAY" + types[TYPE_PACKED_INT32_ARRAY] = "TYPE_PACKED_INT32_ARRAY" + types[TYPE_PACKED_FLOAT32_ARRAY] = "TYPE_PACKED_FLOAT32_ARRAY" + types[TYPE_PACKED_STRING_ARRAY] = "TYPE_PACKED_STRING_ARRAY" + types[TYPE_PACKED_VECTOR2_ARRAY] = "TYPE_PACKED_VECTOR2_ARRAY" + types[TYPE_PACKED_VECTOR3_ARRAY] = "TYPE_PACKED_VECTOR3_ARRAY" + types[TYPE_PACKED_COLOR_ARRAY] = "TYPE_PACKED_COLOR_ARRAY" + types[TYPE_MAX] = "TYPE_MAX" + types[TYPE_STRING_NAME] = "TYPE_STRING_NAME" + # Types to not be formatted when using _str -var _str_ignore_types = [ - TYPE_INT, TYPE_FLOAT, TYPE_STRING, - TYPE_NIL, TYPE_BOOL -] +var _str_ignore_types = [TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_NIL, TYPE_BOOL] + func _init(): _init_types_dictionary() + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func _get_filename(path): - return path.split('/')[-1] + return path.split("/")[-1] + # ------------------------------------------------------------------------------ # Gets the filename of an object passed in. This does not return the @@ -60,29 +62,32 @@ func _get_filename(path): func _get_obj_filename(thing): var filename = null - if(thing == null or - _utils.is_native_class(thing) or - !is_instance_valid(thing) or - str(thing) == '' or - typeof(thing) != TYPE_OBJECT or - _utils.is_double(thing)): + if ( + thing == null + or _utils.is_native_class(thing) + or !is_instance_valid(thing) + or str(thing) == "" + or typeof(thing) != TYPE_OBJECT + or _utils.is_double(thing) + ): return - if(thing.get_script() == null): - if(thing is PackedScene): + if thing.get_script() == null: + if thing is PackedScene: filename = _get_filename(thing.resource_path) else: # If it isn't a packed scene and it doesn't have a script then # we do nothing. This just reads better. pass - elif(!_utils.is_native_class(thing)): + elif !_utils.is_native_class(thing): var dict = inst_to_dict(thing) - filename = _get_filename(dict['@path']) - if(str(dict['@subpath']) != ''): - filename += str('/', dict['@subpath']) + filename = _get_filename(dict["@path"]) + if str(dict["@subpath"]) != "": + filename += str("/", dict["@subpath"]) return filename + # ------------------------------------------------------------------------------ # Better object/thing to string conversion. Includes extra details about # whatever is passed in when it can/should. @@ -91,49 +96,50 @@ func type2str(thing): var filename = _get_obj_filename(thing) var str_thing = str(thing) - if(thing == null): + if thing == null: # According to str there is a difference between null and an Object # that is somehow null. To avoid getting '[Object:null]' as output # always set it to str(null) instead of str(thing). A null object # will pass typeof(thing) == TYPE_OBJECT check so this has to be # before that. str_thing = str(null) - elif(typeof(thing) == TYPE_FLOAT): - if(!'.' in str_thing): - str_thing += '.0' - elif(typeof(thing) == TYPE_STRING): + elif typeof(thing) == TYPE_FLOAT: + if !"." in str_thing: + str_thing += ".0" + elif typeof(thing) == TYPE_STRING: str_thing = str('"', thing, '"') - elif(typeof(thing) in _str_ignore_types): + elif typeof(thing) in _str_ignore_types: # do nothing b/c we already have str(thing) in # to_return. I think this just reads a little # better this way. pass - elif(typeof(thing) == TYPE_OBJECT): - if(_utils.is_native_class(thing)): + elif typeof(thing) == TYPE_OBJECT: + if _utils.is_native_class(thing): str_thing = _utils.get_native_class_name(thing) - elif(_utils.is_double(thing)): + elif _utils.is_double(thing): var double_path = _get_filename(thing.__gutdbl.thepath) - if(thing.__gutdbl.subpath != ''): - double_path += str('/', thing.__gutdbl.subpath) - elif(thing.__gutdbl.from_singleton != ''): + if thing.__gutdbl.subpath != "": + double_path += str("/", thing.__gutdbl.subpath) + elif thing.__gutdbl.from_singleton != "": double_path = thing.__gutdbl.from_singleton + " Singleton" var double_type = "double" - if(thing.__gutdbl.is_partial): + if thing.__gutdbl.is_partial: double_type = "partial-double" str_thing += str("(", double_type, " of ", double_path, ")") filename = null - elif(types.has(typeof(thing))): - if(!str_thing.begins_with('(')): - str_thing = '(' + str_thing + ')' + elif types.has(typeof(thing)): + if !str_thing.begins_with("("): + str_thing = "(" + str_thing + ")" str_thing = str(types[typeof(thing)], str_thing) - if(filename != null): - str_thing += str('(', filename, ')') + if filename != null: + str_thing += str("(", filename, ")") return str_thing + # ------------------------------------------------------------------------------ # Returns the string truncated with an '...' in it. Shows the start and last # 10 chars. If the string is smaller than max_size the entire string is @@ -141,28 +147,31 @@ func type2str(thing): # ------------------------------------------------------------------------------ func truncate_string(src, max_size): var to_return = src - if(src.length() > max_size - 10 and max_size != -1): - to_return = str(src.substr(0, max_size - 10), '...', src.substr(src.length() - 10, src.length())) + if src.length() > max_size - 10 and max_size != -1: + to_return = str( + src.substr(0, max_size - 10), "...", src.substr(src.length() - 10, src.length()) + ) return to_return func _get_indent_text(times, pad): - var to_return = '' + var to_return = "" for i in range(times): to_return += pad return to_return + func indent_text(text, times, pad): - if(times == 0): + if times == 0: return text var to_return = text - var ending_newline = '' + var ending_newline = "" - if(text.ends_with("\n")): + if text.ends_with("\n"): ending_newline = "\n" - to_return = to_return.left(to_return.length() -1) + to_return = to_return.left(to_return.length() - 1) var padding = _get_indent_text(times, pad) to_return = to_return.replace("\n", "\n" + padding) diff --git a/addons/gut/stub_params.gd b/addons/gut/stub_params.gd index bacfe8c..1b9f4c2 100644 --- a/addons/gut/stub_params.gd +++ b/addons/gut/stub_params.gd @@ -1,4 +1,4 @@ -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _lgr = _utils.get_logger() var return_val = null @@ -27,39 +27,42 @@ var parameter_defaults = null var _parameter_override_only = true # -- -const NOT_SET = '|_1_this_is_not_set_1_|' +const NOT_SET = "|_1_this_is_not_set_1_|" -func _init(target=null,method=null,subpath=null): + +func _init(target = null, method = null, subpath = null): stub_target = target stub_method = method - if(typeof(target) == TYPE_STRING): - if(target.is_absolute_path()): + if typeof(target) == TYPE_STRING: + if target.is_absolute_path(): stub_target = load(str(target)) else: - _lgr.warn(str(target, ' is not a valid path')) + _lgr.warn(str(target, " is not a valid path")) - if(stub_target is PackedScene): + if stub_target is PackedScene: stub_target = _utils.get_scene_script_object(stub_target) - elif(_utils.is_native_class(stub_target)): + elif _utils.is_native_class(stub_target): print("Got a native class: ", stub_target) # this is used internally to stub default parameters for everything that is # doubled...or something. Look for stub_defaults_from_meta for usage. This # behavior is not to be used by end users. - if(typeof(method) == TYPE_DICTIONARY): + if typeof(method) == TYPE_DICTIONARY: _load_defaults_from_metadata(method) + func _load_defaults_from_metadata(meta): stub_method = meta.name var values = meta.default_args.duplicate() - while (values.size() < meta.args.size()): + while values.size() < meta.args.size(): values.push_front(null) param_defaults(values) + func to_return(val): - if(stub_method == '_init'): + if stub_method == "_init": _lgr.error("You cannot stub _init to do nothing. Super's _init is always called.") else: return_val = val @@ -74,7 +77,7 @@ func to_do_nothing(): func to_call_super(): - if(stub_method == '_init'): + if stub_method == "_init": _lgr.error("You cannot stub _init to call super. Super's _init is always called.") else: call_super = true @@ -82,11 +85,22 @@ func to_call_super(): return self -func when_passed(p1=NOT_SET,p2=NOT_SET,p3=NOT_SET,p4=NOT_SET,p5=NOT_SET,p6=NOT_SET,p7=NOT_SET,p8=NOT_SET,p9=NOT_SET,p10=NOT_SET): - parameters = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10] +func when_passed( + p1 = NOT_SET, + p2 = NOT_SET, + p3 = NOT_SET, + p4 = NOT_SET, + p5 = NOT_SET, + p6 = NOT_SET, + p7 = NOT_SET, + p8 = NOT_SET, + p9 = NOT_SET, + p10 = NOT_SET +): + parameters = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] var idx = 0 - while(idx < parameters.size()): - if(str(parameters[idx]) == NOT_SET): + while idx < parameters.size(): + if str(parameters[idx]) == NOT_SET: parameters.remove_at(idx) else: idx += 1 @@ -110,28 +124,30 @@ func has_param_override(): func is_param_override_only(): var to_return = false - if(has_param_override()): + if has_param_override(): to_return = _parameter_override_only return to_return func to_s(): - var base_string = str(stub_target, '.', stub_method) + var base_string = str(stub_target, ".", stub_method) - if(has_param_override()): - base_string += str(' (param count override=', parameter_count, ' defaults=', parameter_defaults) - if(is_param_override_only()): + if has_param_override(): + base_string += str( + " (param count override=", parameter_count, " defaults=", parameter_defaults + ) + if is_param_override_only(): base_string += " ONLY" - if(is_script_default): + if is_script_default: base_string += " script default" - base_string += ') ' + base_string += ") " - if(call_super): + if call_super: base_string += " to call SUPER" - if(parameters != null): - base_string += str(' with params (', parameters, ') returns ', return_val) + if parameters != null: + base_string += str(" with params (", parameters, ") returns ", return_val) else: - base_string += str(' returns ', return_val) + base_string += str(" returns ", return_val) return base_string diff --git a/addons/gut/stubber.gd b/addons/gut/stubber.gd index ec67383..6b787b4 100644 --- a/addons/gut/stubber.gd +++ b/addons/gut/stubber.gd @@ -12,14 +12,16 @@ # } # } var returns = {} -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _lgr = _utils.get_logger() var _strutils = _utils.Strutils.new() var _class_db_name_hash = {} + func _init(): _class_db_name_hash = _make_crazy_dynamic_over_engineered_class_db_hash() + # So, I couldn't figure out how to get to a reference for a GDNative Class # using a string. ClassDB has all thier names...so I made a hash using those # names and the classes. Then I dynmaically make a script that has that as @@ -28,12 +30,12 @@ func _init(): func _make_crazy_dynamic_over_engineered_class_db_hash(): var text = "var all_the_classes = {\n" for classname in ClassDB.get_class_list(): - if(ClassDB.can_instantiate(classname)): + if ClassDB.can_instantiate(classname): text += str('"', classname, '": ', classname, ", \n") else: - text += str('# ', classname, "\n") + text += str("# ", classname, "\n") text += "}" - var inst = _utils.create_script_from_source(text).new() + var inst = _utils.create_script_from_source(text).new() return inst.all_the_classes @@ -44,27 +46,27 @@ func _find_matches(obj, method): # Search for what is passed in first. This could be a class or an instance. # We want to find the instance before we find the class. If we do not have # an entry for the instance then see if we have an entry for the class. - if(returns.has(obj) and returns[obj].has(method)): + if returns.has(obj) and returns[obj].has(method): matches = returns[obj][method] - elif(_utils.is_instance(obj)): + elif _utils.is_instance(obj): var parent = obj.get_script() var found = false - while(parent != null and !found): + while parent != null and !found: found = returns.has(parent) - if(!found): + if !found: last_not_null_parent = parent parent = parent.get_base_script() # Could not find the script so check to see if a native class of this # type was stubbed. - if(!found): + if !found: var base_type = last_not_null_parent.get_instance_base_type() - if(_class_db_name_hash.has(base_type)): + if _class_db_name_hash.has(base_type): parent = _class_db_name_hash[base_type] found = returns.has(parent) - if(found and returns[parent].has(method)): + if found and returns[parent].has(method): matches = returns[parent][method] return matches @@ -74,11 +76,11 @@ func _find_matches(obj, method): # passed in obj is. # # obj can be an instance, class, or a path. -func _find_stub(obj, method, parameters=null, find_overloads=false): +func _find_stub(obj, method, parameters = null, find_overloads = false): var to_return = null var matches = _find_matches(obj, method) - if(matches == null): + if matches == null: return null var param_match = null @@ -87,43 +89,43 @@ func _find_stub(obj, method, parameters=null, find_overloads=false): for i in range(matches.size()): var cur_stub = matches[i] - if(cur_stub.parameters == parameters): + if cur_stub.parameters == parameters: param_match = cur_stub - if(cur_stub.parameters == null and !cur_stub.is_param_override_only()): + if cur_stub.parameters == null and !cur_stub.is_param_override_only(): null_match = cur_stub - if(cur_stub.has_param_override()): - if(overload_match == null || overload_match.is_script_default): + if cur_stub.has_param_override(): + if overload_match == null || overload_match.is_script_default: overload_match = cur_stub - if(find_overloads and overload_match != null): + if find_overloads and overload_match != null: to_return = overload_match # We have matching parameter values so return the stub value for that - elif(param_match != null): + elif param_match != null: to_return = param_match # We found a case where the parameters were not specified so return # parameters for that. Only do this if the null match is not *just* # a paramerter override stub. - elif(null_match != null): + elif null_match != null: to_return = null_match return to_return - # ############## # Public # ############## + func add_stub(stub_params): stub_params._lgr = _lgr var key = stub_params.stub_target - if(!returns.has(key)): + if !returns.has(key): returns[key] = {} - if(!returns[key].has(stub_params.stub_method)): + if !returns[key].has(stub_params.stub_method): returns[key][stub_params.stub_method] = [] returns[key][stub_params.stub_method].append(stub_params) @@ -144,34 +146,42 @@ func add_stub(stub_params): # obj: this should be an instance of a doubled object. # method: the method called # parameters: optional array of parameter vales to find a return value for. -func get_return(obj, method, parameters=null): +func get_return(obj, method, parameters = null): var stub_info = _find_stub(obj, method, parameters) - if(stub_info != null): + if stub_info != null: return stub_info.return_val else: - _lgr.warn(str('Call to [', method, '] was not stubbed for the supplied parameters ', parameters, '. Null was returned.')) + _lgr.warn( + str( + "Call to [", + method, + "] was not stubbed for the supplied parameters ", + parameters, + ". Null was returned." + ) + ) return null -func should_call_super(obj, method, parameters=null): - if(_utils.non_super_methods.has(method)): +func should_call_super(obj, method, parameters = null): + if _utils.non_super_methods.has(method): return false var stub_info = _find_stub(obj, method, parameters) var is_partial = false - if(typeof(obj) != TYPE_STRING): # some stubber tests test with strings + if typeof(obj) != TYPE_STRING: # some stubber tests test with strings is_partial = obj.__gutdbl.is_partial var should = is_partial - if(stub_info != null): + if stub_info != null: should = stub_info.call_super - elif(!is_partial): + elif !is_partial: # this log message is here because of how the generated doubled scripts # are structured. With this log msg here, you will only see one # "unstubbed" info instead of multiple. - _lgr.info('Unstubbed call to ' + method + '::' + _strutils.type2str(obj)) + _lgr.info("Unstubbed call to " + method + "::" + _strutils.type2str(obj)) should = false return should @@ -181,7 +191,7 @@ func get_parameter_count(obj, method): var to_return = null var stub_info = _find_stub(obj, method, null, true) - if(stub_info != null and stub_info.has_param_override()): + if stub_info != null and stub_info.has_param_override(): to_return = stub_info.parameter_count return to_return @@ -191,10 +201,11 @@ func get_default_value(obj, method, p_index): var to_return = null var stub_info = _find_stub(obj, method, null, true) - if(stub_info != null and - stub_info.parameter_defaults != null and - stub_info.parameter_defaults.size() > p_index): - + if ( + stub_info != null + and stub_info.parameter_defaults != null + and stub_info.parameter_defaults.size() > p_index + ): to_return = stub_info.parameter_defaults[p_index] return to_return @@ -213,7 +224,7 @@ func set_logger(logger): func to_s(): - var text = '' + var text = "" for thing in returns: text += str("-- ", thing, " --\n") for method in returns[thing]: @@ -221,8 +232,8 @@ func to_s(): for i in range(returns[thing][method].size()): text += "\t\t" + returns[thing][method][i].to_s() + "\n" - if(text == ''): - text = 'Stubber is empty'; + if text == "": + text = "Stubber is empty" return text @@ -230,4 +241,4 @@ func to_s(): func stub_defaults_from_meta(target, method_meta): var params = _utils.StubParams.new(target, method_meta) params.is_script_default = true - add_stub(params) \ No newline at end of file + add_stub(params) diff --git a/addons/gut/summary.gd b/addons/gut/summary.gd index 5fd2d68..be8a5a6 100644 --- a/addons/gut/summary.gd +++ b/addons/gut/summary.gd @@ -28,37 +28,37 @@ class Test: func did_something(): return is_passing() or is_failing() or is_pending() - # NOTE: The "failed" and "pending" text must match what is outputted by # the logger in order for text highlighting to occur in summary. func to_s(): - var pad = ' ' - var to_return = '' + var pad = " " + var to_return = "" for i in range(fail_texts.size()): - to_return += str(pad, '[Failed]: ', fail_texts[i], "\n") + to_return += str(pad, "[Failed]: ", fail_texts[i], "\n") for i in range(pending_texts.size()): - to_return += str(pad, '[Pending]: ', pending_texts[i], "\n") + to_return += str(pad, "[Pending]: ", pending_texts[i], "\n") return to_return func get_status(): - var to_return = 'no asserts' - if(pending_texts.size() > 0): - to_return = 'pending' - elif(fail_texts.size() > 0): - to_return = 'fail' - elif(pass_texts.size() > 0): - to_return = 'pass' + var to_return = "no asserts" + if pending_texts.size() > 0: + to_return = "pending" + elif fail_texts.size() > 0: + to_return = "fail" + elif pass_texts.size() > 0: + to_return = "pass" return to_return + # ------------------------------------------------------------------------------ # Contains all the results for a single test-script/inner class. Persists the # names of the tests and results and the order in which the tests were run. # ------------------------------------------------------------------------------ class TestScript: - var name = 'NOT_SET' + var name = "NOT_SET" var was_skipped = false - var skip_reason = '' + var skip_reason = "" var _tests = {} var _test_order = [] @@ -86,30 +86,29 @@ class TestScript: func get_passing_test_count(): var count = 0 for key in _tests: - if(_tests[key].is_passing()): + if _tests[key].is_passing(): count += 1 return count func get_failing_test_count(): var count = 0 for key in _tests: - if(_tests[key].is_failing()): + if _tests[key].is_failing(): count += 1 return count func get_risky_count(): var count = 0 - if(was_skipped): + if was_skipped: count = 1 else: for key in _tests: - if(!_tests[key].did_something()): + if !_tests[key].did_something(): count += 1 return count - func get_test_obj(obj_name): - if(!_tests.has(obj_name)): + if !_tests.has(obj_name): var to_add = Test.new() _tests[obj_name] = to_add _test_order.append(obj_name) @@ -133,6 +132,7 @@ class TestScript: func get_tests(): return _tests + # ------------------------------------------------------------------------------ # Summary Class # @@ -141,47 +141,57 @@ class TestScript: # ------------------------------------------------------------------------------ var _scripts = [] + func add_script(name): _scripts.append(TestScript.new(name)) + func get_scripts(): return _scripts + func get_current_script(): return _scripts[_scripts.size() - 1] + func add_test(test_name): # print('-- test_name = ', test_name) # print('-- current script = ', get_current_script()) # print('-- test_obj = ', get_current_script().get_test_obj(test_name)) return get_current_script().get_test_obj(test_name) -func add_pass(test_name, reason = ''): + +func add_pass(test_name, reason = ""): get_current_script().add_pass(test_name, reason) -func add_fail(test_name, reason = ''): + +func add_fail(test_name, reason = ""): get_current_script().add_fail(test_name, reason) -func add_pending(test_name, reason = ''): + +func add_pending(test_name, reason = ""): get_current_script().add_pending(test_name, reason) + func get_test_text(test_name): return test_name + "\n" + get_current_script().get_test_obj(test_name).to_s() + # Gets the count of unique script names minus the . at the # end. Used for displaying the number of scripts without including all the # Inner Classes. func get_non_inner_class_script_count(): - var counter = load('res://addons/gut/thing_counter.gd').new() + var counter = load("res://addons/gut/thing_counter.gd").new() for i in range(_scripts.size()): - var ext_loc = _scripts[i].name.rfind('.gd.') + var ext_loc = _scripts[i].name.rfind(".gd.") var to_add = _scripts[i].name - if(ext_loc != -1): + if ext_loc != -1: to_add = _scripts[i].name.substr(0, ext_loc + 3) counter.add(to_add) return counter.get_unique_count() + func get_totals(): var totals = { passing = 0, @@ -217,34 +227,38 @@ func log_summary_text(lgr): for s in range(_scripts.size()): lgr.set_indent_level(0) - if(_scripts[s].was_skipped or _scripts[s].get_fail_count() > 0 or _scripts[s].get_pending_count() > 0): + if ( + _scripts[s].was_skipped + or _scripts[s].get_fail_count() > 0 + or _scripts[s].get_pending_count() > 0 + ): lgr.log(_scripts[s].name, lgr.fmts.underline) - if(_scripts[s].was_skipped): + if _scripts[s].was_skipped: lgr.inc_indent() - var skip_msg = str('[Risky] Script was skipped: ', _scripts[s].skip_reason) + var skip_msg = str("[Risky] Script was skipped: ", _scripts[s].skip_reason) lgr.log(skip_msg, lgr.fmts.yellow) lgr.dec_indent() for t in range(_scripts[s]._test_order.size()): var tname = _scripts[s]._test_order[t] var test = _scripts[s].get_test_obj(tname) - if(!test.is_passing()): + if !test.is_passing(): found_failing_or_pending = true - lgr.log(str('- ', tname)) + lgr.log(str("- ", tname)) lgr.inc_indent() for i in range(test.fail_texts.size()): lgr.failed(test.fail_texts[i]) for i in range(test.pending_texts.size()): lgr.pending(test.pending_texts[i]) - if(!test.did_something()): - lgr.log('[Risky] Did not assert', lgr.fmts.yellow) + if !test.did_something(): + lgr.log("[Risky] Did not assert", lgr.fmts.yellow) lgr.dec_indent() lgr.set_indent_level(0) - if(!found_failing_or_pending): - lgr.log('All tests passed', lgr.fmts.green) + if !found_failing_or_pending: + lgr.log("All tests passed", lgr.fmts.green) # just picked a non-printable char, dunno if it is a good or bad choice. var npws = PackedByteArray([31]).get_string_from_ascii() @@ -252,15 +266,22 @@ func log_summary_text(lgr): lgr.log() var _totals = get_totals() lgr.log("Totals", lgr.fmts.yellow) - lgr.log(str('Scripts: ', get_non_inner_class_script_count())) - lgr.log(str('Passing tests ', _totals.passing_tests)) - lgr.log(str('Failing tests ', _totals.failing_tests)) - lgr.log(str('Risky tests ', _totals.risky)) - var pnd=str('Pending: ', _totals.pending) + lgr.log(str("Scripts: ", get_non_inner_class_script_count())) + lgr.log(str("Passing tests ", _totals.passing_tests)) + lgr.log(str("Failing tests ", _totals.failing_tests)) + lgr.log(str("Risky tests ", _totals.risky)) + var pnd = str("Pending: ", _totals.pending) # add a non printable character so this "pending" isn't highlighted in the # editor's output panel. lgr.log(str(npws, pnd)) - lgr.log(str('Asserts: ', _totals.passing, ' of ', _totals.passing + _totals.failing, ' passed')) + lgr.log( + str( + "Asserts: ", + _totals.passing, + " of ", + _totals.passing + _totals.failing, + " passed" + ) + ) lgr.set_indent_level(orig_indent) - diff --git a/addons/gut/test.gd b/addons/gut/test.gd index bd2cb99..dd2af31 100644 --- a/addons/gut/test.gd +++ b/addons/gut/test.gd @@ -38,11 +38,9 @@ class_name GutTest # ############################################################################## extends Node - -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _compare = _utils.Comparator.new() - # Need a reference to the instance that is running the tests. This # is set by the gut class when it runs the tests. This gets you # access to the asserts in the tests you write. @@ -57,16 +55,10 @@ const EDITOR_PROPERTY = PROPERTY_USAGE_SCRIPT_VARIABLE | PROPERTY_USAGE_DEFAULT const VARIABLE_PROPERTY = PROPERTY_USAGE_SCRIPT_VARIABLE # Summary counts for the test. -var _summary = { - asserts = 0, - passed = 0, - failed = 0, - tests = 0, - pending = 0 -} +var _summary = {asserts = 0, passed = 0, failed = 0, tests = 0, pending = 0} # This is used to watch signals so we can make assertions about them. -var _signal_watcher = load('res://addons/gut/signal_watcher.gd').new() +var _signal_watcher = load("res://addons/gut/signal_watcher.gd").new() # Convenience copy of _utils.DOUBLE_STRATEGY var DOUBLE_STRATEGY = _utils.DOUBLE_STRATEGY @@ -80,6 +72,7 @@ var CompareResult = _utils.CompareResult var InputFactory = _utils.InputFactory var InputSender = _utils.InputSender + func _init(): pass @@ -87,28 +80,31 @@ func _init(): func _str(thing): return _strutils.type2str(thing) + # ------------------------------------------------------------------------------ # Fail an assertion. Causes test and script to fail as well. # ------------------------------------------------------------------------------ func _fail(text): _summary.asserts += 1 _summary.failed += 1 - _fail_pass_text.append('failed: ' + text) - if(gut): + _fail_pass_text.append("failed: " + text) + if gut: _lgr.failed(text) gut._fail(text) + # ------------------------------------------------------------------------------ # Pass an assertion. # ------------------------------------------------------------------------------ func _pass(text): _summary.asserts += 1 _summary.passed += 1 - _fail_pass_text.append('passed: ' + text) - if(gut): + _fail_pass_text.append("passed: " + text) + if gut: _lgr.passed(text) gut._pass(text) + # ------------------------------------------------------------------------------ # Checks if the datatypes passed in match. If they do not then this will cause # a fail to occur. If they match then TRUE is returned, FALSE if not. This is @@ -117,30 +113,52 @@ func _pass(text): func _do_datatypes_match__fail_if_not(got, expected, text): var did_pass = true - if(!_disable_strict_datatype_checks): + if !_disable_strict_datatype_checks: var got_type = typeof(got) var expect_type = typeof(expected) - if(got_type != expect_type and got != null and expected != null): + if got_type != expect_type and got != null and expected != null: # If we have a mismatch between float and int (types 2 and 3) then # print out a warning but do not fail. - if([2, 3].has(got_type) and [2, 3].has(expect_type)): - _lgr.warn(str('Warn: Float/Int comparison. Got ', _strutils.types[got_type], - ' but expected ', _strutils.types[expect_type])) - elif([TYPE_STRING, TYPE_STRING_NAME].has(got_type) and [TYPE_STRING, TYPE_STRING_NAME].has(expect_type)): + if [2, 3].has(got_type) and [2, 3].has(expect_type): + _lgr.warn( + str( + "Warn: Float/Int comparison. Got ", + _strutils.types[got_type], + " but expected ", + _strutils.types[expect_type] + ) + ) + elif ( + [TYPE_STRING, TYPE_STRING_NAME].has(got_type) + and [TYPE_STRING, TYPE_STRING_NAME].has(expect_type) + ): pass else: - _fail('Cannot compare ' + _strutils.types[got_type] + '[' + _str(got) + '] to ' + \ - _strutils.types[expect_type] + '[' + _str(expected) + ']. ' + text) + _fail( + ( + "Cannot compare " + + _strutils.types[got_type] + + "[" + + _str(got) + + "] to " + + _strutils.types[expect_type] + + "[" + + _str(expected) + + "]. " + + text + ) + ) did_pass = false return did_pass + # ------------------------------------------------------------------------------ # Create a string that lists all the methods that were called on an spied # instance. # ------------------------------------------------------------------------------ func _get_desc_of_calls_to_instance(inst): - var BULLET = ' * ' + var BULLET = " * " var calls = gut.get_spy().get_call_list_as_string(inst) # indent all the calls calls = BULLET + calls.replace("\n", "\n" + BULLET) @@ -148,33 +166,42 @@ func _get_desc_of_calls_to_instance(inst): calls = calls.substr(0, calls.length() - BULLET.length() - 1) return "Calls made on " + str(inst) + "\n" + calls + # ------------------------------------------------------------------------------ # Signal assertion helper. Do not call directly, use _can_make_signal_assertions # ------------------------------------------------------------------------------ func _fail_if_does_not_have_signal(object, signal_name): var did_fail = false - if(!_signal_watcher.does_object_have_signal(object, signal_name)): - _fail(str('Object ', object, ' does not have the signal [', signal_name, ']')) + if !_signal_watcher.does_object_have_signal(object, signal_name): + _fail(str("Object ", object, " does not have the signal [", signal_name, "]")) did_fail = true return did_fail + # ------------------------------------------------------------------------------ # Signal assertion helper. Do not call directly, use _can_make_signal_assertions # ------------------------------------------------------------------------------ func _fail_if_not_watching(object): var did_fail = false - if(!_signal_watcher.is_watching_object(object)): - _fail(str('Cannot make signal assertions because the object ', object, \ - ' is not being watched. Call watch_signals(some_object) to be able to make assertions about signals.')) + if !_signal_watcher.is_watching_object(object): + _fail( + str( + "Cannot make signal assertions because the object ", + object, + " is not being watched. Call watch_signals(some_object) to be able to make assertions about signals." + ) + ) did_fail = true return did_fail + # ------------------------------------------------------------------------------ # Returns text that contains original text and a list of all the signals that # were emitted for the passed in object. # ------------------------------------------------------------------------------ func _get_fail_msg_including_emitted_signals(text, object): - return str(text," (Signals emitted: ", _signal_watcher.get_signals_emitted(object), ")") + return str(text, " (Signals emitted: ", _signal_watcher.get_signals_emitted(object), ")") + # ------------------------------------------------------------------------------ # This validates that parameters is an array and generates a specific error @@ -182,9 +209,9 @@ func _get_fail_msg_including_emitted_signals(text, object): # ------------------------------------------------------------------------------ func _fail_if_parameters_not_array(parameters): var invalid = parameters != null and typeof(parameters) != TYPE_ARRAY - if(invalid): + if invalid: _lgr.error('The "parameters" parameter must be an array of expected parameter values.') - _fail('Cannot compare paramter values because an array was not passed.') + _fail("Cannot compare paramter values because an array was not passed.") return invalid @@ -202,29 +229,36 @@ func _create_obj_from_type(type): # Virtual Methods # ####################### + # alias for prerun_setup func before_all(): pass + # alias for setup func before_each(): pass + # alias for postrun_teardown func after_all(): pass + # alias for teardown func after_each(): pass + # ####################### # Public # ####################### + func get_logger(): return _lgr + func set_logger(logger): _lgr = logger @@ -233,24 +267,24 @@ func set_logger(logger): # Asserts # ####################### + # ------------------------------------------------------------------------------ # Asserts that the expected value equals the value got. # ------------------------------------------------------------------------------ -func assert_eq(got, expected, text=""): - - if(_do_datatypes_match__fail_if_not(got, expected, text)): +func assert_eq(got, expected, text = ""): + if _do_datatypes_match__fail_if_not(got, expected, text): var disp = "[" + _str(got) + "] expected to equal [" + _str(expected) + "]: " + text var result = null - if(typeof(got) == TYPE_ARRAY): + if typeof(got) == TYPE_ARRAY: result = _compare.shallow(got, expected) else: result = _compare.simple(got, expected) - if(typeof(got) in [TYPE_ARRAY, TYPE_DICTIONARY]): - disp = str(result.summary, ' ', text) + if typeof(got) in [TYPE_ARRAY, TYPE_DICTIONARY]: + disp = str(result.summary, " ", text) - if(result.are_equal): + if result.are_equal: _pass(disp) else: _fail(disp) @@ -259,20 +293,22 @@ func assert_eq(got, expected, text=""): # ------------------------------------------------------------------------------ # Asserts that the value got does not equal the "not expected" value. # ------------------------------------------------------------------------------ -func assert_ne(got, not_expected, text=""): - if(_do_datatypes_match__fail_if_not(got, not_expected, text)): - var disp = "[" + _str(got) + "] expected to not equal [" + _str(not_expected) + "]: " + text +func assert_ne(got, not_expected, text = ""): + if _do_datatypes_match__fail_if_not(got, not_expected, text): + var disp = ( + "[" + _str(got) + "] expected to not equal [" + _str(not_expected) + "]: " + text + ) var result = null - if(typeof(got) == TYPE_ARRAY): + if typeof(got) == TYPE_ARRAY: result = _compare.shallow(got, not_expected) else: result = _compare.simple(got, not_expected) - if(typeof(got) in [TYPE_ARRAY, TYPE_DICTIONARY]): - disp = str(result.summary, ' ', text) + if typeof(got) in [TYPE_ARRAY, TYPE_DICTIONARY]: + disp = str(result.summary, " ", text) - if(result.are_equal): + if result.are_equal: _fail(disp) else: _pass(disp) @@ -281,25 +317,51 @@ func assert_ne(got, not_expected, text=""): # ------------------------------------------------------------------------------ # Asserts that the expected value almost equals the value got. # ------------------------------------------------------------------------------ -func assert_almost_eq(got, expected, error_interval, text=''): - var disp = "[" + _str(got) + "] expected to equal [" + _str(expected) + "] +/- [" + str(error_interval) + "]: " + text - if(_do_datatypes_match__fail_if_not(got, expected, text) and _do_datatypes_match__fail_if_not(got, error_interval, text)): +func assert_almost_eq(got, expected, error_interval, text = ""): + var disp = ( + "[" + + _str(got) + + "] expected to equal [" + + _str(expected) + + "] +/- [" + + str(error_interval) + + "]: " + + text + ) + if ( + _do_datatypes_match__fail_if_not(got, expected, text) + and _do_datatypes_match__fail_if_not(got, error_interval, text) + ): if not _is_almost_eq(got, expected, error_interval): _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Asserts that the expected value does not almost equal the value got. # ------------------------------------------------------------------------------ -func assert_almost_ne(got, not_expected, error_interval, text=''): - var disp = "[" + _str(got) + "] expected to not equal [" + _str(not_expected) + "] +/- [" + str(error_interval) + "]: " + text - if(_do_datatypes_match__fail_if_not(got, not_expected, text) and _do_datatypes_match__fail_if_not(got, error_interval, text)): +func assert_almost_ne(got, not_expected, error_interval, text = ""): + var disp = ( + "[" + + _str(got) + + "] expected to not equal [" + + _str(not_expected) + + "] +/- [" + + str(error_interval) + + "]: " + + text + ) + if ( + _do_datatypes_match__fail_if_not(got, not_expected, text) + and _do_datatypes_match__fail_if_not(got, error_interval, text) + ): if _is_almost_eq(got, not_expected, error_interval): _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Helper function which correctly compares two variables, # while properly handling vector2/3 types @@ -308,45 +370,57 @@ func _is_almost_eq(got, expected, error_interval) -> bool: var result = false if typeof(got) == TYPE_VECTOR2: if got.x >= (expected.x - error_interval.x) and got.x <= (expected.x + error_interval.x): - if got.y >= (expected.y - error_interval.y) and got.y <= (expected.y + error_interval.y): + if ( + got.y >= (expected.y - error_interval.y) + and got.y <= (expected.y + error_interval.y) + ): result = true elif typeof(got) == TYPE_VECTOR3: if got.x >= (expected.x - error_interval.x) and got.x <= (expected.x + error_interval.x): - if got.y >= (expected.y - error_interval.y) and got.y <= (expected.y + error_interval.y): - if got.z >= (expected.z - error_interval.z) and got.z <= (expected.z + error_interval.z): + if ( + got.y >= (expected.y - error_interval.y) + and got.y <= (expected.y + error_interval.y) + ): + if ( + got.z >= (expected.z - error_interval.z) + and got.z <= (expected.z + error_interval.z) + ): result = true - elif(got >= (expected - error_interval) and got <= (expected + error_interval)): + elif got >= (expected - error_interval) and got <= (expected + error_interval): result = true - return(result) + return result + # ------------------------------------------------------------------------------ # Asserts got is greater than expected # ------------------------------------------------------------------------------ -func assert_gt(got, expected, text=""): +func assert_gt(got, expected, text = ""): var disp = "[" + _str(got) + "] expected to be > than [" + _str(expected) + "]: " + text - if(_do_datatypes_match__fail_if_not(got, expected, text)): - if(got > expected): + if _do_datatypes_match__fail_if_not(got, expected, text): + if got > expected: _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Asserts got is less than expected # ------------------------------------------------------------------------------ -func assert_lt(got, expected, text=""): +func assert_lt(got, expected, text = ""): var disp = "[" + _str(got) + "] expected to be < than [" + _str(expected) + "]: " + text - if(_do_datatypes_match__fail_if_not(got, expected, text)): - if(got < expected): + if _do_datatypes_match__fail_if_not(got, expected, text): + if got < expected: _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # asserts that got is true # ------------------------------------------------------------------------------ -func assert_true(got, text=""): - if(typeof(got) == TYPE_BOOL): - if(got): +func assert_true(got, text = ""): + if typeof(got) == TYPE_BOOL: + if got: _pass(text) else: _fail(text) @@ -354,12 +428,13 @@ func assert_true(got, text=""): var msg = str("Cannot convert ", _strutils.type2str(got), " to boolean") _fail(msg) + # ------------------------------------------------------------------------------ # Asserts that got is false # ------------------------------------------------------------------------------ -func assert_false(got, text=""): - if(typeof(got) == TYPE_BOOL): - if(got): +func assert_false(got, text = ""): + if typeof(got) == TYPE_BOOL: + if got: _fail(text) else: _pass(text) @@ -367,105 +442,152 @@ func assert_false(got, text=""): var msg = str("Cannot convert ", _strutils.type2str(got), " to boolean") _fail(msg) + # ------------------------------------------------------------------------------ # Asserts value is between (inclusive) the two expected values. # ------------------------------------------------------------------------------ -func assert_between(got, expect_low, expect_high, text=""): - var disp = "[" + _str(got) + "] expected to be between [" + _str(expect_low) + "] and [" + str(expect_high) + "]: " + text +func assert_between(got, expect_low, expect_high, text = ""): + var disp = ( + "[" + + _str(got) + + "] expected to be between [" + + _str(expect_low) + + "] and [" + + str(expect_high) + + "]: " + + text + ) - if(_do_datatypes_match__fail_if_not(got, expect_low, text) and _do_datatypes_match__fail_if_not(got, expect_high, text)): - if(expect_low > expect_high): - disp = "INVALID range. [" + str(expect_low) + "] is not less than [" + str(expect_high) + "]" + if ( + _do_datatypes_match__fail_if_not(got, expect_low, text) + and _do_datatypes_match__fail_if_not(got, expect_high, text) + ): + if expect_low > expect_high: + disp = ( + "INVALID range. [" + + str(expect_low) + + "] is not less than [" + + str(expect_high) + + "]" + ) _fail(disp) else: - if(got < expect_low or got > expect_high): + if got < expect_low or got > expect_high: _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Asserts value is not between (exclusive) the two expected values. # ------------------------------------------------------------------------------ -func assert_not_between(got, expect_low, expect_high, text=""): - var disp = "[" + _str(got) + "] expected not to be between [" + _str(expect_low) + "] and [" + str(expect_high) + "]: " + text +func assert_not_between(got, expect_low, expect_high, text = ""): + var disp = ( + "[" + + _str(got) + + "] expected not to be between [" + + _str(expect_low) + + "] and [" + + str(expect_high) + + "]: " + + text + ) - if(_do_datatypes_match__fail_if_not(got, expect_low, text) and _do_datatypes_match__fail_if_not(got, expect_high, text)): - if(expect_low > expect_high): - disp = "INVALID range. [" + str(expect_low) + "] is not less than [" + str(expect_high) + "]" + if ( + _do_datatypes_match__fail_if_not(got, expect_low, text) + and _do_datatypes_match__fail_if_not(got, expect_high, text) + ): + if expect_low > expect_high: + disp = ( + "INVALID range. [" + + str(expect_low) + + "] is not less than [" + + str(expect_high) + + "]" + ) _fail(disp) else: - if(got > expect_low and got < expect_high): + if got > expect_low and got < expect_high: _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Uses the 'has' method of the object passed in to determine if it contains # the passed in element. # ------------------------------------------------------------------------------ -func assert_has(obj, element, text=""): - var disp = str('Expected [', _str(obj), '] to contain value: [', _str(element), ']: ', text) - if(obj.has(element)): +func assert_has(obj, element, text = ""): + var disp = str("Expected [", _str(obj), "] to contain value: [", _str(element), "]: ", text) + if obj.has(element): _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func assert_does_not_have(obj, element, text=""): - var disp = str('Expected [', _str(obj), '] to NOT contain value: [', _str(element), ']: ', text) - if(obj.has(element)): +func assert_does_not_have(obj, element, text = ""): + var disp = str( + "Expected [", _str(obj), "] to NOT contain value: [", _str(element), "]: ", text + ) + if obj.has(element): _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Asserts that a file exists # ------------------------------------------------------------------------------ func assert_file_exists(file_path): - var disp = 'expected [' + file_path + '] to exist.' - if(FileAccess.file_exists(file_path)): + var disp = "expected [" + file_path + "] to exist." + if FileAccess.file_exists(file_path): _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Asserts that a file should not exist # ------------------------------------------------------------------------------ func assert_file_does_not_exist(file_path): - var disp = 'expected [' + file_path + '] to NOT exist' - if(!FileAccess.file_exists(file_path)): + var disp = "expected [" + file_path + "] to NOT exist" + if !FileAccess.file_exists(file_path): _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Asserts the specified file is empty # ------------------------------------------------------------------------------ func assert_file_empty(file_path): - var disp = 'expected [' + file_path + '] to be empty' - if(FileAccess.file_exists(file_path) and gut.is_file_empty(file_path)): + var disp = "expected [" + file_path + "] to be empty" + if FileAccess.file_exists(file_path) and gut.is_file_empty(file_path): _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Asserts the specified file is not empty # ------------------------------------------------------------------------------ func assert_file_not_empty(file_path): - var disp = 'expected [' + file_path + '] to contain data' - if(!gut.is_file_empty(file_path)): + var disp = "expected [" + file_path + "] to contain data" + if !gut.is_file_empty(file_path): _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Asserts the object has the specified method # ------------------------------------------------------------------------------ -func assert_has_method(obj, method, text=''): - var disp = _str(obj) + ' should have method: ' + method - if(text != ''): - disp = _str(obj) + ' ' + text +func assert_has_method(obj, method, text = ""): + var disp = _str(obj) + " should have method: " + method + if text != "": + disp = _str(obj) + " " + text assert_true(obj.has_method(method), disp) @@ -478,20 +600,20 @@ func assert_has_method(obj, method, text=''): # ------------------------------------------------------------------------------ func assert_accessors(obj, property, default, set_to): var fail_count = _summary.failed - var get_func = 'get_' + property - var set_func = 'set_' + property + var get_func = "get_" + property + var set_func = "set_" + property - if(obj.has_method('is_' + property)): - get_func = 'is_' + property + if obj.has_method("is_" + property): + get_func = "is_" + property - assert_has_method(obj, get_func, 'should have getter starting with get_ or is_') + assert_has_method(obj, get_func, "should have getter starting with get_ or is_") assert_has_method(obj, set_func) # SHORT CIRCUIT - if(_summary.failed > fail_count): + if _summary.failed > fail_count: return - assert_eq(obj.call(get_func), default, 'It should have the expected default value.') + assert_eq(obj.call(get_func), default, "It should have the expected default value.") obj.call(set_func, set_to) - assert_eq(obj.call(get_func), set_to, 'The set value should have been returned.') + assert_eq(obj.call(get_func), set_to, "The set value should have been returned.") # --------------------------------------------------------------------------- @@ -502,34 +624,39 @@ func assert_accessors(obj, property, default, set_to): # EDITOR_PROPERTY for properties defined as: export var some_value: int # VARIABLE_PROPERTY for properties defined as: var another_value # --------------------------------------------------------------------------- -func _find_object_property(obj, property_name, property_usage=null): +func _find_object_property(obj, property_name, property_usage = null): var result = null var found = false var properties = obj.get_property_list() while !found and !properties.is_empty(): var property = properties.pop_back() - if property['name'] == property_name: - if property_usage == null or property['usage'] == property_usage: + if property["name"] == property_name: + if property_usage == null or property["usage"] == property_usage: result = property found = true return result + # ------------------------------------------------------------------------------ # Asserts a class exports a variable. # ------------------------------------------------------------------------------ func assert_exports(obj, property_name, type): - var disp = 'expected %s to have editor property [%s]' % [_str(obj), property_name] + var disp = "expected %s to have editor property [%s]" % [_str(obj), property_name] var property = _find_object_property(obj, property_name, EDITOR_PROPERTY) if property != null: - disp += ' of type [%s]. Got type [%s].' % [_strutils.types[type], _strutils.types[property['type']]] - if property['type'] == type: + disp += ( + " of type [%s]. Got type [%s]." + % [_strutils.types[type], _strutils.types[property["type"]]] + ) + if property["type"] == type: _pass(disp) else: _fail(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Signal assertion helper. # @@ -540,19 +667,25 @@ func assert_exports(obj, property_name, type): func _can_make_signal_assertions(object, signal_name): return !(_fail_if_not_watching(object) or _fail_if_does_not_have_signal(object, signal_name)) + # ------------------------------------------------------------------------------ # Check if an object is connected to a signal on another object. Returns True # if it is and false otherwise # ------------------------------------------------------------------------------ -func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name=""): - if(method_name != ""): - return signaler_obj.is_connected(signal_name,Callable(connect_to_obj,method_name)) +func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""): + if method_name != "": + return signaler_obj.is_connected(signal_name, Callable(connect_to_obj, method_name)) else: var connections = signaler_obj.get_signal_connection_list(signal_name) for conn in connections: - if(conn['signal'].get_name() == signal_name and conn['callable'].get_object() == connect_to_obj): + if ( + conn["signal"].get_name() == signal_name + and conn["callable"].get_object() == connect_to_obj + ): return true return false + + # ------------------------------------------------------------------------------ # Watch the signals for an object. This must be called before you can make # any assertions about the signals themselves. @@ -560,71 +693,92 @@ func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name=""): func watch_signals(object): _signal_watcher.watch_signals(object) + # ------------------------------------------------------------------------------ # Asserts that an object is connected to a signal on another object # # This will fail with specific messages if the target object is not connected # to the specified signal on the source object. # ------------------------------------------------------------------------------ -func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name=""): +func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""): pass - var method_disp = '' - if (method_name != ""): - method_disp = str(' using method: [', method_name, '] ') - var disp = str('Expected object ', _str(signaler_obj),\ - ' to be connected to signal: [', signal_name, '] on ',\ - _str(connect_to_obj), method_disp) - if(_is_connected(signaler_obj, connect_to_obj, signal_name, method_name)): + var method_disp = "" + if method_name != "": + method_disp = str(" using method: [", method_name, "] ") + var disp = str( + "Expected object ", + _str(signaler_obj), + " to be connected to signal: [", + signal_name, + "] on ", + _str(connect_to_obj), + method_disp + ) + if _is_connected(signaler_obj, connect_to_obj, signal_name, method_name): _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Asserts that an object is not connected to a signal on another object # # This will fail with specific messages if the target object is connected # to the specified signal on the source object. # ------------------------------------------------------------------------------ -func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name=""): - var method_disp = '' - if (method_name != ""): - method_disp = str(' using method: [', method_name, '] ') - var disp = str('Expected object ', _str(signaler_obj),\ - ' to not be connected to signal: [', signal_name, '] on ',\ - _str(connect_to_obj), method_disp) - if(_is_connected(signaler_obj, connect_to_obj, signal_name, method_name)): +func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""): + var method_disp = "" + if method_name != "": + method_disp = str(" using method: [", method_name, "] ") + var disp = str( + "Expected object ", + _str(signaler_obj), + " to not be connected to signal: [", + signal_name, + "] on ", + _str(connect_to_obj), + method_disp + ) + if _is_connected(signaler_obj, connect_to_obj, signal_name, method_name): _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Asserts that a signal has been emitted at least once. # # This will fail with specific messages if the object is not being watched or # the object does not have the specified signal # ------------------------------------------------------------------------------ -func assert_signal_emitted(object, signal_name, text=""): - var disp = str('Expected object ', _str(object), ' to have emitted signal [', signal_name, ']: ', text) - if(_can_make_signal_assertions(object, signal_name)): - if(_signal_watcher.did_emit(object, signal_name)): +func assert_signal_emitted(object, signal_name, text = ""): + var disp = str( + "Expected object ", _str(object), " to have emitted signal [", signal_name, "]: ", text + ) + if _can_make_signal_assertions(object, signal_name): + if _signal_watcher.did_emit(object, signal_name): _pass(disp) else: _fail(_get_fail_msg_including_emitted_signals(disp, object)) + # ------------------------------------------------------------------------------ # Asserts that a signal has not been emitted. # # This will fail with specific messages if the object is not being watched or # the object does not have the specified signal # ------------------------------------------------------------------------------ -func assert_signal_not_emitted(object, signal_name, text=""): - var disp = str('Expected object ', _str(object), ' to NOT emit signal [', signal_name, ']: ', text) - if(_can_make_signal_assertions(object, signal_name)): - if(_signal_watcher.did_emit(object, signal_name)): +func assert_signal_not_emitted(object, signal_name, text = ""): + var disp = str( + "Expected object ", _str(object), " to NOT emit signal [", signal_name, "]: ", text + ) + if _can_make_signal_assertions(object, signal_name): + if _signal_watcher.did_emit(object, signal_name): _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Asserts that a signal was fired with the specified parameters. The expected # parameters should be passed in as an array. An optional index can be passed @@ -634,46 +788,76 @@ func assert_signal_not_emitted(object, signal_name, text=""): # This will fail with specific messages if the object is not being watched or # the object does not have the specified signal # ------------------------------------------------------------------------------ -func assert_signal_emitted_with_parameters(object, signal_name, parameters, index=-1): - if(typeof(parameters) != TYPE_ARRAY): - _lgr.error("The expected parameters must be wrapped in an array, you passed: " + _str(parameters)) +func assert_signal_emitted_with_parameters(object, signal_name, parameters, index = -1): + if typeof(parameters) != TYPE_ARRAY: + _lgr.error( + "The expected parameters must be wrapped in an array, you passed: " + _str(parameters) + ) _fail("Bad Parameters") return - var disp = str('Expected object ', _str(object), ' to emit signal [', signal_name, '] with parameters ', parameters, ', got ') - if(_can_make_signal_assertions(object, signal_name)): - if(_signal_watcher.did_emit(object, signal_name)): + var disp = str( + "Expected object ", + _str(object), + " to emit signal [", + signal_name, + "] with parameters ", + parameters, + ", got " + ) + if _can_make_signal_assertions(object, signal_name): + if _signal_watcher.did_emit(object, signal_name): var parms_got = _signal_watcher.get_signal_parameters(object, signal_name, index) var diff_result = _compare.deep(parameters, parms_got) - if(diff_result.are_equal): + if diff_result.are_equal: _pass(str(disp, parms_got)) else: - _fail(str('Expected object ', _str(object), ' to emit signal [', signal_name, '] with parameters ', diff_result.summarize())) + _fail( + str( + "Expected object ", + _str(object), + " to emit signal [", + signal_name, + "] with parameters ", + diff_result.summarize() + ) + ) else: - var text = str('Object ', object, ' did not emit signal [', signal_name, ']') + var text = str("Object ", object, " did not emit signal [", signal_name, "]") _fail(_get_fail_msg_including_emitted_signals(text, object)) + # ------------------------------------------------------------------------------ # Assert that a signal has been emitted a specific number of times. # # This will fail with specific messages if the object is not being watched or # the object does not have the specified signal # ------------------------------------------------------------------------------ -func assert_signal_emit_count(object, signal_name, times, text=""): - if(_can_make_signal_assertions(object, signal_name)): +func assert_signal_emit_count(object, signal_name, times, text = ""): + if _can_make_signal_assertions(object, signal_name): var count = _signal_watcher.get_emit_count(object, signal_name) - var disp = str('Expected the signal [', signal_name, '] emit count of [', count, '] to equal [', times, ']: ', text) - if(count== times): + var disp = str( + "Expected the signal [", + signal_name, + "] emit count of [", + count, + "] to equal [", + times, + "]: ", + text + ) + if count == times: _pass(disp) else: _fail(_get_fail_msg_including_emitted_signals(disp, object)) + # ------------------------------------------------------------------------------ # Assert that the passed in object has the specified signal # ------------------------------------------------------------------------------ -func assert_has_signal(object, signal_name, text=""): - var disp = str('Expected object ', _str(object), ' to have signal [', signal_name, ']: ', text) - if(_signal_watcher.does_object_have_signal(object, signal_name)): +func assert_has_signal(object, signal_name, text = ""): + var disp = str("Expected object ", _str(object), " to have signal [", signal_name, "]: ", text) + if _signal_watcher.does_object_have_signal(object, signal_name): _pass(disp) else: _fail(disp) @@ -686,6 +870,7 @@ func assert_has_signal(object, signal_name, text=""): func get_signal_emit_count(object, signal_name): return _signal_watcher.get_emit_count(object, signal_name) + # ------------------------------------------------------------------------------ # Get the parmaters of a fired signal. If the signal was not fired null is # returned. You can specify an optional index (use get_signal_emit_count to @@ -693,9 +878,10 @@ func get_signal_emit_count(object, signal_name): # latest time the signal was fired (size() -1 insetead of 0). The parameters # returned are in an array. # ------------------------------------------------------------------------------ -func get_signal_parameters(object, signal_name, index=-1): +func get_signal_parameters(object, signal_name, index = -1): return _signal_watcher.get_signal_parameters(object, signal_name, index) + # ------------------------------------------------------------------------------ # Get the parameters for a method call to a doubled object. By default it will # return the most recent call. You can optionally specify an index. @@ -705,116 +891,122 @@ func get_signal_parameters(object, signal_name, index=-1): # * null when a call to the method was not found or the index specified was # invalid. # ------------------------------------------------------------------------------ -func get_call_parameters(object, method_name, index=-1): +func get_call_parameters(object, method_name, index = -1): var to_return = null - if(_utils.is_double(object)): + if _utils.is_double(object): to_return = gut.get_spy().get_call_parameters(object, method_name, index) else: - _lgr.error('You must pass a doulbed object to get_call_parameters.') + _lgr.error("You must pass a doulbed object to get_call_parameters.") return to_return + # ------------------------------------------------------------------------------ # Returns the call count for a method with optional paramter matching. # ------------------------------------------------------------------------------ -func get_call_count(object, method_name, parameters=null): +func get_call_count(object, method_name, parameters = null): return gut.get_spy().call_count(object, method_name, parameters) # ------------------------------------------------------------------------------ # Assert that object is an instance of a_class # ------------------------------------------------------------------------------ -func assert_is(object, a_class, text=''): - var disp = ''#var disp = str('Expected [', _str(object), '] to be type of [', a_class, ']: ', text) - var NATIVE_CLASS = 'GDScriptNativeClass' - var GDSCRIPT_CLASS = 'GDScript' - var bad_param_2 = 'Parameter 2 must be a Class (like Node2D or Label). You passed ' +func assert_is(object, a_class, text = ""): + var disp = "" #var disp = str('Expected [', _str(object), '] to be type of [', a_class, ']: ', text) + var NATIVE_CLASS = "GDScriptNativeClass" + var GDSCRIPT_CLASS = "GDScript" + var bad_param_2 = "Parameter 2 must be a Class (like Node2D or Label). You passed " - if(typeof(object) != TYPE_OBJECT): - _fail(str('Parameter 1 must be an instance of an object. You passed: ', _str(object))) - elif(typeof(a_class) != TYPE_OBJECT): + if typeof(object) != TYPE_OBJECT: + _fail(str("Parameter 1 must be an instance of an object. You passed: ", _str(object))) + elif typeof(a_class) != TYPE_OBJECT: _fail(str(bad_param_2, _str(a_class))) else: var a_str = _str(a_class) - disp = str('Expected [', _str(object), '] to extend [', a_str, ']: ', text) - if(!_utils.is_native_class(a_class) and !_utils.is_gdscript(a_class)): + disp = str("Expected [", _str(object), "] to extend [", a_str, "]: ", text) + if !_utils.is_native_class(a_class) and !_utils.is_gdscript(a_class): _fail(str(bad_param_2, a_str)) else: - if(object is a_class): + if object is a_class: _pass(disp) else: _fail(disp) + func _get_typeof_string(the_type): var to_return = "" - if(_strutils.types.has(the_type)): - to_return += str(the_type, '(', _strutils.types[the_type], ')') + if _strutils.types.has(the_type): + to_return += str(the_type, "(", _strutils.types[the_type], ")") else: to_return += str(the_type) return to_return + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func assert_typeof(object, type, text=''): - var disp = str('Expected [typeof(', object, ') = ') +func assert_typeof(object, type, text = ""): + var disp = str("Expected [typeof(", object, ") = ") disp += _get_typeof_string(typeof(object)) - disp += '] to equal [' - disp += _get_typeof_string(type) + ']' - disp += '. ' + text - if(typeof(object) == type): + disp += "] to equal [" + disp += _get_typeof_string(type) + "]" + disp += ". " + text + if typeof(object) == type: _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func assert_not_typeof(object, type, text=''): - var disp = str('Expected [typeof(', object, ') = ') +func assert_not_typeof(object, type, text = ""): + var disp = str("Expected [typeof(", object, ") = ") disp += _get_typeof_string(typeof(object)) - disp += '] to not equal [' - disp += _get_typeof_string(type) + ']' - disp += '. ' + text - if(typeof(object) != type): + disp += "] to not equal [" + disp += _get_typeof_string(type) + "]" + disp += ". " + text + if typeof(object) != type: _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Assert that text contains given search string. # The match_case flag determines case sensitivity. # ------------------------------------------------------------------------------ -func assert_string_contains(text, search, match_case=true): - var empty_search = 'Expected text and search strings to be non-empty. You passed \'%s\' and \'%s\'.' - var disp = 'Expected \'%s\' to contain \'%s\', match_case=%s' % [text, search, match_case] - if(text == '' or search == ''): +func assert_string_contains(text, search, match_case = true): + var empty_search = "Expected text and search strings to be non-empty. You passed '%s' and '%s'." + var disp = "Expected '%s' to contain '%s', match_case=%s" % [text, search, match_case] + if text == "" or search == "": _fail(empty_search % [text, search]) - elif(match_case): - if(text.find(search) == -1): + elif match_case: + if text.find(search) == -1: _fail(disp) else: _pass(disp) else: - if(text.to_lower().find(search.to_lower()) == -1): + if text.to_lower().find(search.to_lower()) == -1: _fail(disp) else: _pass(disp) + # ------------------------------------------------------------------------------ # Assert that text starts with given search string. # match_case flag determines case sensitivity. # ------------------------------------------------------------------------------ -func assert_string_starts_with(text, search, match_case=true): - var empty_search = 'Expected text and search strings to be non-empty. You passed \'%s\' and \'%s\'.' - var disp = 'Expected \'%s\' to start with \'%s\', match_case=%s' % [text, search, match_case] - if(text == '' or search == ''): +func assert_string_starts_with(text, search, match_case = true): + var empty_search = "Expected text and search strings to be non-empty. You passed '%s' and '%s'." + var disp = "Expected '%s' to start with '%s', match_case=%s" % [text, search, match_case] + if text == "" or search == "": _fail(empty_search % [text, search]) - elif(match_case): - if(text.find(search) == 0): + elif match_case: + if text.find(search) == 0: _pass(disp) else: _fail(disp) else: - if(text.to_lower().find(search.to_lower()) == 0): + if text.to_lower().find(search.to_lower()) == 0: _pass(disp) else: _fail(disp) @@ -824,23 +1016,24 @@ func assert_string_starts_with(text, search, match_case=true): # Assert that text ends with given search string. # match_case flag determines case sensitivity. # ------------------------------------------------------------------------------ -func assert_string_ends_with(text, search, match_case=true): - var empty_search = 'Expected text and search strings to be non-empty. You passed \'%s\' and \'%s\'.' - var disp = 'Expected \'%s\' to end with \'%s\', match_case=%s' % [text, search, match_case] +func assert_string_ends_with(text, search, match_case = true): + var empty_search = "Expected text and search strings to be non-empty. You passed '%s' and '%s'." + var disp = "Expected '%s' to end with '%s', match_case=%s" % [text, search, match_case] var required_index = len(text) - len(search) - if(text == '' or search == ''): + if text == "" or search == "": _fail(empty_search % [text, search]) - elif(match_case): - if(text.find(search) == required_index): + elif match_case: + if text.find(search) == required_index: _pass(disp) else: _fail(disp) else: - if(text.to_lower().find(search.to_lower()) == required_index): + if text.to_lower().find(search.to_lower()) == required_index: _pass(disp) else: _fail(disp) + # ------------------------------------------------------------------------------ # Assert that a method was called on an instance of a doubled class. If # parameters are supplied then the params passed in when called must match. @@ -848,124 +1041,137 @@ func assert_string_ends_with(text, search, match_case=true): # then work some magic so this can have a "text" parameter without being # annoying. # ------------------------------------------------------------------------------ -func assert_called(inst, method_name, parameters=null): - var disp = str('Expected [',method_name,'] to have been called on ',_str(inst)) +func assert_called(inst, method_name, parameters = null): + var disp = str("Expected [", method_name, "] to have been called on ", _str(inst)) - if(_fail_if_parameters_not_array(parameters)): + if _fail_if_parameters_not_array(parameters): return - if(!_utils.is_double(inst)): - _fail('You must pass a doubled instance to assert_called. Check the wiki for info on using double.') + if !_utils.is_double(inst): + _fail( + "You must pass a doubled instance to assert_called. Check the wiki for info on using double." + ) else: - if(gut.get_spy().was_called(inst, method_name, parameters)): + if gut.get_spy().was_called(inst, method_name, parameters): _pass(disp) else: - if(parameters != null): - disp += str(' with parameters ', parameters) + if parameters != null: + disp += str(" with parameters ", parameters) _fail(str(disp, "\n", _get_desc_of_calls_to_instance(inst))) + # ------------------------------------------------------------------------------ # Assert that a method was not called on an instance of a doubled class. If # parameters are specified then this will only fail if it finds a call that was # sent matching parameters. # ------------------------------------------------------------------------------ -func assert_not_called(inst, method_name, parameters=null): - var disp = str('Expected [', method_name, '] to NOT have been called on ', _str(inst)) +func assert_not_called(inst, method_name, parameters = null): + var disp = str("Expected [", method_name, "] to NOT have been called on ", _str(inst)) - if(_fail_if_parameters_not_array(parameters)): + if _fail_if_parameters_not_array(parameters): return - if(!_utils.is_double(inst)): - _fail('You must pass a doubled instance to assert_not_called. Check the wiki for info on using double.') + if !_utils.is_double(inst): + _fail( + "You must pass a doubled instance to assert_not_called. Check the wiki for info on using double." + ) else: - if(gut.get_spy().was_called(inst, method_name, parameters)): - if(parameters != null): - disp += str(' with parameters ', parameters) + if gut.get_spy().was_called(inst, method_name, parameters): + if parameters != null: + disp += str(" with parameters ", parameters) _fail(str(disp, "\n", _get_desc_of_calls_to_instance(inst))) else: _pass(disp) + # ------------------------------------------------------------------------------ # Assert that a method on an instance of a doubled class was called a number # of times. If parameters are specified then only calls with matching # parameter values will be counted. # ------------------------------------------------------------------------------ -func assert_call_count(inst, method_name, expected_count, parameters=null): +func assert_call_count(inst, method_name, expected_count, parameters = null): var count = gut.get_spy().call_count(inst, method_name, parameters) - if(_fail_if_parameters_not_array(parameters)): + if _fail_if_parameters_not_array(parameters): return - var param_text = '' - if(parameters): - param_text = ' with parameters ' + str(parameters) - var disp = 'Expected [%s] on %s to be called [%s] times%s. It was called [%s] times.' + var param_text = "" + if parameters: + param_text = " with parameters " + str(parameters) + var disp = "Expected [%s] on %s to be called [%s] times%s. It was called [%s] times." disp = disp % [method_name, _str(inst), expected_count, param_text, count] - if(!_utils.is_double(inst)): - _fail('You must pass a doubled instance to assert_call_count. Check the wiki for info on using double.') + if !_utils.is_double(inst): + _fail( + "You must pass a doubled instance to assert_call_count. Check the wiki for info on using double." + ) else: - if(count == expected_count): + if count == expected_count: _pass(disp) else: _fail(str(disp, "\n", _get_desc_of_calls_to_instance(inst))) -# ------------------------------------------------------------------------------ -# Asserts the passed in value is null -# ------------------------------------------------------------------------------ -func assert_null(got, text=''): - var disp = str('Expected [', _str(got), '] to be NULL: ', text) - if(got == null): - _pass(disp) - else: - _fail(disp) # ------------------------------------------------------------------------------ # Asserts the passed in value is null # ------------------------------------------------------------------------------ -func assert_not_null(got, text=''): - var disp = str('Expected [', _str(got), '] to be anything but NULL: ', text) - if(got == null): +func assert_null(got, text = ""): + var disp = str("Expected [", _str(got), "] to be NULL: ", text) + if got == null: + _pass(disp) + else: + _fail(disp) + + +# ------------------------------------------------------------------------------ +# Asserts the passed in value is null +# ------------------------------------------------------------------------------ +func assert_not_null(got, text = ""): + var disp = str("Expected [", _str(got), "] to be anything but NULL: ", text) + if got == null: _fail(disp) else: _pass(disp) + # ----------------------------------------------------------------------------- # Asserts object has been freed from memory # We pass in a title (since if it is freed, we lost all identity data) # ----------------------------------------------------------------------------- -func assert_freed(obj, title='something'): +func assert_freed(obj, title = "something"): var disp = title - if(is_instance_valid(obj)): + if is_instance_valid(obj): disp = _strutils.type2str(obj) + title assert_true(not is_instance_valid(obj), "Expected [%s] to be freed" % disp) + # ------------------------------------------------------------------------------ # Asserts Object has not been freed from memory # ----------------------------------------------------------------------------- func assert_not_freed(obj, title): var disp = title - if(is_instance_valid(obj)): + if is_instance_valid(obj): disp = _strutils.type2str(obj) + title assert_true(is_instance_valid(obj), "Expected [%s] to not be freed" % disp) + # ------------------------------------------------------------------------------ # Asserts that the current test has not introduced any new orphans. This only # applies to the test code that preceedes a call to this method so it should be # the last thing your test does. # ------------------------------------------------------------------------------ -func assert_no_new_orphans(text=''): - var count = gut.get_orphan_counter().get_counter('test') - var msg = '' - if(text != ''): - msg = ': ' + text +func assert_no_new_orphans(text = ""): + var count = gut.get_orphan_counter().get_counter("test") + var msg = "" + if text != "": + msg = ": " + text # Note that get_counter will return -1 if the counter does not exist. This # can happen with a misplaced assert_no_new_orphans. Checking for > 0 # ensures this will not cause some weird failure. - if(count > 0): - _fail(str('Expected no orphans, but found ', count, msg)) + if count > 0: + _fail(str("Expected no orphans, but found ", count, msg)) else: - _pass('No new orphans found.' + msg) + _pass("No new orphans found." + msg) # ------------------------------------------------------------------------------ @@ -974,15 +1180,21 @@ func assert_no_new_orphans(text=''): # ------------------------------------------------------------------------------ func _validate_singleton_name(singleton_name): var is_valid = true - if(typeof(singleton_name) != TYPE_STRING): - _lgr.error("double_singleton requires a Godot singleton name, you passed " + _str(singleton_name)) + if typeof(singleton_name) != TYPE_STRING: + _lgr.error( + "double_singleton requires a Godot singleton name, you passed " + _str(singleton_name) + ) is_valid = false # Sometimes they have underscores in front of them, sometimes they do not. # The doubler is smart enought of ind the right thing, so this has to be # that smart as well. - elif(!ClassDB.class_exists(singleton_name) and !ClassDB.class_exists('_' + singleton_name)): - var txt = str("The singleton [", singleton_name, "] could not be found. ", - "Check the GlobalScope page for a list of singletons.") + elif !ClassDB.class_exists(singleton_name) and !ClassDB.class_exists("_" + singleton_name): + var txt = str( + "The singleton [", + singleton_name, + "] could not be found. ", + "Check the GlobalScope page for a list of singletons." + ) _lgr.error(txt) is_valid = false return is_valid @@ -990,11 +1202,11 @@ func _validate_singleton_name(singleton_name): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func assert_setget( - instance, name_property, - const_or_setter = null, getter="__not_set__"): - _lgr.deprecated('assert_setget') - _fail('assert_setget has been removed. Use assert_property, assert_set_property, assert_readonly_property instead.') +func assert_setget(instance, name_property, const_or_setter = null, getter = "__not_set__"): + _lgr.deprecated("assert_setget") + _fail( + "assert_setget has been removed. Use assert_property, assert_set_property, assert_readonly_property instead." + ) # ------------------------------------------------------------------------------ @@ -1020,17 +1232,16 @@ func assert_readonly_property(obj, property_name, new_value, expected_value): func _warn_for_public_accessors(obj, property_name): var public_accessors = [] var accessor_names = [ - str('get_', property_name), - str('is_', property_name), - str('set_', property_name) + str("get_", property_name), str("is_", property_name), str("set_", property_name) ] for acc in accessor_names: - if(obj.has_method(acc)): + if obj.has_method(acc): public_accessors.append(acc) - if(public_accessors.size() > 0): - _lgr.warn (str('Public accessors ', public_accessors, ' found for property ', property_name)) + if public_accessors.size() > 0: + _lgr.warn(str("Public accessors ", public_accessors, " found for property ", property_name)) + # ------------------------------------------------------------------------------ # Assumes backing varible with be _. This will perform all the @@ -1038,32 +1249,38 @@ func _warn_for_public_accessors(obj, property_name): # and check the backing variable value. It will then reset throught the setter # and set the backing variable and check the getter. # ------------------------------------------------------------------------------ -func assert_property_with_backing_variable(obj, property_name, default_value, new_value, backed_by_name=null): - var setter_name = str('@', property_name, '_setter') - var getter_name = str('@', property_name, '_getter') - var backing_name = _utils.nvl(backed_by_name, str('_', property_name)) +func assert_property_with_backing_variable( + obj, property_name, default_value, new_value, backed_by_name = null +): + var setter_name = str("@", property_name, "_setter") + var getter_name = str("@", property_name, "_getter") + var backing_name = _utils.nvl(backed_by_name, str("_", property_name)) var pre_fail_count = get_fail_count() var props = obj.get_property_list() var found = false var idx = 0 - while(idx < props.size() and !found): + while idx < props.size() and !found: found = props[idx].name == backing_name idx += 1 - assert_true(found, str(obj, ' has ', backing_name, ' variable.')) - assert_true(obj.has_method(setter_name), str('There should be a setter for ', property_name)) - assert_true(obj.has_method(getter_name), str('There should be a getter for ', property_name)) + assert_true(found, str(obj, " has ", backing_name, " variable.")) + assert_true(obj.has_method(setter_name), str("There should be a setter for ", property_name)) + assert_true(obj.has_method(getter_name), str("There should be a getter for ", property_name)) - if(pre_fail_count == get_fail_count()): + if pre_fail_count == get_fail_count(): var call_setter = Callable(obj, setter_name) var call_getter = Callable(obj, getter_name) - assert_eq(obj.get(backing_name), default_value, str('Variable ', backing_name, ' has default value.')) - assert_eq(call_getter.call(), default_value, 'Getter returns default value.') + assert_eq( + obj.get(backing_name), + default_value, + str("Variable ", backing_name, " has default value.") + ) + assert_eq(call_getter.call(), default_value, "Getter returns default value.") call_setter.call(new_value) - assert_eq(call_getter.call(), new_value, 'Getter returns value from Setter.') - assert_eq(obj.get(backing_name), new_value, str('Variable ', backing_name, ' was set')) + assert_eq(call_getter.call(), new_value, "Getter returns value from Setter.") + assert_eq(obj.get(backing_name), new_value, str("Variable ", backing_name, " was set")) _warn_for_public_accessors(obj, property_name) @@ -1078,23 +1295,23 @@ func assert_property(obj, property_name, default_value, new_value) -> void: var resource = null var pre_fail_count = get_fail_count() - var setter_name = str('@', property_name, '_setter') - var getter_name = str('@', property_name, '_getter') + var setter_name = str("@", property_name, "_setter") + var getter_name = str("@", property_name, "_getter") - if(typeof(obj) != TYPE_OBJECT): - _fail(str(_str(obj), ' is not an object')) + if typeof(obj) != TYPE_OBJECT: + _fail(str(_str(obj), " is not an object")) return assert_has_method(obj, setter_name) assert_has_method(obj, getter_name) - if(pre_fail_count == get_fail_count()): + if pre_fail_count == get_fail_count(): var call_setter = Callable(obj, setter_name) var call_getter = Callable(obj, getter_name) - assert_eq(call_getter.call(), default_value, 'Default value') + assert_eq(call_getter.call(), default_value, "Default value") call_setter.call(new_value) - assert_eq(call_getter.call(), new_value, 'Getter gets Setter value') + assert_eq(call_getter.call(), new_value, "Getter gets Setter value") _warn_for_public_accessors(obj, property_name) @@ -1102,9 +1319,9 @@ func assert_property(obj, property_name, default_value, new_value) -> void: # ------------------------------------------------------------------------------ # Mark the current test as pending. # ------------------------------------------------------------------------------ -func pending(text=""): +func pending(text = ""): _summary.pending += 1 - if(gut): + if gut: _lgr.pending(text) gut._pending(text) @@ -1113,12 +1330,13 @@ func pending(text=""): # Yield for the time sent in. The optional message will be printed when # Gut detects the yield. # ------------------------------------------------------------------------------ -func wait_seconds(time, msg=''): +func wait_seconds(time, msg = ""): var to_return = gut.set_wait_time(time, msg) return to_return -func yield_for(time, msg=''): - _lgr.deprecated('yield_for', 'wait_seconds') + +func yield_for(time, msg = ""): + _lgr.deprecated("yield_for", "wait_seconds") var to_return = gut.set_wait_time(time, msg) return to_return @@ -1126,25 +1344,28 @@ func yield_for(time, msg=''): # ------------------------------------------------------------------------------ # Yield to a signal or a maximum amount of time, whichever comes first. # ------------------------------------------------------------------------------ -func wait_for_signal(sig, max_wait, msg=''): +func wait_for_signal(sig, max_wait, msg = ""): watch_signals(sig.get_object()) var to_return = gut.set_wait_for_signal_or_time(sig.get_object(), sig.get_name(), max_wait, msg) return to_return -func yield_to(obj, signal_name, max_wait, msg=''): - _lgr.deprecated('yield_to', 'wait_for_signal') +func yield_to(obj, signal_name, max_wait, msg = ""): + _lgr.deprecated("yield_to", "wait_for_signal") watch_signals(obj) var to_return = gut.set_wait_for_signal_or_time(obj, signal_name, max_wait, msg) return to_return + # ------------------------------------------------------------------------------ # Yield for a number of frames. The optional message will be printed. when # Gut detects a yield. # ------------------------------------------------------------------------------ -func wait_frames(frames, msg=''): - if(frames <= 0): - var text = str('yeild_frames: frames must be > 0, you passed ', frames, '. 0 frames waited.') +func wait_frames(frames, msg = ""): + if frames <= 0: + var text = str( + "yeild_frames: frames must be > 0, you passed ", frames, ". 0 frames waited." + ) _lgr.error(text) frames = 1 @@ -1152,82 +1373,95 @@ func wait_frames(frames, msg=''): return to_return -func yield_frames(frames, msg=''): +func yield_frames(frames, msg = ""): _lgr.deprecated("yield_frames", "wait_frames") var to_return = wait_frames(frames, msg) return to_return + func get_summary(): return _summary + func get_fail_count(): return _summary.failed + func get_pass_count(): return _summary.passed + func get_pending_count(): return _summary.pending + func get_assert_count(): return _summary.asserts + func clear_signal_watcher(): _signal_watcher.clear() + func get_double_strategy(): return gut.get_doubler().get_strategy() + func set_double_strategy(double_strategy): gut.get_doubler().set_strategy(double_strategy) + func pause_before_teardown(): gut.pause_before_teardown() + # ------------------------------------------------------------------------------ # Convert the _summary dictionary into text # ------------------------------------------------------------------------------ func get_summary_text(): var to_return = get_script().get_path() + "\n" - to_return += str(' ', _summary.passed, ' of ', _summary.asserts, ' passed.') - if(_summary.pending > 0): - to_return += str("\n ", _summary.pending, ' pending') - if(_summary.failed > 0): - to_return += str("\n ", _summary.failed, ' failed.') + to_return += str(" ", _summary.passed, " of ", _summary.asserts, " passed.") + if _summary.pending > 0: + to_return += str("\n ", _summary.pending, " pending") + if _summary.failed > 0: + to_return += str("\n ", _summary.failed, " failed.") return to_return + # ------------------------------------------------------------------------------ # Double a script, inner class, or scene using a path or a loaded script/scene. # # # ------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ func _smart_double(thing, double_strat, partial): var override_strat = _utils.nvl(double_strat, gut.get_doubler().get_strategy()) var to_return = null - if(thing is PackedScene): - if(partial): - to_return = gut.get_doubler().partial_double_scene(thing, override_strat) + if thing is PackedScene: + if partial: + to_return = gut.get_doubler().partial_double_scene(thing, override_strat) else: - to_return = gut.get_doubler().double_scene(thing, override_strat) + to_return = gut.get_doubler().double_scene(thing, override_strat) - elif(_utils.is_native_class(thing)): - if(partial): + elif _utils.is_native_class(thing): + if partial: to_return = gut.get_doubler().partial_double_gdnative(thing) else: to_return = gut.get_doubler().double_gdnative(thing) - elif(thing is GDScript): - if(partial): + elif thing is GDScript: + if partial: to_return = gut.get_doubler().partial_double(thing, override_strat) else: to_return = gut.get_doubler().double(thing, override_strat) return to_return + # ------------------------------------------------------------------------------ # This is here to aid in the transition to the new doubling sytnax. Once this # has been established it could be removed. We must keep the is_instance check @@ -1235,16 +1469,16 @@ func _smart_double(thing, double_strat, partial): # ------------------------------------------------------------------------------ func _are_double_parameters_valid(thing, p2, p3): var bad_msg = "" - if(p3 != null or typeof(p2) == TYPE_STRING): + if p3 != null or typeof(p2) == TYPE_STRING: bad_msg += "Doubling using a subpath is not supported. Call register_inner_class and then pass the Inner Class to double().\n" - if(typeof(thing) == TYPE_STRING): + if typeof(thing) == TYPE_STRING: bad_msg += "Doubling using the path to a script or scene is no longer supported. Load the script or scene and pass that to double instead.\n" - if(_utils.is_instance(thing)): + if _utils.is_instance(thing): bad_msg += "double requires a script, you passed an instance: " + _str(thing) - if(bad_msg != ""): + if bad_msg != "": _lgr.error(bad_msg) return bad_msg == "" @@ -1252,20 +1486,22 @@ func _are_double_parameters_valid(thing, p2, p3): # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func double(thing, double_strat=null, not_used_anymore=null): - if(!_are_double_parameters_valid(thing, double_strat, not_used_anymore)): +func double(thing, double_strat = null, not_used_anymore = null): + if !_are_double_parameters_valid(thing, double_strat, not_used_anymore): return null return _smart_double(thing, double_strat, false) + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ -func partial_double(thing, double_strat=null, not_used_anymore=null): - if(!_are_double_parameters_valid(thing, double_strat, not_used_anymore)): +func partial_double(thing, double_strat = null, not_used_anymore = null): + if !_are_double_parameters_valid(thing, double_strat, not_used_anymore): return null return _smart_double(thing, double_strat, true) + # ------------------------------------------------------------------------------ # Doubles a Godot singleton # ------------------------------------------------------------------------------ @@ -1276,6 +1512,7 @@ func double_singleton(singleton_name): # to_return = gut.get_doubler().double_singleton(singleton_name) # return to_return + # ------------------------------------------------------------------------------ # Partial Doubles a Godot singleton # ------------------------------------------------------------------------------ @@ -1286,31 +1523,36 @@ func partial_double_singleton(singleton_name): # to_return = gut.get_doubler().partial_double_singleton(singleton_name) # return to_return + # ------------------------------------------------------------------------------ # Specifically double a scene # ------------------------------------------------------------------------------ -func double_scene(path, strategy=null): - _lgr.deprecated('test.double_scene has been removed.', 'double') +func double_scene(path, strategy = null): + _lgr.deprecated("test.double_scene has been removed.", "double") return null # var override_strat = _utils.nvl(strategy, gut.get_doubler().get_strategy()) # return gut.get_doubler().double_scene(path, override_strat) + # ------------------------------------------------------------------------------ # Specifically double a script # ------------------------------------------------------------------------------ -func double_script(path, strategy=null): - _lgr.deprecated('test.double_script has been removed.', 'double') +func double_script(path, strategy = null): + _lgr.deprecated("test.double_script has been removed.", "double") return null # var override_strat = _utils.nvl(strategy, gut.get_doubler().get_strategy()) # return gut.get_doubler().double(path, override_strat) + # ------------------------------------------------------------------------------ # Specifically double an Inner class in a a script # ------------------------------------------------------------------------------ -func double_inner(path, subpath, strategy=null): - _lgr.deprecated('double_inner should not be used. Use register_inner_classes and double instead.', 'double') +func double_inner(path, subpath, strategy = null): + _lgr.deprecated( + "double_inner should not be used. Use register_inner_classes and double instead.", "double" + ) return null var override_strat = _utils.nvl(strategy, gut.get_doubler().get_strategy()) @@ -1322,19 +1564,22 @@ func double_inner(path, subpath, strategy=null): # or scene. These ignores are cleared after every test. # ------------------------------------------------------------------------------ func ignore_method_when_doubling(thing, method_name): - if(typeof(thing) == TYPE_STRING): - _lgr.error('ignore_method_when_doubling no longer supports paths to scripts or scenes. Load them and pass them instead.') + if typeof(thing) == TYPE_STRING: + _lgr.error( + "ignore_method_when_doubling no longer supports paths to scripts or scenes. Load them and pass them instead." + ) return var r = thing - if(thing is PackedScene): + if thing is PackedScene: var inst = thing.instantiate() - if(inst.get_script()): + if inst.get_script(): r = inst.get_script() gut.get_doubler().add_ignored_method(r, method_name) + # ------------------------------------------------------------------------------ # Stub something. # @@ -1346,14 +1591,14 @@ func ignore_method_when_doubling(thing, method_name): # only be called with two parameters. I did the work though so I'm going # to leave it but not update the wiki. # ------------------------------------------------------------------------------ -func stub(thing, p2, p3=null): - if(_utils.is_instance(thing) and !_utils.is_double(thing)): - _lgr.error(str('You cannot use stub on ', _str(thing), ' because it is not a double.')) +func stub(thing, p2, p3 = null): + if _utils.is_instance(thing) and !_utils.is_double(thing): + _lgr.error(str("You cannot use stub on ", _str(thing), " because it is not a double.")) return _utils.StubParams.new() var method_name = p2 var subpath = null - if(p3 != null): + if p3 != null: subpath = p2 method_name = p3 @@ -1361,12 +1606,14 @@ func stub(thing, p2, p3=null): gut.get_stubber().add_stub(sp) return sp + # ------------------------------------------------------------------------------ # convenience wrapper. # ------------------------------------------------------------------------------ func simulate(obj, times, delta): gut.simulate(obj, times, delta) + # ------------------------------------------------------------------------------ # Replace the node at base_node.get_node(path) with with_this. All references # to the node via $ and get_node(...) will now return with_this. with_this will @@ -1379,18 +1626,18 @@ func simulate(obj, times, delta): func replace_node(base_node, path_or_node, with_this): var path = path_or_node - if(typeof(path_or_node) != TYPE_STRING): + if typeof(path_or_node) != TYPE_STRING: # This will cause an engine error if it fails. It always returns a # NodePath, even if it fails. Checking the name count is the only way # I found to check if it found something or not (after it worked I # didn't look any farther). path = base_node.get_path_to(path_or_node) - if(path.get_name_count() == 0): - _lgr.error('You passed an object that base_node does not have. Cannot replace node.') + if path.get_name_count() == 0: + _lgr.error("You passed an object that base_node does not have. Cannot replace node.") return - if(!base_node.has_node(path)): - _lgr.error(str('Could not find node at path [', path, ']')) + if !base_node.has_node(path): + _lgr.error(str("Could not find node at path [", path, "]")) return var to_replace = base_node.get_node(path) @@ -1416,15 +1663,18 @@ func replace_node(base_node, path_or_node, with_this): # ------------------------------------------------------------------------------ func use_parameters(params): var ph = gut.parameter_handler - if(ph == null): + if ph == null: ph = _utils.ParameterHandler.new(params) gut.parameter_handler = ph - var output = str('(call #', ph.get_call_count() + 1, ') with parameters: ', ph.get_current_parameters()) + var output = str( + "(call #", ph.get_call_count() + 1, ") with parameters: ", ph.get_current_parameters() + ) _lgr.log(output) _lgr.inc_indent() return ph.next_parameters() + # ------------------------------------------------------------------------------ # Marks whatever is passed in to be freed after the test finishes. It also # returns what is passed in so you can save a line of code. @@ -1434,6 +1684,7 @@ func autofree(thing): gut.get_autofree().add_free(thing) return thing + # ------------------------------------------------------------------------------ # Works the same as autofree except queue_free will be called on the object # instead. This also imparts a brief pause after the test finishes so that @@ -1443,6 +1694,7 @@ func autoqfree(thing): gut.get_autofree().add_queue_free(thing) return thing + # ------------------------------------------------------------------------------ # The same as autofree but it also adds the object as a child of the test. # ------------------------------------------------------------------------------ @@ -1453,39 +1705,48 @@ func add_child_autofree(node, legible_unique_name = false): super.add_child(node, legible_unique_name) return node + # ------------------------------------------------------------------------------ # The same as autoqfree but it also adds the object as a child of the test. # ------------------------------------------------------------------------------ -func add_child_autoqfree(node, legible_unique_name=false): +func add_child_autoqfree(node, legible_unique_name = false): gut.get_autofree().add_queue_free(node) # Explicitly calling super here b/c add_child MIGHT change and I don't want # a bug sneaking its way in here. super.add_child(node, legible_unique_name) return node + # ------------------------------------------------------------------------------ # Returns true if the test is passing as of the time of this call. False if not. # ------------------------------------------------------------------------------ func is_passing(): - if(gut.get_current_test_object() != null and - !['before_all', 'after_all'].has(gut.get_current_test_object().name)): - return gut.get_current_test_object().passed and \ - gut.get_current_test_object().assert_count > 0 + if ( + gut.get_current_test_object() != null + and !["before_all", "after_all"].has(gut.get_current_test_object().name) + ): + return ( + gut.get_current_test_object().passed and gut.get_current_test_object().assert_count > 0 + ) else: - _lgr.error('No current test object found. is_passing must be called inside a test.') + _lgr.error("No current test object found. is_passing must be called inside a test.") return null + # ------------------------------------------------------------------------------ # Returns true if the test is failing as of the time of this call. False if not. # ------------------------------------------------------------------------------ func is_failing(): - if(gut.get_current_test_object() != null and - !['before_all', 'after_all'].has(gut.get_current_test_object().name)): + if ( + gut.get_current_test_object() != null + and !["before_all", "after_all"].has(gut.get_current_test_object().name) + ): return !gut.get_current_test_object().passed else: - _lgr.error('No current test object found. is_failing must be called inside a test.') + _lgr.error("No current test object found. is_failing must be called inside a test.") return null + # ------------------------------------------------------------------------------ # Marks the test as passing. Does not override any failing asserts or calls to # fail_test. Same as a passing assert. @@ -1493,68 +1754,75 @@ func is_failing(): func pass_test(text): _pass(text) + # ------------------------------------------------------------------------------ # Marks the test as failing. Same as a failing assert. # ------------------------------------------------------------------------------ func fail_test(text): _fail(text) + # ------------------------------------------------------------------------------ # Peforms a deep compare on both values, a CompareResult instnace is returned. # The optional max_differences paramter sets the max_differences to be displayed. # ------------------------------------------------------------------------------ -func compare_deep(v1, v2, max_differences=null): +func compare_deep(v1, v2, max_differences = null): var result = _compare.deep(v1, v2) - if(max_differences != null): + if max_differences != null: result.max_differences = max_differences return result + # ------------------------------------------------------------------------------ # Peforms a shallow compare on both values, a CompareResult instnace is returned. # The optional max_differences paramter sets the max_differences to be displayed. # ------------------------------------------------------------------------------ -func compare_shallow(v1, v2, max_differences=null): +func compare_shallow(v1, v2, max_differences = null): var result = _compare.shallow(v1, v2) - if(max_differences != null): + if max_differences != null: result.max_differences = max_differences return result + # ------------------------------------------------------------------------------ # Performs a deep compare and asserts the values are equal # ------------------------------------------------------------------------------ func assert_eq_deep(v1, v2): var result = compare_deep(v1, v2) - if(result.are_equal): + if result.are_equal: _pass(result.get_short_summary()) else: _fail(result.summary) + # ------------------------------------------------------------------------------ # Performs a deep compare and asserts the values are not equal # ------------------------------------------------------------------------------ func assert_ne_deep(v1, v2): var result = compare_deep(v1, v2) - if(!result.are_equal): + if !result.are_equal: _pass(result.get_short_summary()) else: _fail(result.get_short_summary()) + # ------------------------------------------------------------------------------ # Performs a shallow compare and asserts the values are equal # ------------------------------------------------------------------------------ func assert_eq_shallow(v1, v2): var result = compare_shallow(v1, v2) - if(result.are_equal): + if result.are_equal: _pass(result.get_short_summary()) else: _fail(result.summary) + # ------------------------------------------------------------------------------ # Performs a shallow compare and asserts the values are not equal # ------------------------------------------------------------------------------ func assert_ne_shallow(v1, v2): var result = compare_shallow(v1, v2) - if(!result.are_equal): + if !result.are_equal: _pass(result.get_short_summary()) else: _fail(result.get_short_summary()) @@ -1572,8 +1840,8 @@ func assert_ne_shallow(v1, v2): # ------------------------------------------------------------------------------ func skip_if_godot_version_lt(expected): var should_skip = !_utils.is_godot_version_gte(expected) - if(should_skip): - _pass(str('Skipping ', _utils.godot_version(), ' is less than ', expected)) + if should_skip: + _pass(str("Skipping ", _utils.godot_version(), " is less than ", expected)) return should_skip @@ -1589,13 +1857,14 @@ func skip_if_godot_version_lt(expected): # ------------------------------------------------------------------------------ func skip_if_godot_version_ne(expected): var should_skip = !_utils.is_godot_version(expected) - if(should_skip): - _pass(str('Skipping ', _utils.godot_version(), ' is not ', expected)) + if should_skip: + _pass(str("Skipping ", _utils.godot_version(), " is not ", expected)) return should_skip + # ------------------------------------------------------------------------------ # Registers all the inner classes in a script with the doubler. This is required # before you can double any inner class. # ------------------------------------------------------------------------------ func register_inner_classes(base_script): - gut.get_doubler().inner_class_registry.register(base_script) \ No newline at end of file + gut.get_doubler().inner_class_registry.register(base_script) diff --git a/addons/gut/test_collector.gd b/addons/gut/test_collector.gd index ad75944..86ac893 100644 --- a/addons/gut/test_collector.gd +++ b/addons/gut/test_collector.gd @@ -35,24 +35,24 @@ class Test: # This class also facilitates all the exporting and importing of tests. # ------------------------------------------------------------------------------ class TestScript: - var inner_class_name:StringName + var inner_class_name: StringName var tests = [] - var path:String + var path: String var _utils = null var _lgr = null var is_loaded = false - func _init(utils=null,logger=null): + func _init(utils = null, logger = null): _utils = utils _lgr = logger func to_s(): var to_return = path - if(inner_class_name != null): - to_return += str('.', inner_class_name) + if inner_class_name != null: + to_return += str(".", inner_class_name) to_return += "\n" for i in range(tests.size()): - to_return += str(' ', tests[i].name, "\n") + to_return += str(" ", tests[i].name, "\n") return to_return func get_new(): @@ -61,7 +61,7 @@ class TestScript: func load_script(): var to_return = load(path) - if(inner_class_name != null and inner_class_name != ''): + if inner_class_name != null and inner_class_name != "": # If we wanted to do inner classes in inner classses # then this would have to become some kind of loop or recursive # call to go all the way down the chain or this class would @@ -73,120 +73,123 @@ class TestScript: func get_filename_and_inner(): var to_return = get_filename() - if(inner_class_name != ''): - to_return += '.' + String(inner_class_name) + if inner_class_name != "": + to_return += "." + String(inner_class_name) return to_return func get_full_name(): var to_return = path - if(inner_class_name != ''): - to_return += '.' + String(inner_class_name) + if inner_class_name != "": + to_return += "." + String(inner_class_name) return to_return func get_filename(): return path.get_file() func has_inner_class(): - return inner_class_name != '' - + return inner_class_name != "" # Note: although this no longer needs to export the inner_class names since # they are pulled from metadata now, it is easier to leave that in # so we don't have to cut the export down to unique script names. func export_to(config_file, section): - config_file.set_value(section, 'path', path) - config_file.set_value(section, 'inner_class', inner_class_name) + config_file.set_value(section, "path", path) + config_file.set_value(section, "inner_class", inner_class_name) var names = [] for i in range(tests.size()): names.append(tests[i].name) - config_file.set_value(section, 'tests', names) - + config_file.set_value(section, "tests", names) func _remap_path(source_path): var to_return = source_path - if(!_utils.file_exists(source_path)): - _lgr.debug('Checking for remap for: ' + source_path) - var remap_path = source_path.get_basename() + '.gd.remap' - if(_utils.file_exists(remap_path)): + if !_utils.file_exists(source_path): + _lgr.debug("Checking for remap for: " + source_path) + var remap_path = source_path.get_basename() + ".gd.remap" + if _utils.file_exists(remap_path): var cf = ConfigFile.new() cf.load(remap_path) - to_return = cf.get_value('remap', 'path') + to_return = cf.get_value("remap", "path") else: - _lgr.warn('Could not find remap file ' + remap_path) + _lgr.warn("Could not find remap file " + remap_path) return to_return - func import_from(config_file, section): - path = config_file.get_value(section, 'path') + path = config_file.get_value(section, "path") path = _remap_path(path) # Null is an acceptable value, but you can't pass null as a default to # get_value since it thinks you didn't send a default...then it spits # out red text. This works around that. - var inner_name = config_file.get_value(section, 'inner_class', 'Placeholder') - if(inner_name != 'Placeholder'): + var inner_name = config_file.get_value(section, "inner_class", "Placeholder") + if inner_name != "Placeholder": inner_class_name = inner_name - else: # just being explicit + else: # just being explicit inner_class_name = StringName("") func get_test_named(name): - return _utils.search_array(tests, 'name', name) + return _utils.search_array(tests, "name", name) func mark_tests_to_skip_with_suffix(suffix): for single_test in tests: single_test.should_skip = single_test.name.ends_with(suffix) - # ------------------------------------------------------------------------------ # start test_collector, I don't think I like the name. # ------------------------------------------------------------------------------ var scripts = [] -var _test_prefix = 'test_' -var _test_class_prefix = 'Test' +var _test_prefix = "test_" +var _test_class_prefix = "Test" -var _utils = load('res://addons/gut/utils.gd').get_instance() +var _utils = load("res://addons/gut/utils.gd").get_instance() var _lgr = _utils.get_logger() + func _does_inherit_from_test(thing): var base_script = thing.get_base_script() var to_return = false - if(base_script != null): + if base_script != null: var base_path = base_script.get_path() - if(base_path == 'res://addons/gut/test.gd'): + if base_path == "res://addons/gut/test.gd": to_return = true else: to_return = _does_inherit_from_test(base_script) return to_return -func _populate_tests(test_script:TestScript): - var script = test_script.load_script() - if(script == null): - print(' !!! ', test_script.path, ' could not be loaded') +func _populate_tests(test_script: TestScript): + var script = test_script.load_script() + if script == null: + print(" !!! ", test_script.path, " could not be loaded") return false test_script.is_loaded = true var methods = script.get_script_method_list() for i in range(methods.size()): - var name = methods[i]['name'] - if(name.begins_with(_test_prefix)): + var name = methods[i]["name"] + if name.begins_with(_test_prefix): var t = Test.new() t.name = name - t.arg_count = methods[i]['args'].size() + t.arg_count = methods[i]["args"].size() test_script.tests.append(t) + func _get_inner_test_class_names(loaded): var inner_classes = [] var const_map = loaded.get_script_constant_map() for key in const_map: var thing = const_map[key] - if(_utils.is_gdscript(thing)): - if(key.begins_with(_test_class_prefix)): - if(_does_inherit_from_test(thing)): + if _utils.is_gdscript(thing): + if key.begins_with(_test_class_prefix): + if _does_inherit_from_test(thing): inner_classes.append(key) else: - _lgr.warn(str('Ignoring Inner Class ', key, - ' because it does not extend res://addons/gut/test.gd')) + _lgr.warn( + str( + "Ignoring Inner Class ", + key, + " because it does not extend res://addons/gut/test.gd" + ) + ) # This could go deeper and find inner classes within inner classes # but requires more experimentation. Right now I'm keeping it at @@ -195,40 +198,42 @@ func _get_inner_test_class_names(loaded): # _populate_inner_test_classes(thing) return inner_classes + func _parse_script(test_script): var inner_classes = [] var scripts_found = [] var loaded = load(test_script.path) - if(_does_inherit_from_test(loaded)): + if _does_inherit_from_test(loaded): _populate_tests(test_script) scripts_found.append(test_script.path) inner_classes = _get_inner_test_class_names(loaded) for i in range(inner_classes.size()): var loaded_inner = loaded.get(inner_classes[i]) - if(_does_inherit_from_test(loaded_inner)): + if _does_inherit_from_test(loaded_inner): var ts = TestScript.new(_utils, _lgr) ts.path = test_script.path ts.inner_class_name = inner_classes[i] _populate_tests(ts) scripts.append(ts) - scripts_found.append(test_script.path + '[' + inner_classes[i] +']') + scripts_found.append(test_script.path + "[" + inner_classes[i] + "]") return scripts_found + # ----------------- # Public # ----------------- func add_script(path): # print('Adding ', path) # SHORTCIRCUIT - if(has_script(path)): + if has_script(path): return [] # SHORTCIRCUIT - if(!FileAccess.file_exists(path)): - _lgr.error('Could not find script: ' + path) + if !FileAccess.file_exists(path): + _lgr.error("Could not find script: " + path) return var ts = TestScript.new(_utils, _lgr) @@ -236,36 +241,40 @@ func add_script(path): scripts.append(ts) return _parse_script(ts) + func clear(): scripts.clear() + func has_script(path): var found = false var idx = 0 - while(idx < scripts.size() and !found): - if(scripts[idx].get_full_name() == path): + while idx < scripts.size() and !found: + if scripts[idx].get_full_name() == path: found = true else: idx += 1 return found + func export_tests(path): var success = true var f = ConfigFile.new() for i in range(scripts.size()): - scripts[i].export_to(f, str('TestScript-', i)) + scripts[i].export_to(f, str("TestScript-", i)) var result = f.save(path) - if(result != OK): - _lgr.error(str('Could not save exported tests to [', path, ']. Error code: ', result)) + if result != OK: + _lgr.error(str("Could not save exported tests to [", path, "]. Error code: ", result)) success = false return success + func import_tests(path): var success = false var f = ConfigFile.new() var result = f.load(path) - if(result != OK): - _lgr.error(str('Could not load exported tests from [', path, ']. Error code: ', result)) + if result != OK: + _lgr.error(str("Could not load exported tests from [", path, "]. Error code: ", result)) else: var sections = f.get_sections() for key in sections: @@ -276,39 +285,48 @@ func import_tests(path): success = true return success + func get_script_named(name): - return _utils.search_array(scripts, 'get_filename_and_inner', name) + return _utils.search_array(scripts, "get_filename_and_inner", name) + func get_test_named(script_name, test_name): var s = get_script_named(script_name) - if(s != null): + if s != null: return s.get_test_named(test_name) else: return null + func to_s(): - var to_return = '' + var to_return = "" for i in range(scripts.size()): to_return += scripts[i].to_s() + "\n" return to_return + # --------------------- # Accessors # --------------------- func get_logger(): return _lgr + func set_logger(logger): _lgr = logger + func get_test_prefix(): return _test_prefix + func set_test_prefix(test_prefix): _test_prefix = test_prefix + func get_test_class_prefix(): return _test_class_prefix + func set_test_class_prefix(test_class_prefix): _test_class_prefix = test_class_prefix diff --git a/addons/gut/thing_counter.gd b/addons/gut/thing_counter.gd index a9b0b48..ae99b3b 100644 --- a/addons/gut/thing_counter.gd +++ b/addons/gut/thing_counter.gd @@ -1,29 +1,35 @@ var things = {} + func get_unique_count(): return things.size() + func add(thing): - if(things.has(thing)): + if things.has(thing): things[thing] += 1 else: things[thing] = 1 + func has(thing): return things.has(thing) + func get(thing): var to_return = 0 - if(things.has(thing)): + if things.has(thing): to_return = things[thing] return to_return + func sum(): var count = 0 for key in things: count += things[key] return count + func to_s(): var to_return = "" for key in things: @@ -31,13 +37,15 @@ func to_s(): to_return += str("sum: ", sum()) return to_return + func get_max_count(): var max_val = null for key in things: - if(max_val == null or things[key] > max_val): + if max_val == null or things[key] > max_val: max_val = things[key] return max_val + func add_array_items(array): for i in range(array.size()): add(array[i]) diff --git a/addons/gut/utils.gd b/addons/gut/utils.gd index 3263ca9..9c57ab0 100644 --- a/addons/gut/utils.gd +++ b/addons/gut/utils.gd @@ -33,11 +33,13 @@ # ############################################################################## extends Node + # ------------------------------------------------------------------------------ # The instance name as a function since you can't have static variables. # ------------------------------------------------------------------------------ static func INSTANCE_NAME(): - return '__GutUtilsInstName__' + return "__GutUtilsInstName__" + # ------------------------------------------------------------------------------ # Gets the root node without having to be in the tree and pushing out an error @@ -45,12 +47,13 @@ static func INSTANCE_NAME(): # ------------------------------------------------------------------------------ static func get_root_node(): var main_loop = Engine.get_main_loop() - if(main_loop != null): + if main_loop != null: return main_loop.root else: - push_error('No Main Loop Yet') + push_error("No Main Loop Yet") return null + # ------------------------------------------------------------------------------ # Get the ONE instance of utils # Since we can't have static variables we have to store the instance in the @@ -60,52 +63,52 @@ static func get_root_node(): static func get_instance(): var the_root = get_root_node() var inst = null - if(the_root.has_node(INSTANCE_NAME())): + if the_root.has_node(INSTANCE_NAME()): inst = the_root.get_node(INSTANCE_NAME()) else: - inst = load('res://addons/gut/utils.gd').new() + inst = load("res://addons/gut/utils.gd").new() inst.set_name(INSTANCE_NAME()) the_root.add_child(inst) return inst -var Logger = load('res://addons/gut/logger.gd') # everything should use get_logger + +var Logger = load("res://addons/gut/logger.gd") # everything should use get_logger var _lgr = null var json = JSON.new() var _test_mode = false -var AutoFree = load('res://addons/gut/autofree.gd') -var Awaiter = load('res://addons/gut/awaiter.gd') -var Comparator = load('res://addons/gut/comparator.gd') -var CompareResult = load('res://addons/gut/compare_result.gd') -var DiffTool = load('res://addons/gut/diff_tool.gd') -var Doubler = load('res://addons/gut/doubler.gd') -var Gut = load('res://addons/gut/gut.gd') -var HookScript = load('res://addons/gut/hook_script.gd') -var InnerClassRegistry = load('res://addons/gut/inner_class_registry.gd') +var AutoFree = load("res://addons/gut/autofree.gd") +var Awaiter = load("res://addons/gut/awaiter.gd") +var Comparator = load("res://addons/gut/comparator.gd") +var CompareResult = load("res://addons/gut/compare_result.gd") +var DiffTool = load("res://addons/gut/diff_tool.gd") +var Doubler = load("res://addons/gut/doubler.gd") +var Gut = load("res://addons/gut/gut.gd") +var HookScript = load("res://addons/gut/hook_script.gd") +var InnerClassRegistry = load("res://addons/gut/inner_class_registry.gd") var InputFactory = load("res://addons/gut/input_factory.gd") var InputSender = load("res://addons/gut/input_sender.gd") -var JunitXmlExport = load('res://addons/gut/junit_xml_export.gd') -var MethodMaker = load('res://addons/gut/method_maker.gd') -var OneToMany = load('res://addons/gut/one_to_many.gd') -var OrphanCounter = load('res://addons/gut/orphan_counter.gd') -var ParameterFactory = load('res://addons/gut/parameter_factory.gd') -var ParameterHandler = load('res://addons/gut/parameter_handler.gd') -var Printers = load('res://addons/gut/printers.gd') -var ResultExporter = load('res://addons/gut/result_exporter.gd') -var ScriptCollector = load('res://addons/gut/script_parser.gd') -var Spy = load('res://addons/gut/spy.gd') -var Strutils = load('res://addons/gut/strutils.gd') -var Stubber = load('res://addons/gut/stubber.gd') -var StubParams = load('res://addons/gut/stub_params.gd') -var Summary = load('res://addons/gut/summary.gd') -var Test = load('res://addons/gut/test.gd') -var TestCollector = load('res://addons/gut/test_collector.gd') -var ThingCounter = load('res://addons/gut/thing_counter.gd') - +var JunitXmlExport = load("res://addons/gut/junit_xml_export.gd") +var MethodMaker = load("res://addons/gut/method_maker.gd") +var OneToMany = load("res://addons/gut/one_to_many.gd") +var OrphanCounter = load("res://addons/gut/orphan_counter.gd") +var ParameterFactory = load("res://addons/gut/parameter_factory.gd") +var ParameterHandler = load("res://addons/gut/parameter_handler.gd") +var Printers = load("res://addons/gut/printers.gd") +var ResultExporter = load("res://addons/gut/result_exporter.gd") +var ScriptCollector = load("res://addons/gut/script_parser.gd") +var Spy = load("res://addons/gut/spy.gd") +var Strutils = load("res://addons/gut/strutils.gd") +var Stubber = load("res://addons/gut/stubber.gd") +var StubParams = load("res://addons/gut/stub_params.gd") +var Summary = load("res://addons/gut/summary.gd") +var Test = load("res://addons/gut/test.gd") +var TestCollector = load("res://addons/gut/test_collector.gd") +var ThingCounter = load("res://addons/gut/thing_counter.gd") # Source of truth for the GUT version -var version = '7.4.1' +var version = "7.4.1" # The required Godot version as an array. var req_godot = [3, 2, 0] @@ -131,15 +134,19 @@ var non_super_methods = [ func _ready() -> void: _http_request_latest_version() + func _http_request_latest_version() -> void: return var http_request = HTTPRequest.new() http_request.name = "http_request" add_child(http_request) - http_request.connect("request_completed",Callable(self,"_on_http_request_latest_version_completed")) + http_request.connect( + "request_completed", Callable(self, "_on_http_request_latest_version_completed") + ) # Perform a GET request. The URL below returns JSON as of writing. var __error = http_request.request("https://api.github.com/repos/bitwes/Gut/releases/latest") + func _on_http_request_latest_version_completed(result, response_code, headers, body): if not result == HTTPRequest.RESULT_SUCCESS: return @@ -155,29 +162,24 @@ func _on_http_request_latest_version_completed(result, response_code, headers, b should_display_latest_version = true - -const GUT_METADATA = '__gutdbl' +const GUT_METADATA = "__gutdbl" # Note, these cannot change since places are checking for TYPE_INT to determine # how to process parameters. -enum DOUBLE_STRATEGY{ - SCRIPT_ONLY, - INCLUDE_SUPER -} +enum DOUBLE_STRATEGY { SCRIPT_ONLY, INCLUDE_SUPER } + +enum DIFF { DEEP, SHALLOW, SIMPLE } -enum DIFF { - DEEP, - SHALLOW, - SIMPLE -} # ------------------------------------------------------------------------------ # Blurb of text with GUT and Godot versions. # ------------------------------------------------------------------------------ func get_version_text(): var v_info = Engine.get_version_info() - var gut_version_info = str('GUT version: ', version) - var godot_version_info = str('Godot version: ', v_info.major, '.', v_info.minor, '.', v_info.patch) + var gut_version_info = str("GUT version: ", version) + var godot_version_info = str( + "Godot version: ", v_info.major, ".", v_info.minor, ".", v_info.patch + ) return godot_version_info + "\n" + gut_version_info @@ -185,24 +187,26 @@ func get_version_text(): # Returns a nice string for erroring out when we have a bad Godot version. # ------------------------------------------------------------------------------ func get_bad_version_text(): - var ver = '.'.join(PackedStringArray(req_godot)) + var ver = ".".join(PackedStringArray(req_godot)) var info = Engine.get_version_info() - var gd_version = str(info.major, '.', info.minor, '.', info.patch) - return 'GUT ' + version + ' requires Godot ' + ver + ' or greater. Godot version is ' + gd_version + var gd_version = str(info.major, ".", info.minor, ".", info.patch) + return ( + "GUT " + version + " requires Godot " + ver + " or greater. Godot version is " + gd_version + ) # ------------------------------------------------------------------------------ # Checks the Godot version against req_godot array. # ------------------------------------------------------------------------------ -func is_version_ok(engine_info=Engine.get_version_info(),required=req_godot): +func is_version_ok(engine_info = Engine.get_version_info(), required = req_godot): var is_ok = null var engine_array = [engine_info.major, engine_info.minor, engine_info.patch] var idx = 0 - while(is_ok == null and idx < engine_array.size()): - if(engine_array[idx] > required[idx]): + while is_ok == null and idx < engine_array.size(): + if engine_array[idx] > required[idx]: is_ok = true - elif(engine_array[idx] < required[idx]): + elif engine_array[idx] < required[idx]: is_ok = false idx += 1 @@ -211,21 +215,21 @@ func is_version_ok(engine_info=Engine.get_version_info(),required=req_godot): return nvl(is_ok, true) -func godot_version(engine_info=Engine.get_version_info()): - return str(engine_info.major, '.', engine_info.minor, '.', engine_info.patch) +func godot_version(engine_info = Engine.get_version_info()): + return str(engine_info.major, ".", engine_info.minor, ".", engine_info.patch) -func is_godot_version(expected, engine_info=Engine.get_version_info()): +func is_godot_version(expected, engine_info = Engine.get_version_info()): var engine_array = [engine_info.major, engine_info.minor, engine_info.patch] - var expected_array = expected.split('.') + var expected_array = expected.split(".") - if(expected_array.size() > engine_array.size()): + if expected_array.size() > engine_array.size(): return false var is_version = true var i = 0 - while(i < expected_array.size() and i < engine_array.size() and is_version): - if(expected_array[i] == str(engine_array[i])): + while i < expected_array.size() and i < engine_array.size() and is_version: + if expected_array[i] == str(engine_array[i]): i += 1 else: is_version = false @@ -233,8 +237,8 @@ func is_godot_version(expected, engine_info=Engine.get_version_info()): return is_version -func is_godot_version_gte(expected, engine_info=Engine.get_version_info()): - return is_version_ok(engine_info, expected.split('.')) +func is_godot_version_gte(expected, engine_info = Engine.get_version_info()): + return is_version_ok(engine_info, expected.split(".")) # ------------------------------------------------------------------------------ @@ -244,20 +248,19 @@ func is_godot_version_gte(expected, engine_info=Engine.get_version_info()): # are not caused by getting bad warn/error/etc counts. # ------------------------------------------------------------------------------ func get_logger(): - if(_test_mode): + if _test_mode: return Logger.new() else: - if(_lgr == null): + if _lgr == null: _lgr = Logger.new() return _lgr - # ------------------------------------------------------------------------------ # return if_null if value is null otherwise return value # ------------------------------------------------------------------------------ func nvl(value, if_null): - if(value == null): + if value == null: return if_null else: return value @@ -272,7 +275,7 @@ func nvl(value, if_null): # ------------------------------------------------------------------------------ func is_freed(obj): var wr = weakref(obj) - return !(wr.get_ref() and str(obj) != '') + return !(wr.get_ref() and str(obj) != "") # ------------------------------------------------------------------------------ @@ -287,8 +290,8 @@ func is_not_freed(obj): # ------------------------------------------------------------------------------ func is_double(obj): var to_return = false - if(typeof(obj) == TYPE_OBJECT and is_instance_valid(obj)): - to_return = obj.has_method('__gutdbl_check_method__') + if typeof(obj) == TYPE_OBJECT and is_instance_valid(obj): + to_return = obj.has_method("__gutdbl_check_method__") return to_return @@ -296,13 +299,19 @@ func is_double(obj): # Checks if the passed in is an instance of a class # ------------------------------------------------------------------------------ func is_instance(obj): - return typeof(obj) == TYPE_OBJECT and !is_native_class(obj) and !obj.has_method('new') and !obj.has_method('instantiate') + return ( + typeof(obj) == TYPE_OBJECT + and !is_native_class(obj) + and !obj.has_method("new") + and !obj.has_method("instantiate") + ) + # ------------------------------------------------------------------------------ # Checks if the passed in is a GDScript # ------------------------------------------------------------------------------ func is_gdscript(obj): - return typeof(obj) == TYPE_OBJECT and str(obj).begins_with('= 0): + while count >= 0: temp = decimal_value >> count - if(temp & 1): + if temp & 1: binary_string = binary_string + "1" else: binary_string = binary_string + "0" @@ -464,28 +476,31 @@ func dec2bistr(decimal_value, max_bits = 31): func add_line_numbers(contents): - if(contents == null): - return '' + if contents == null: + return "" var to_return = "" var lines = contents.split("\n") var line_num = 1 for line in lines: - var line_str = str(line_num).lpad(6, ' ') - to_return += str(line_str, ' |', line, "\n") + var line_str = str(line_num).lpad(6, " ") + to_return += str(line_str, " |", line, "\n") line_num += 1 return to_return -func pp(dict, indent=''): - var text = json.stringify(dict, ' ') + +func pp(dict, indent = ""): + var text = json.stringify(dict, " ") print(text) var _created_script_count = 0 -func create_script_from_source(source, override_path=null): + + +func create_script_from_source(source, override_path = null): _created_script_count += 1 - var r_path = ''#str('workaround for godot issue #65263 (', _created_script_count, ')') - if(override_path != null): + var r_path = "" #str('workaround for godot issue #65263 (', _created_script_count, ')') + if override_path != null: r_path = override_path var DynamicScript = GDScript.new() @@ -505,14 +520,17 @@ func get_scene_script_object(scene): var root_node_path = NodePath(".") var node_idx = 0 - while(node_idx < state.get_node_count() and to_return == null): + while node_idx < state.get_node_count() and to_return == null: # Assumes that the first node we encounter that has a root node path, one # property, and that property is named 'script' is the GDScript for the # scene. This could be flawed. - if(state.get_node_path(node_idx) == root_node_path and state.get_node_property_count(node_idx) == 1): - if(state.get_node_property_name(node_idx, 0) == 'script'): + if ( + state.get_node_path(node_idx) == root_node_path + and state.get_node_property_count(node_idx) == 1 + ): + if state.get_node_property_name(node_idx, 0) == "script": to_return = state.get_node_property_value(node_idx, 0) node_idx += 1 - return to_return \ No newline at end of file + return to_return diff --git a/test/integration/terminal.test.gd b/test/integration/terminal.test.gd index d0e8b7b..f05e544 100644 --- a/test/integration/terminal.test.gd +++ b/test/integration/terminal.test.gd @@ -71,16 +71,15 @@ class TestTheme: func _get_pixelv(src: Vector2) -> Color: var screen := get_tree().root.get_texture().get_data() - false # screen.lock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed + false # screen.lock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed screen.flip_y() var pixel := screen.get_pixelv(src) - false # screen.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed + false # screen.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed return pixel func _check_colors(theme: Theme): var cell_size := Vector2( - int(terminal.size.x / terminal.get_cols()), - int(terminal.size.y / terminal.get_rows()) + int(terminal.size.x / terminal.get_cols()), int(terminal.size.y / terminal.get_rows()) ) var src := cell_size / 2 diff --git a/test/platform/unix/unix.test.gd b/test/platform/unix/unix.test.gd index 7588882..641333b 100644 --- a/test/platform/unix/unix.test.gd +++ b/test/platform/unix/unix.test.gd @@ -137,7 +137,7 @@ func test_emits_exited_signal_when_child_process_exits(): class Helper: static func _get_pts() -> Array: - assert(false) #,"Abstract method") + assert(false) #,"Abstract method") return [] static func _get_winsize(fd: int) -> Dictionary: @@ -161,7 +161,7 @@ class Helper: true, output ) - assert(exit_code == 0) #,"Failed to run python command for this test.") + assert(exit_code == 0) #,"Failed to run python command for this test.") var size = str_to_var("Vector2" + output[0].strip_edges()) return {rows = int(size.x), cols = int(size.y)} @@ -228,8 +228,8 @@ class LinuxHelper: static func _get_pts() -> Array: var dir := Directory.new() - if dir.open("/dev/pts") != OK or dir.list_dir_begin() != OK:# TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547 - assert(false) #,"Could not open /dev/pts.") + if dir.open("/dev/pts") != OK or dir.list_dir_begin() != OK: # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547 + assert(false) #,"Could not open /dev/pts.") var pts := [] var file_name: String = dir.get_next() @@ -249,5 +249,5 @@ class MacOSHelper: # TODO: Implement for macOS. # On macOS there is no /dev/pts directory, rather new ptys are created # under /dev/ttysXYZ. - assert(false) #,"Not implemented") + assert(false) #,"Not implemented") return []