From 7ad82a56663c4f46ed2790a5f779d4a66ad91496 Mon Sep 17 00:00:00 2001 From: Nullpointer Date: Sat, 30 Nov 2024 14:07:39 +0100 Subject: [PATCH] GD-605: Fixes the CMD tool to collect multipe command arguments (#606) # Why The CMD tool had an issue to collect all given arguments. e.g. using --add or --i multiple times it only applyes the first argument example: `./addons/gdUnit4/runtest.sh --add res://addons/gdUnit4/test/core/parse/ --add res://addons/gdUnit4/test/asserts/GdUnitAssertImplTest.gd -i GdDefaultValueDecoderTest -i GdScriptParserTest` # What - fixes the root cause on `CmdCommandHandler#execute` to call the correct callable to handle collected arguments - add register callback validations to the handler - code formattings - remove obsolete code `_enhanced_fr_test ` --- addons/gdUnit4/bin/GdUnitCmdTool.gd | 12 +- addons/gdUnit4/src/cmd/CmdCommandHandler.gd | 82 +++++++++----- addons/gdUnit4/src/core/GdUnitRunnerConfig.gd | 30 ++--- .../src/core/command/GdUnitCommandHandler.gd | 64 +++++------ .../gdUnit4/test/cmd/CmdCommandHandlerTest.gd | 106 ++++++++++++------ addons/gdUnit4/test/cmd/runtestDebug.tscn | 2 +- .../test/core/GdUnitRunnerConfigTest.gd | 6 +- 7 files changed, 184 insertions(+), 118 deletions(-) diff --git a/addons/gdUnit4/bin/GdUnitCmdTool.gd b/addons/gdUnit4/bin/GdUnitCmdTool.gd index 170102e7..21c7a47e 100644 --- a/addons/gdUnit4/bin/GdUnitCmdTool.gd +++ b/addons/gdUnit4/bin/GdUnitCmdTool.gd @@ -312,12 +312,12 @@ class CLIRunner: commands.append_array(result.value() as Array) result = ( CmdCommandHandler.new(_cmd_options) - .register_cb("-help", Callable(self, "show_help")) - .register_cb("--help-advanced", Callable(self, "show_advanced_help")) - .register_cb("-a", Callable(_runner_config, "add_test_suite")) - .register_cbv("-a", Callable(_runner_config, "add_test_suites")) - .register_cb("-i", Callable(_runner_config, "skip_test_suite")) - .register_cbv("-i", Callable(_runner_config, "skip_test_suites")) + .register_cb("-help", show_help) + .register_cb("--help-advanced", show_advanced_help) + .register_cb("-a", _runner_config.add_test_suite) + .register_cbv("-a", _runner_config.add_test_suites) + .register_cb("-i", _runner_config.skip_test_suite) + .register_cbv("-i", _runner_config.skip_test_suites) .register_cb("-rd", set_report_dir) .register_cb("-rc", set_report_count) .register_cb("--selftest", run_self_test) diff --git a/addons/gdUnit4/src/cmd/CmdCommandHandler.gd b/addons/gdUnit4/src/cmd/CmdCommandHandler.gd index a11c7bcf..2a7ed553 100644 --- a/addons/gdUnit4/src/cmd/CmdCommandHandler.gd +++ b/addons/gdUnit4/src/cmd/CmdCommandHandler.gd @@ -10,26 +10,28 @@ var _cmd_options :CmdOptions # Dictionary[String, Array[Callback] var _command_cbs :Dictionary -# we only able to check cb function name since Godot 3.3.x -var _enhanced_fr_test := false func _init(cmd_options: CmdOptions) -> void: _cmd_options = cmd_options - var major: int = Engine.get_version_info()["major"] - var minor: int = Engine.get_version_info()["minor"] - if major == 3 and minor == 3: - _enhanced_fr_test = true # register a callback function for given command # cmd_name short name of the command # fr_arg a funcref to a function with a single argument -func register_cb(cmd_name: String, cb: Callable = NO_CB) -> CmdCommandHandler: +func register_cb(cmd_name: String, cb: Callable) -> CmdCommandHandler: var registered_cb: Array = _command_cbs.get(cmd_name, [NO_CB, NO_CB]) if registered_cb[CB_SINGLE_ARG]: push_error("A function for command '%s' is already registered!" % cmd_name) return self + + if not _validate_cb_signature(cb, TYPE_STRING): + push_error( + ("The callback '%s:%s' for command '%s' has invalid function signature. " + +"The callback signature must be 'func name(value: PackedStringArray)'") + % [cb.get_object().get_class(), cb.get_method(), cmd_name]) + return null + registered_cb[CB_SINGLE_ARG] = cb _command_cbs[cmd_name] = registered_cb return self @@ -42,15 +44,23 @@ func register_cbv(cmd_name: String, cb: Callable) -> CmdCommandHandler: if registered_cb[CB_MULTI_ARGS]: push_error("A function for command '%s' is already registered!" % cmd_name) return self + + if not _validate_cb_signature(cb, TYPE_PACKED_STRING_ARRAY): + push_error( + ("The callback '%s:%s' for command '%s' has invalid function signature. " + +"The callback signature must be 'func name(value: PackedStringArray)'") + % [cb.get_object().get_class(), cb.get_method(), cmd_name]) + return null + registered_cb[CB_MULTI_ARGS] = cb _command_cbs[cmd_name] = registered_cb return self func _validate() -> GdUnitResult: - var errors: = PackedStringArray() + var errors := PackedStringArray() # Dictionary[StringName, String] - var registered_cbs: = Dictionary() + var registered_cbs := Dictionary() for cmd_name in _command_cbs.keys() as Array[String]: var cb: Callable = (_command_cbs[cmd_name][CB_SINGLE_ARG] @@ -63,8 +73,8 @@ func _validate() -> GdUnitResult: @warning_ignore("return_value_discarded") errors.append("The command '%s' is unknown, verify your CmdOptions!" % cmd_name) # verify for multiple registered command callbacks - if _enhanced_fr_test and cb != NO_CB: - var cb_method: = cb.get_method() + if cb != NO_CB: + var cb_method := cb.get_method() if registered_cbs.has(cb_method): var already_registered_cmd :String = registered_cbs[cb_method] @warning_ignore("return_value_discarded") @@ -76,33 +86,51 @@ func _validate() -> GdUnitResult: return GdUnitResult.error("\n".join(errors)) -func execute(commands :Array[CmdCommand]) -> GdUnitResult: +func execute(commands: Array[CmdCommand]) -> GdUnitResult: var result := _validate() if result.is_error(): return result for cmd in commands: var cmd_name := cmd.name() if _command_cbs.has(cmd_name): - var cb_s :Callable = _command_cbs.get(cmd_name)[CB_SINGLE_ARG] + var cb_s: Callable = _command_cbs.get(cmd_name)[CB_SINGLE_ARG] var arguments := cmd.arguments() var cmd_option := _cmd_options.get_option(cmd_name) - if cb_s and arguments.size() == 0: + + if arguments.is_empty(): cb_s.call() - elif cb_s: + elif arguments.size() > 1: + var cb_m: Callable = _command_cbs.get(cmd_name)[CB_MULTI_ARGS] + cb_m.call(arguments) + else: if cmd_option.type() == TYPE_BOOL: cb_s.call(true if arguments[0] == "true" else false) else: cb_s.call(arguments[0]) - else: - var cb_m :Callable = _command_cbs.get(cmd_name)[CB_MULTI_ARGS] - # we need to find the method and determin the arguments to call the right function - for m in cb_m.get_object().get_method_list(): - if m["name"] == cb_m.get_method(): - @warning_ignore("unsafe_cast") - if (m["args"] as Array).size() > 1: - cb_m.callv(arguments) - break - else: - cb_m.call(arguments) - break + return GdUnitResult.success(true) + + +func _validate_cb_signature(cb: Callable, arg_type: int) -> bool: + for m in cb.get_object().get_method_list(): + if m["name"] == cb.get_method(): + @warning_ignore("unsafe_cast") + return _validate_func_arguments(m["args"] as Array, arg_type) + return true + + +func _validate_func_arguments(arguments: Array, arg_type: int) -> bool: + # validate we have a single argument + if arguments.size() > 1: + return false + # a cb with no arguments is also valid + if arguments.size() == 0: + return true + # validate argument type + var arg: Dictionary = arguments[0] + @warning_ignore("unsafe_cast") + if arg["usage"] as int == PROPERTY_USAGE_NIL_IS_VARIANT: + return true + if arg["type"] != arg_type: + return false + return true diff --git a/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd b/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd index 820f2482..205d4e5b 100644 --- a/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd +++ b/addons/gdUnit4/src/core/GdUnitRunnerConfig.gd @@ -8,7 +8,7 @@ const VERSION = "version" const INCLUDED = "included" const SKIPPED = "skipped" const SERVER_PORT = "server_port" -const EXIT_FAIL_FAST ="exit_on_first_fail" +const EXIT_FAIL_FAST = "exit_on_first_fail" const CONFIG_FILE = "res://addons/gdUnit4/GdUnitRunner.cfg" @@ -29,7 +29,7 @@ func clear() -> GdUnitRunnerConfig: return self -func set_server_port(port :int) -> GdUnitRunnerConfig: +func set_server_port(port: int) -> GdUnitRunnerConfig: _config[SERVER_PORT] = port return self @@ -45,22 +45,22 @@ func self_test() -> GdUnitRunnerConfig: return self -func add_test_suite(p_resource_path :String) -> GdUnitRunnerConfig: +func add_test_suite(p_resource_path: String) -> GdUnitRunnerConfig: var to_execute_ := to_execute() to_execute_[p_resource_path] = to_execute_.get(p_resource_path, PackedStringArray()) return self -func add_test_suites(resource_paths :PackedStringArray) -> GdUnitRunnerConfig: +func add_test_suites(resource_paths: PackedStringArray) -> GdUnitRunnerConfig: for resource_path_ in resource_paths: @warning_ignore("return_value_discarded") add_test_suite(resource_path_) return self -func add_test_case(p_resource_path :String, test_name :StringName, test_param_index :int = -1) -> GdUnitRunnerConfig: +func add_test_case(p_resource_path: String, test_name: String, test_param_index: int = -1) -> GdUnitRunnerConfig: var to_execute_ := to_execute() - var test_cases :PackedStringArray = to_execute_.get(p_resource_path, PackedStringArray()) + var test_cases: PackedStringArray = to_execute_.get(p_resource_path, PackedStringArray()) if test_param_index != -1: @warning_ignore("return_value_discarded") test_cases.append("%s:%d" % [test_name, test_param_index]) @@ -75,7 +75,7 @@ func add_test_case(p_resource_path :String, test_name :StringName, test_param_in # [:] # '/path/path', res://path/path', 'res://path/path/testsuite.gd' or 'testsuite' # 'res://path/path/testsuite.gd:test_case' or 'testsuite:test_case' -func skip_test_suite(value :StringName) -> GdUnitRunnerConfig: +func skip_test_suite(value: String) -> GdUnitRunnerConfig: var parts: PackedStringArray = GdUnitFileAccess.make_qualified_path(value).rsplit(":") if parts[0] == "res": parts.remove_at(0) @@ -85,20 +85,20 @@ func skip_test_suite(value :StringName) -> GdUnitRunnerConfig: skipped()[parts[0]] = PackedStringArray() 2: @warning_ignore("return_value_discarded") - skip_test_case(parts[0], parts[1]) + _skip_test_case(parts[0], parts[1]) return self -func skip_test_suites(resource_paths :PackedStringArray) -> GdUnitRunnerConfig: +func skip_test_suites(resource_paths: PackedStringArray) -> GdUnitRunnerConfig: for resource_path_ in resource_paths: @warning_ignore("return_value_discarded") skip_test_suite(resource_path_) return self -func skip_test_case(p_resource_path :String, test_name :StringName) -> GdUnitRunnerConfig: +func _skip_test_case(p_resource_path: String, test_name: String) -> GdUnitRunnerConfig: var to_ignore := skipped() - var test_cases :PackedStringArray = to_ignore.get(p_resource_path, PackedStringArray()) + var test_cases: PackedStringArray = to_ignore.get(p_resource_path, PackedStringArray()) @warning_ignore("return_value_discarded") test_cases.append(test_name) to_ignore[p_resource_path] = test_cases @@ -114,7 +114,7 @@ func skipped() -> Dictionary: return _config.get(SKIPPED, {}) -func save_config(path :String = CONFIG_FILE) -> GdUnitResult: +func save_config(path: String = CONFIG_FILE) -> GdUnitResult: var file := FileAccess.open(path, FileAccess.WRITE) if file == null: var error := FileAccess.get_open_error() @@ -124,7 +124,7 @@ func save_config(path :String = CONFIG_FILE) -> GdUnitResult: return GdUnitResult.success(path) -func load_config(path :String = CONFIG_FILE) -> GdUnitResult: +func load_config(path: String = CONFIG_FILE) -> GdUnitResult: if not FileAccess.file_exists(path): return GdUnitResult.error("Can't find test runner configuration '%s'! Please select a test to run." % path) var file := FileAccess.open(path, FileAccess.READ) @@ -148,13 +148,13 @@ func load_config(path :String = CONFIG_FILE) -> GdUnitResult: @warning_ignore("unsafe_cast") func fix_value_types() -> void: # fix float value to int json stores all numbers as float - var server_port_ :int = _config.get(SERVER_PORT, -1) + var server_port_: int = _config.get(SERVER_PORT, -1) _config[SERVER_PORT] = server_port_ convert_Array_to_PackedStringArray(_config[INCLUDED] as Dictionary) convert_Array_to_PackedStringArray(_config[SKIPPED] as Dictionary) -func convert_Array_to_PackedStringArray(data :Dictionary) -> void: +func convert_Array_to_PackedStringArray(data: Dictionary) -> void: for key in data.keys() as Array[String]: var values :Array = data[key] data[key] = PackedStringArray(values) diff --git a/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd b/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd index 6f4c1251..fa24abdd 100644 --- a/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd +++ b/addons/gdUnit4/src/core/command/GdUnitCommandHandler.gd @@ -34,13 +34,13 @@ const SETTINGS_SHORTCUT_MAPPING := { var _runner_config := GdUnitRunnerConfig.new() # holds the current connected gdUnit runner client id -var _client_id :int +var _client_id: int # if no debug mode we have an process id -var _current_runner_process_id :int = 0 +var _current_runner_process_id: int = 0 # hold is current an test running -var _is_running :bool = false +var _is_running: bool = false # holds if the current running tests started in debug mode -var _running_debug_mode :bool +var _running_debug_mode: bool var _commands := {} var _shortcuts := {} @@ -82,7 +82,7 @@ func _init() -> void: timer.timeout.connect(cmd_discover_tests) -func _notification(what :int) -> void: +func _notification(what: int) -> void: if what == NOTIFICATION_PREDELETE: _commands.clear() _shortcuts.clear() @@ -104,16 +104,16 @@ func is_test_running_but_stop_pressed() -> bool: return _running_debug_mode and _is_running and not EditorInterface.is_playing_scene() -func assert_shortcut_mappings(mappings :Dictionary) -> void: - for shortcut :int in GdUnitShortcut.ShortCut.values(): +func assert_shortcut_mappings(mappings: Dictionary) -> void: + for shortcut: int in GdUnitShortcut.ShortCut.values(): assert(mappings.values().has(shortcut), "missing settings mapping for shortcut '%s'!" % GdUnitShortcut.ShortCut.keys()[shortcut]) func init_shortcuts() -> void: - for shortcut :int in GdUnitShortcut.ShortCut.values(): + for shortcut: int in GdUnitShortcut.ShortCut.values(): if shortcut == GdUnitShortcut.ShortCut.NONE: continue - var property_name :String = SETTINGS_SHORTCUT_MAPPING.find_key(shortcut) + var property_name: String = SETTINGS_SHORTCUT_MAPPING.find_key(shortcut) var property := GdUnitSettings.get_property(property_name) var keys := GdUnitShortcut.default_keys(shortcut) if property != null: @@ -123,7 +123,7 @@ func init_shortcuts() -> void: func create_shortcut_input_even(key_codes: PackedInt32Array) -> InputEventKey: - var inputEvent :InputEventKey = InputEventKey.new() + var inputEvent := InputEventKey.new() inputEvent.pressed = true for key_code in key_codes: match key_code: @@ -139,35 +139,35 @@ func create_shortcut_input_even(key_codes: PackedInt32Array) -> InputEventKey: return inputEvent -func register_shortcut(p_shortcut :GdUnitShortcut.ShortCut, p_input_event :InputEvent) -> void: +func register_shortcut(p_shortcut: GdUnitShortcut.ShortCut, p_input_event: InputEvent) -> void: GdUnitTools.prints_verbose("register shortcut: '%s' to '%s'" % [GdUnitShortcut.ShortCut.keys()[p_shortcut], p_input_event.as_text()]) var shortcut := Shortcut.new() shortcut.set_events([p_input_event]) - var command_name :String = get_shortcut_command(p_shortcut) + var command_name := get_shortcut_command(p_shortcut) _shortcuts[p_shortcut] = GdUnitShortcutAction.new(p_shortcut, shortcut, command_name) -func get_shortcut(shortcut_type :GdUnitShortcut.ShortCut) -> Shortcut: +func get_shortcut(shortcut_type: GdUnitShortcut.ShortCut) -> Shortcut: return get_shortcut_action(shortcut_type).shortcut -func get_shortcut_action(shortcut_type :GdUnitShortcut.ShortCut) -> GdUnitShortcutAction: +func get_shortcut_action(shortcut_type: GdUnitShortcut.ShortCut) -> GdUnitShortcutAction: return _shortcuts.get(shortcut_type) -func get_shortcut_command(p_shortcut :GdUnitShortcut.ShortCut) -> String: +func get_shortcut_command(p_shortcut: GdUnitShortcut.ShortCut) -> String: return GdUnitShortcut.CommandMapping.get(p_shortcut, "unknown command") -func register_command(p_command :GdUnitCommand) -> void: +func register_command(p_command: GdUnitCommand) -> void: _commands[p_command.name] = p_command -func command(cmd_name :String) -> GdUnitCommand: +func command(cmd_name: String) -> GdUnitCommand: return _commands.get(cmd_name) -func cmd_run_test_suites(test_suite_paths :PackedStringArray, debug :bool, rerun := false) -> void: +func cmd_run_test_suites(test_suite_paths: PackedStringArray, debug: bool, rerun := false) -> void: # create new runner runner_config for fresh run otherwise use saved one if not rerun: var result := _runner_config.clear()\ @@ -179,7 +179,7 @@ func cmd_run_test_suites(test_suite_paths :PackedStringArray, debug :bool, rerun cmd_run(debug) -func cmd_run_test_case(test_suite_resource_path :String, test_case :String, test_param_index :int, debug :bool, rerun := false) -> void: +func cmd_run_test_case(test_suite_resource_path: String, test_case: String, test_param_index: int, debug: bool, rerun := false) -> void: # create new runner config for fresh run otherwise use saved one if not rerun: var result := _runner_config.clear()\ @@ -191,8 +191,8 @@ func cmd_run_test_case(test_suite_resource_path :String, test_case :String, test cmd_run(debug) -func cmd_run_overall(debug :bool) -> void: - var test_suite_paths :PackedStringArray = GdUnitCommandHandler.scan_test_directorys("res://" , GdUnitSettings.test_root_folder(), []) +func cmd_run_overall(debug: bool) -> void: + var test_suite_paths: PackedStringArray = GdUnitCommandHandler.scan_test_directorys("res://" , GdUnitSettings.test_root_folder(), []) var result := _runner_config.clear()\ .add_test_suites(test_suite_paths)\ .save_config() @@ -202,7 +202,7 @@ func cmd_run_overall(debug :bool) -> void: cmd_run(debug) -func cmd_run(debug :bool) -> void: +func cmd_run(debug: bool) -> void: # don't start is already running if _is_running: return @@ -223,7 +223,7 @@ func cmd_run(debug :bool) -> void: run_release_mode() -func cmd_stop(client_id :int) -> void: +func cmd_stop(client_id: int) -> void: # don't stop if is already stopped if not _is_running: return @@ -231,7 +231,7 @@ func cmd_stop(client_id :int) -> void: gdunit_runner_stop.emit(client_id) if _running_debug_mode: EditorInterface.stop_playing_scene() - else: if _current_runner_process_id > 0: + elif _current_runner_process_id > 0: if OS.is_process_running(_current_runner_process_id): var result := OS.kill(_current_runner_process_id) if result != OK: @@ -239,7 +239,7 @@ func cmd_stop(client_id :int) -> void: _current_runner_process_id = -1 -func cmd_editor_run_test(debug :bool) -> void: +func cmd_editor_run_test(debug: bool) -> void: var cursor_line := active_base_editor().get_caret_line() #run test case? var regex := RegEx.new() @@ -274,7 +274,7 @@ func cmd_discover_tests() -> void: await GdUnitTestDiscoverer.run() -static func scan_test_directorys(base_directory :String, test_directory: String, test_suite_paths :PackedStringArray) -> PackedStringArray: +static func scan_test_directorys(base_directory: String, test_directory: String, test_suite_paths: PackedStringArray) -> PackedStringArray: print_verbose("Scannning for test directory '%s' at %s" % [test_directory, base_directory]) for directory in DirAccess.get_directories_at(base_directory): if directory.begins_with("."): @@ -291,11 +291,11 @@ static func scan_test_directorys(base_directory :String, test_directory: String, return test_suite_paths -static func normalize_path(path :String) -> String: +static func normalize_path(path: String) -> String: return path.replace("///", "//") -static func match_test_directory(directory :String, test_directory: String) -> bool: +static func match_test_directory(directory: String, test_directory: String) -> bool: return directory == test_directory or test_directory.is_empty() or test_directory == "/" or test_directory == "res://" @@ -328,7 +328,7 @@ func active_script() -> Script: ################################################################################ # signals handles ################################################################################ -func _on_event(event :GdUnitEvent) -> void: +func _on_event(event: GdUnitEvent) -> void: if event.type() == GdUnitEvent.STOP: cmd_stop(_client_id) @@ -345,7 +345,7 @@ func _on_run_overall_pressed(_debug := false) -> void: cmd_run_overall(true) -func _on_settings_changed(property :GdUnitProperty) -> void: +func _on_settings_changed(property: GdUnitProperty) -> void: if SETTINGS_SHORTCUT_MAPPING.has(property.name()): var shortcut :GdUnitShortcut.ShortCut = SETTINGS_SHORTCUT_MAPPING.get(property.name()) var value: PackedInt32Array = property.value() @@ -361,11 +361,11 @@ func _on_settings_changed(property :GdUnitProperty) -> void: ################################################################################ # Network stuff ################################################################################ -func _on_client_connected(client_id :int) -> void: +func _on_client_connected(client_id: int) -> void: _client_id = client_id -func _on_client_disconnected(client_id :int) -> void: +func _on_client_disconnected(client_id: int) -> void: # only stops is not in debug mode running and the current client if not _running_debug_mode and _client_id == client_id: cmd_stop(client_id) diff --git a/addons/gdUnit4/test/cmd/CmdCommandHandlerTest.gd b/addons/gdUnit4/test/cmd/CmdCommandHandlerTest.gd index 8f46cc88..a3ddb978 100644 --- a/addons/gdUnit4/test/cmd/CmdCommandHandlerTest.gd +++ b/addons/gdUnit4/test/cmd/CmdCommandHandlerTest.gd @@ -11,17 +11,17 @@ var _cmd_instance: TestCommands # small example of command class class TestCommands: - func cmd_a() -> String: - return "cmd_a" + func cmd_no_arg() -> String: + return "" func cmd_foo() -> String: return "cmd_foo" - func cmd_bar(value :String) -> String: + func cmd_arg(value: String) -> String: return value - func cmd_bar2(value_a: String, value_b: String) -> Array: - return [value_a, value_b] + func cmd_args(values: PackedStringArray) -> Array: + return values func cmd_x() -> String: return "cmd_x" @@ -32,8 +32,7 @@ func before() -> void: _cmd_options = CmdOptions.new([ CmdOption.new("-a", "some help text a", "some description a"), CmdOption.new("-f, --foo", "some help text foo", "some description foo"), - CmdOption.new("-b, --bar", "some help text bar", "some description bar"), - CmdOption.new("-b2, --bar2", "some help text bar", "some description bar"), + CmdOption.new("-arg, --arg", "some help text bar", "some description bar") ], # advnaced options [ @@ -42,6 +41,46 @@ func before() -> void: _cmd_instance = TestCommands.new() +func test_register_cb() -> void: + var cmd_handler: = CmdCommandHandler.new(_cmd_options) + + # register a single argumend cb + cmd_handler.register_cb("-a", _cmd_instance.cmd_arg) + assert_dict(cmd_handler._command_cbs).contains_key_value("-a", [_cmd_instance.cmd_arg, CmdCommandHandler.NO_CB]) + + +func test_register_invalid_cb() -> void: + var cmd_handler: = CmdCommandHandler.new(_cmd_options) + # try to register a multi argumend cb + cmd_handler.register_cb("-a", _cmd_instance.cmd_args) + # verify the cb is not registered + assert_dict(cmd_handler._command_cbs).is_empty() + + +func test_register_cbv() -> void: + var cmd_handler: = CmdCommandHandler.new(_cmd_options) + + # register a single argumend cb + cmd_handler.register_cbv("-a", _cmd_instance.cmd_args) + assert_dict(cmd_handler._command_cbs).contains_key_value("-a", [CmdCommandHandler.NO_CB, _cmd_instance.cmd_args]) + + +func test_register_invalid_cbv() -> void: + var cmd_handler: = CmdCommandHandler.new(_cmd_options) + # try to register a single argumend cb + cmd_handler.register_cbv("-a", _cmd_instance.cmd_arg) + # verify the cb is not registered + assert_dict(cmd_handler._command_cbs).is_empty() + + +func test_register_cb_and_cbv() -> void: + var cmd_handler: = CmdCommandHandler.new(_cmd_options) + + cmd_handler.register_cb("-a", _cmd_instance.cmd_arg) + cmd_handler.register_cbv("-a", _cmd_instance.cmd_args) + assert_dict(cmd_handler._command_cbs).contains_key_value("-a", [_cmd_instance.cmd_arg, _cmd_instance.cmd_args]) + + func test__validate_no_registerd_commands() -> void: var cmd_handler := CmdCommandHandler.new(_cmd_options) @@ -50,19 +89,19 @@ func test__validate_no_registerd_commands() -> void: func test__validate_registerd_commands() -> void: var cmd_handler: = CmdCommandHandler.new(_cmd_options) - cmd_handler.register_cb("-a", Callable(_cmd_instance, "cmd_a")) - cmd_handler.register_cb("-f", Callable(_cmd_instance, "cmd_foo")) - cmd_handler.register_cb("-b", Callable(_cmd_instance, "cmd_bar")) + cmd_handler.register_cb("-a", _cmd_instance.cmd_no_arg) + cmd_handler.register_cb("-f", _cmd_instance.cmd_foo) + cmd_handler.register_cb("-arg", _cmd_instance.cmd_arg) assert_result(cmd_handler._validate()).is_success() func test__validate_registerd_unknown_commands() -> void: var cmd_handler: = CmdCommandHandler.new(_cmd_options) - cmd_handler.register_cb("-a", Callable(_cmd_instance, "cmd_a")) - cmd_handler.register_cb("-d", Callable(_cmd_instance, "cmd_foo")) - cmd_handler.register_cb("-b", Callable(_cmd_instance, "cmd_bar")) - cmd_handler.register_cb("-y", Callable(_cmd_instance, "cmd_x")) + cmd_handler.register_cb("-a", _cmd_instance.cmd_no_arg) + cmd_handler.register_cb("-d", _cmd_instance.cmd_foo) + cmd_handler.register_cb("-arg", _cmd_instance.cmd_arg) + cmd_handler.register_cb("-y", _cmd_instance.cmd_x) assert_result(cmd_handler._validate())\ .is_error()\ @@ -71,23 +110,21 @@ func test__validate_registerd_unknown_commands() -> void: func test__validate_registerd_invalid_callbacks() -> void: var cmd_handler := CmdCommandHandler.new(_cmd_options) - cmd_handler.register_cb("-a", Callable(_cmd_instance, "cmd_a")) - cmd_handler.register_cb("-f") - cmd_handler.register_cb("-b", Callable(_cmd_instance, "cmd_not_exists")) + cmd_handler.register_cb("-a", _cmd_instance.cmd_no_arg) + cmd_handler.register_cb("-arg", Callable(_cmd_instance, "cmd_not_exists")) assert_result(cmd_handler._validate())\ .is_error()\ - .contains_message("Invalid function reference for command '-b', Check the function reference!") + .contains_message("Invalid function reference for command '-arg', Check the function reference!") func test__validate_registerd_register_same_callback_twice() -> void: var cmd_handler: = CmdCommandHandler.new(_cmd_options) - cmd_handler.register_cb("-a", Callable(_cmd_instance, "cmd_a")) - cmd_handler.register_cb("-b", Callable(_cmd_instance, "cmd_a")) - if cmd_handler._enhanced_fr_test: - assert_result(cmd_handler._validate())\ - .is_error()\ - .contains_message("The function reference 'cmd_a' already registerd for command '-a'!") + cmd_handler.register_cb("-a", _cmd_instance.cmd_no_arg) + cmd_handler.register_cb("-arg", _cmd_instance.cmd_no_arg) + assert_result(cmd_handler._validate())\ + .is_error()\ + .contains_message("The function reference 'cmd_no_arg' already registerd for command '-a'!") func test_execute_no_commands() -> void: @@ -100,24 +137,25 @@ func test_execute_commands_no_cb_registered() -> void: assert_result(cmd_handler.execute([CmdCommand.new("-a")])).is_success() +@warning_ignore("unsafe_method_access") func test_execute_commands_with_cb_registered() -> void: var cmd_handler: = CmdCommandHandler.new(_cmd_options) - var cmd_spy: Object = spy(_cmd_instance) + var cmd_spy: TestCommands = spy(_cmd_instance) - cmd_handler.register_cb("-a", Callable(cmd_spy, "cmd_a")) - cmd_handler.register_cb("-b", Callable(cmd_spy, "cmd_bar")) - cmd_handler.register_cbv("-b2", Callable(cmd_spy, "cmd_bar2")) + cmd_handler.register_cb("-arg", cmd_spy.cmd_arg) + cmd_handler.register_cbv("-arg", cmd_spy.cmd_args) + cmd_handler.register_cb("-a", cmd_spy.cmd_no_arg) assert_result(cmd_handler.execute([CmdCommand.new("-a")])).is_success() - verify(cmd_spy).cmd_a() + verify(cmd_spy).cmd_no_arg() verify_no_more_interactions(cmd_spy) reset(cmd_spy) assert_result(cmd_handler.execute([ CmdCommand.new("-a"), - CmdCommand.new("-b", ["some_value"]), - CmdCommand.new("-b2", ["value1", "value2"])])).is_success() - verify(cmd_spy).cmd_a() - verify(cmd_spy).cmd_bar("some_value") - verify(cmd_spy).cmd_bar2("value1", "value2") + CmdCommand.new("-arg", ["some_value"]), + CmdCommand.new("-arg", ["value1", "value2"])])).is_success() + verify(cmd_spy).cmd_no_arg() + verify(cmd_spy).cmd_arg("some_value") + verify(cmd_spy).cmd_args(PackedStringArray(["value1", "value2"])) verify_no_more_interactions(cmd_spy) diff --git a/addons/gdUnit4/test/cmd/runtestDebug.tscn b/addons/gdUnit4/test/cmd/runtestDebug.tscn index 9716b71b..1186645b 100644 --- a/addons/gdUnit4/test/cmd/runtestDebug.tscn +++ b/addons/gdUnit4/test/cmd/runtestDebug.tscn @@ -12,7 +12,7 @@ func _ready() -> void: #var tool := CmdTool.new() var runner := CmdTool.CLIRunner.new() - runner._debug_cmd_args = [\"GdUnitCmdTool.gd\", \"--add\", \"res://addons/gdUnit4/test/cmd\", \"-i\", \"CmdArgumentParserTest\", \"--continue\", \"-rc\", \"1\"] + runner._debug_cmd_args = [\"GdUnitCmdTool.gd\", \"--add\", \"res://addons/gdUnit4/test/core/parse/\", \"--add\", \"res://addons/gdUnit4/test/asserts/GdUnitAssertImplTest.gd\", \"-i\", \"GdDefaultValueDecoderTest\", \"-i\", \"GdScriptParserTest\", \"--continue\", \"-rc\", \"1\"] add_child(runner) diff --git a/addons/gdUnit4/test/core/GdUnitRunnerConfigTest.gd b/addons/gdUnit4/test/core/GdUnitRunnerConfigTest.gd index c3b08d58..2b48d5d6 100644 --- a/addons/gdUnit4/test/core/GdUnitRunnerConfigTest.gd +++ b/addons/gdUnit4/test/core/GdUnitRunnerConfigTest.gd @@ -156,12 +156,12 @@ func test_skip_test_suite_and_test_case() -> void: func test_skip_test_case() -> void: var config := GdUnitRunnerConfig.new() - config.skip_test_case("res://foo1.gd", "testcaseA") + config._skip_test_case("res://foo1.gd", "testcaseA") assert_dict(config.skipped()).contains_key_value("res://foo1.gd", PackedStringArray(["testcaseA"])) # add two more config.skip_test_suite("res://foo2/skippedTestsuite.gd") - config.skip_test_case("res://foo1.gd", "testcaseB") - config.skip_test_case("res://foo2.gd", "testcaseX") + config._skip_test_case("res://foo1.gd", "testcaseB") + config._skip_test_case("res://foo2.gd", "testcaseX") assert_dict(config.skipped())\ .contains_key_value("res://foo2/skippedTestsuite.gd", PackedStringArray())\ .contains_key_value("res://foo1.gd", PackedStringArray(["testcaseA", "testcaseB"]))\