fixed camera and sword animation issue and upgraded to Godot 4.6
This commit is contained in:
@@ -1 +1 @@
|
||||
uid://bk60ywsj4ekp7
|
||||
uid://etq75dot1c03
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b5sli0lem5xca
|
||||
uid://cx8bp6vsxyrts
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b7ldhc4ryfh1v
|
||||
uid://dk4tv55wf5mlm
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bbaqjhpbxce3u
|
||||
uid://ds3n71e8n4wce
|
||||
|
||||
@@ -196,7 +196,7 @@ static func resource_as_string(resource_path :String) -> String:
|
||||
if file == null:
|
||||
push_error("ERROR: Can't read resource '%s'. %s" % [resource_path, error_string(FileAccess.get_open_error())])
|
||||
return ""
|
||||
return file.get_as_text(true)
|
||||
return file.get_as_text()
|
||||
|
||||
|
||||
static func make_qualified_path(path :String) -> String:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dflqb5germp5n
|
||||
uid://ddr26lg6f055n
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cqndh0nuu8ltx
|
||||
uid://c0ymnlx3jooyl
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cnvq3nb61ei76
|
||||
uid://b6k1ufvw6w2s5
|
||||
|
||||
@@ -18,7 +18,10 @@ var _config := {
|
||||
TESTS : Array([], TYPE_OBJECT, "RefCounted", GdUnitTestCase),
|
||||
|
||||
# the port of running test server for this session
|
||||
SERVER_PORT : -1
|
||||
SERVER_PORT : -1,
|
||||
|
||||
# Exit on first failure
|
||||
EXIT_FAIL_FAST : false
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +43,15 @@ func server_port() -> int:
|
||||
return _config.get(SERVER_PORT, -1)
|
||||
|
||||
|
||||
func do_fail_fast(is_fail_fast: bool) -> GdUnitRunnerConfig:
|
||||
_config[EXIT_FAIL_FAST] = is_fail_fast
|
||||
return self
|
||||
|
||||
|
||||
func is_fail_fast() -> bool:
|
||||
return _config.get(EXIT_FAIL_FAST, false)
|
||||
|
||||
|
||||
func add_test_cases(tests: Array[GdUnitTestCase]) -> GdUnitRunnerConfig:
|
||||
test_cases().append_array(tests)
|
||||
return self
|
||||
@@ -57,7 +69,8 @@ func save_config(path: String = CONFIG_FILE) -> GdUnitResult:
|
||||
|
||||
var to_save := {
|
||||
VERSION : CONFIG_VERSION,
|
||||
SERVER_PORT : _config.get(SERVER_PORT),
|
||||
EXIT_FAIL_FAST : is_fail_fast(),
|
||||
SERVER_PORT : server_port(),
|
||||
TESTS : Array()
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ltvpkh3ayklf
|
||||
uid://dvrxtyni1604f
|
||||
|
||||
@@ -72,12 +72,11 @@ func _init(p_scene: Variant, p_verbose: bool, p_hide_push_errors := false) -> vo
|
||||
return
|
||||
|
||||
_scene_tree().root.add_child(_current_scene)
|
||||
Engine.set_meta("GdUnitSceneRunner", self)
|
||||
# do finally reset all open input events when the scene is removed
|
||||
@warning_ignore("return_value_discarded")
|
||||
_scene_tree().root.child_exiting_tree.connect(func f(child :Node) -> void:
|
||||
_scene_tree().root.child_exiting_tree.connect(func f(child: Node) -> void:
|
||||
if child == _current_scene:
|
||||
# we need to disable the processing to avoid input flush buffer errors
|
||||
_current_scene.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
_reset_input_to_default()
|
||||
)
|
||||
_simulate_start_time = LocalTime.now()
|
||||
@@ -103,6 +102,7 @@ func _notification(what: int) -> void:
|
||||
_current_scene.free()
|
||||
_is_disposed = true
|
||||
_current_scene = null
|
||||
Engine.remove_meta("GdUnitSceneRunner")
|
||||
|
||||
|
||||
func _scene_tree() -> SceneTree:
|
||||
@@ -145,6 +145,7 @@ func simulate_action_release(action: String, event_index := -1) -> GdUnitSceneRu
|
||||
|
||||
@warning_ignore("return_value_discarded")
|
||||
func simulate_key_pressed(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner:
|
||||
_push_warning_deprecated_arguments(shift_pressed, ctrl_pressed)
|
||||
simulate_key_press(key_code, shift_pressed, ctrl_pressed)
|
||||
await _scene_tree().process_frame
|
||||
simulate_key_release(key_code, shift_pressed, ctrl_pressed)
|
||||
@@ -152,30 +153,33 @@ func simulate_key_pressed(key_code: int, shift_pressed := false, ctrl_pressed :=
|
||||
|
||||
|
||||
func simulate_key_press(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner:
|
||||
_push_warning_deprecated_arguments(shift_pressed, ctrl_pressed)
|
||||
__print_current_focus()
|
||||
var event := InputEventKey.new()
|
||||
event.pressed = true
|
||||
event.keycode = key_code as Key
|
||||
event.physical_keycode = key_code as Key
|
||||
event.unicode = key_code
|
||||
event.alt_pressed = key_code == KEY_ALT
|
||||
event.shift_pressed = shift_pressed or key_code == KEY_SHIFT
|
||||
event.ctrl_pressed = ctrl_pressed or key_code == KEY_CTRL
|
||||
event.set_alt_pressed(key_code == KEY_ALT)
|
||||
event.set_shift_pressed(shift_pressed)
|
||||
event.set_ctrl_pressed(ctrl_pressed)
|
||||
event.get_modifiers_mask()
|
||||
_apply_input_modifiers(event)
|
||||
_key_on_press.append(key_code)
|
||||
return _handle_input_event(event)
|
||||
|
||||
|
||||
func simulate_key_release(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner:
|
||||
_push_warning_deprecated_arguments(shift_pressed, ctrl_pressed)
|
||||
__print_current_focus()
|
||||
var event := InputEventKey.new()
|
||||
event.pressed = false
|
||||
event.keycode = key_code as Key
|
||||
event.physical_keycode = key_code as Key
|
||||
event.unicode = key_code
|
||||
event.alt_pressed = key_code == KEY_ALT
|
||||
event.shift_pressed = shift_pressed or key_code == KEY_SHIFT
|
||||
event.ctrl_pressed = ctrl_pressed or key_code == KEY_CTRL
|
||||
event.set_alt_pressed(key_code == KEY_ALT)
|
||||
event.set_shift_pressed(shift_pressed)
|
||||
event.set_ctrl_pressed(ctrl_pressed)
|
||||
_apply_input_modifiers(event)
|
||||
_key_on_press.erase(key_code)
|
||||
return _handle_input_event(event)
|
||||
@@ -485,6 +489,8 @@ func find_child(name: String, recursive: bool = true, owned: bool = false) -> No
|
||||
|
||||
|
||||
func _scene_name() -> String:
|
||||
if scene() == null:
|
||||
return "unknown"
|
||||
var scene_script :GDScript = scene().get_script()
|
||||
var scene_name :String = scene().get_name()
|
||||
if not scene_script:
|
||||
@@ -515,6 +521,13 @@ func _apply_input_modifiers(event: InputEvent) -> void:
|
||||
_event.ctrl_pressed = _event.ctrl_pressed or last_input_event.ctrl_pressed
|
||||
# this line results into reset the control_pressed state!!!
|
||||
#event.command_or_control_autoremap = event.command_or_control_autoremap or _last_input_event.command_or_control_autoremap
|
||||
if _last_input_event is InputEventKey and event is InputEventWithModifiers:
|
||||
var last_input_event := _last_input_event as InputEventKey
|
||||
var _event := event as InputEventWithModifiers
|
||||
_event.shift_pressed = _event.shift_pressed or last_input_event.keycode == KEY_SHIFT
|
||||
_event.alt_pressed = _event.alt_pressed or last_input_event.keycode == KEY_ALT
|
||||
_event.ctrl_pressed = _event.ctrl_pressed or last_input_event.keycode == KEY_CTRL
|
||||
_event.meta_pressed = _event.meta_pressed or last_input_event.keycode == KEY_META
|
||||
|
||||
|
||||
# copy over current active mouse mask and combine with curren mask
|
||||
@@ -620,3 +633,10 @@ func scene() -> Node:
|
||||
if not _is_disposed:
|
||||
push_error("The current scene instance is not valid anymore! check your test is valid. e.g. check for missing awaits.")
|
||||
return null
|
||||
|
||||
|
||||
func _push_warning_deprecated_arguments(shift_pressed: bool, ctrl_pressed: bool) -> void:
|
||||
if shift_pressed:
|
||||
push_warning("Deprecated! Don't use 'shift_pressed' it will be removed in v7.0, checkout the documentaion how to use key combinations.")
|
||||
if ctrl_pressed:
|
||||
push_warning("Deprecated! Don't use 'ctrl_pressed' it will be removed in v7.0, checkout the documentaion how to use key combinations.")
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://7a566a4kfreu
|
||||
uid://bdhmqovuioydb
|
||||
|
||||
@@ -21,6 +21,7 @@ const TEST_SUITE_NAMING_CONVENTION = GROUP_TEST + "/test_suite_naming_convention
|
||||
const TEST_DISCOVER_ENABLED = GROUP_TEST + "/test_discovery"
|
||||
const TEST_FLAKY_CHECK = GROUP_TEST + "/flaky_check_enable"
|
||||
const TEST_FLAKY_MAX_RETRIES = GROUP_TEST + "/flaky_max_retries"
|
||||
const TEST_RERUN_UNTIL_FAILURE_RETRIES = GROUP_TEST + "/rerun_until_failure_retries"
|
||||
|
||||
|
||||
# Report Setiings
|
||||
@@ -62,6 +63,7 @@ const SHORTCUT_INSPECTOR_RERUN_TEST = GROUP_SHORTCUT_INSPECTOR + "/rerun_test"
|
||||
const SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG = GROUP_SHORTCUT_INSPECTOR + "/rerun_test_debug"
|
||||
const SHORTCUT_INSPECTOR_RUN_TEST_OVERALL = GROUP_SHORTCUT_INSPECTOR + "/run_test_overall"
|
||||
const SHORTCUT_INSPECTOR_RUN_TEST_STOP = GROUP_SHORTCUT_INSPECTOR + "/run_test_stop"
|
||||
const SHORTCUT_INSPECTOR_RERUN_TEST_UNTIL_FAILURE = GROUP_SHORTCUT_INSPECTOR + "/rerun_test_until_failure"
|
||||
|
||||
const GROUP_SHORTCUT_EDITOR = SHORTCUT_SETTINGS + "/editor"
|
||||
const SHORTCUT_EDITOR_RUN_TEST = GROUP_SHORTCUT_EDITOR + "/run_test"
|
||||
@@ -112,6 +114,7 @@ static func setup() -> void:
|
||||
create_property_if_need(TEST_DISCOVER_ENABLED, false, "Automatically detect new tests in test lookup folders at runtime")
|
||||
create_property_if_need(TEST_FLAKY_CHECK, false, "Rerun tests on failure and mark them as FLAKY")
|
||||
create_property_if_need(TEST_FLAKY_MAX_RETRIES, 3, "Sets the number of retries for rerunning a flaky test")
|
||||
create_property_if_need(TEST_RERUN_UNTIL_FAILURE_RETRIES, 10, "The number of reruns until the test fails.")
|
||||
# report settings
|
||||
create_property_if_need(REPORT_PUSH_ERRORS, false, "Report push_error() as failure")
|
||||
create_property_if_need(REPORT_SCRIPT_ERRORS, true, "Report script errors as failure")
|
||||
@@ -148,6 +151,7 @@ static func create_shortcut_properties_if_need() -> void:
|
||||
# inspector
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RERUN_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RERUN_TESTS), "Rerun the most recently executed tests")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG), "Rerun the most recently executed tests (Debug mode)")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RERUN_TEST_UNTIL_FAILURE, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RERUN_TESTS_UNTIL_FAILURE), "Rerun tests until failure occurs")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RUN_TEST_OVERALL, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTS_OVERALL), "Runs all tests (Debug mode)")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RUN_TEST_STOP, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.STOP_TEST_RUN), "Stop the current test execution")
|
||||
# script editor
|
||||
@@ -155,8 +159,8 @@ static func create_shortcut_properties_if_need() -> void:
|
||||
create_property_if_need(SHORTCUT_EDITOR_RUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTCASE_DEBUG), "Run the currently selected test (Debug mode).")
|
||||
create_property_if_need(SHORTCUT_EDITOR_CREATE_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.CREATE_TEST), "Create a new test case for the currently selected function")
|
||||
# filesystem
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.NONE), "Run all test suites in the selected folder or file")
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.NONE), "Run all test suites in the selected folder or file (Debug)")
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTSUITE), "Run all test suites in the selected folder or file")
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTSUITE_DEBUG), "Run all test suites in the selected folder or file (Debug)")
|
||||
|
||||
|
||||
static func create_property_if_need(name :String, default :Variant, help :="", value_set := PackedStringArray()) -> void:
|
||||
@@ -306,6 +310,10 @@ static func get_flaky_max_retries() -> int:
|
||||
return get_setting(TEST_FLAKY_MAX_RETRIES, 3)
|
||||
|
||||
|
||||
static func get_rerun_max_retries() -> int:
|
||||
return get_setting(TEST_RERUN_UNTIL_FAILURE_RETRIES, 10)
|
||||
|
||||
|
||||
static func set_test_discover_enabled(enable :bool) -> void:
|
||||
var property := get_property(TEST_DISCOVER_ENABLED)
|
||||
property.set_value(enable)
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://coby4unvmd3eh
|
||||
uid://djrx6fy3w3bb
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ckx5jnr3ip6vp
|
||||
uid://l1nsecnjoon6
|
||||
|
||||
@@ -107,7 +107,7 @@ func is_signal_collecting(emitter: Object, signal_name: String) -> bool:
|
||||
return _collected_signals.has(emitter) and (_collected_signals[emitter] as Dictionary).has(signal_name)
|
||||
|
||||
|
||||
func match(emitter :Object, signal_name :String, args :Array) -> bool:
|
||||
func match(emitter: Object, signal_name: String, args: Array) -> bool:
|
||||
#prints("match", signal_name, _collected_signals[emitter][signal_name]);
|
||||
if _collected_signals.is_empty() or not _collected_signals.has(emitter):
|
||||
return false
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cm0rbs8vhdhd1
|
||||
uid://bnvdsssykfaeh
|
||||
|
||||
@@ -33,9 +33,9 @@ signal gdunit_client_connected(client_id: int)
|
||||
signal gdunit_client_disconnected(client_id: int)
|
||||
|
||||
|
||||
## Emitted when a client terminates unexpectedly.
|
||||
## Emitted when a the user stops (terminates) the current test session
|
||||
@warning_ignore("unused_signal")
|
||||
signal gdunit_client_terminated()
|
||||
signal gdunit_test_session_terminate()
|
||||
|
||||
|
||||
## Emitted when a test execution event occurs.[br]
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://kj16fg0hf6kn
|
||||
uid://7fkqtqq0ib25
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://4sujouo3vf6d
|
||||
uid://djyr7is32ffbs
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ierjyaem56m3
|
||||
uid://cg0fqsmpf8fdh
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dthfh16tl5wqc
|
||||
uid://cqe6i2xbwgneb
|
||||
|
||||
@@ -70,8 +70,14 @@ func scan_directory(resource_path: String) -> Array[Script]:
|
||||
|
||||
|
||||
func _scan_test_suites_scripts(dir: DirAccess, collected_suites: Array[Script]) -> Array[Script]:
|
||||
# Skip excluded directories
|
||||
if dir.file_exists(".gdignore"):
|
||||
prints("Exclude directory %s, containing .gdignore file" % dir.get_current_dir())
|
||||
return []
|
||||
|
||||
if exclude_scan_directories.has(dir.get_current_dir()):
|
||||
return collected_suites
|
||||
|
||||
var err := dir.list_dir_begin()
|
||||
if err != OK:
|
||||
push_error("Error on scanning directory %s" % dir.get_current_dir(), error_string(err))
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bju0nt1bgsc2s
|
||||
uid://bymtxj63ek2kd
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://d05qgv6uu477i
|
||||
uid://4tbcywx0qg1d
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dehxycxsj68ev
|
||||
uid://d0d4s6tkgoh3b
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dmta1h7ndfnko
|
||||
uid://dd7g37aslbmm1
|
||||
|
||||
@@ -9,7 +9,8 @@ var _attribute: TestCaseAttribute
|
||||
var _current_iteration: int = -1
|
||||
var _expect_to_interupt := false
|
||||
var _timer: Timer
|
||||
var _interupted: bool = false
|
||||
var _interupted := false
|
||||
var _terminated := false
|
||||
var _failed := false
|
||||
var _parameter_set_resolver: GdUnitTestParameterSetResolver
|
||||
var _is_disposed := false
|
||||
@@ -123,7 +124,7 @@ func do_interrupt() -> void:
|
||||
# We need to dispose manually the function state here
|
||||
GdObjects.dispose_function_state(_func_state)
|
||||
if not is_expect_interupted():
|
||||
var execution_context:= GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
var execution_context := GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
if is_fuzzed():
|
||||
execution_context.add_report(GdUnitReport.new()\
|
||||
.create(GdUnitReport.INTERUPTED, line_number(), GdAssertMessages.fuzzer_interuped(_current_iteration, "timedout")))
|
||||
@@ -133,6 +134,16 @@ func do_interrupt() -> void:
|
||||
completed.emit()
|
||||
|
||||
|
||||
func do_terminate() -> void:
|
||||
_terminated = true
|
||||
# We need to dispose manually the function state here
|
||||
GdObjects.dispose_function_state(_func_state)
|
||||
var execution_context := GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
execution_context.add_report(GdUnitReport.new()\
|
||||
.create(GdUnitReport.TERMINATED, line_number(), GdAssertMessages.test_session_terminated()))
|
||||
completed.emit()
|
||||
|
||||
|
||||
func _set_failure_handler() -> void:
|
||||
if not GdUnitSignals.instance().gdunit_set_test_failed.is_connected(_failure_received):
|
||||
@warning_ignore("return_value_discarded")
|
||||
@@ -172,6 +183,10 @@ func is_expect_interupted() -> bool:
|
||||
return _expect_to_interupt
|
||||
|
||||
|
||||
func is_terminated() -> bool:
|
||||
return _terminated
|
||||
|
||||
|
||||
func is_parameterized() -> bool:
|
||||
return _parameter_set_resolver.is_parameterized()
|
||||
|
||||
@@ -192,11 +207,6 @@ func test_name() -> String:
|
||||
return _test_case.test_name
|
||||
|
||||
|
||||
@warning_ignore("native_method_override")
|
||||
func get_name() -> StringName:
|
||||
return _test_case.test_name
|
||||
|
||||
|
||||
func line_number() -> int:
|
||||
return _test_case.line_number
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cb2lkpvh0liiv
|
||||
uid://dvhr6i0bdk05n
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://csgvrbao53xmv"
|
||||
uid="uid://c0lvcprd6501t"
|
||||
path="res://.godot/imported/touch-button.png-2fff40c8520d8e97a57db1b2b043f641.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://d2bres53mgxnw
|
||||
uid://b3ilfkx1js423
|
||||
|
||||
64
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd
Normal file
64
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd
Normal file
@@ -0,0 +1,64 @@
|
||||
@abstract class_name GdUnitBaseCommand
|
||||
extends Node
|
||||
|
||||
|
||||
var id: String
|
||||
var icon: Texture2D
|
||||
var shortcut: Shortcut = null
|
||||
var shortcut_type: GdUnitShortcut.ShortCut
|
||||
|
||||
|
||||
func _init(p_id: String, p_shortcut: GdUnitShortcut.ShortCut = GdUnitShortcut.ShortCut.NONE) -> void:
|
||||
id = p_id
|
||||
shortcut_type = p_shortcut
|
||||
_set_shortcut()
|
||||
|
||||
|
||||
func _shortcut_input(event: InputEvent) -> void:
|
||||
if is_running():
|
||||
return
|
||||
|
||||
if shortcut and shortcut.matches_event(event):
|
||||
execute()
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
|
||||
func update_shortcut() -> void:
|
||||
_set_shortcut()
|
||||
|
||||
|
||||
func _set_shortcut() -> void:
|
||||
if shortcut_type == GdUnitShortcut.ShortCut.NONE:
|
||||
return
|
||||
|
||||
var property_name := GdUnitShortcut.as_property(shortcut_type)
|
||||
var property := GdUnitSettings.get_property(property_name)
|
||||
var keys := GdUnitShortcut.default_keys(shortcut_type)
|
||||
if property != null:
|
||||
keys = property.value()
|
||||
var inputEvent := _create_shortcut_input_even(keys)
|
||||
|
||||
shortcut = Shortcut.new()
|
||||
shortcut.set_events([inputEvent])
|
||||
|
||||
|
||||
func _create_shortcut_input_even(key_codes: PackedInt32Array) -> InputEventKey:
|
||||
var inputEvent := InputEventKey.new()
|
||||
inputEvent.pressed = true
|
||||
for key_code in key_codes:
|
||||
match key_code:
|
||||
KEY_ALT:
|
||||
inputEvent.alt_pressed = true
|
||||
KEY_SHIFT:
|
||||
inputEvent.shift_pressed = true
|
||||
KEY_CTRL:
|
||||
inputEvent.ctrl_pressed = true
|
||||
_:
|
||||
inputEvent.keycode = key_code as Key
|
||||
inputEvent.physical_keycode = key_code as Key
|
||||
return inputEvent
|
||||
|
||||
|
||||
@abstract func is_running() -> bool
|
||||
|
||||
@abstract func execute(...parameters: Array) -> void
|
||||
1
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd.uid
Normal file
1
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bxuturao0ahb5
|
||||
@@ -1,41 +0,0 @@
|
||||
class_name GdUnitCommand
|
||||
extends RefCounted
|
||||
|
||||
|
||||
func _init(p_name :String, p_is_enabled: Callable, p_runnable: Callable, p_shortcut :GdUnitShortcut.ShortCut = GdUnitShortcut.ShortCut.NONE) -> void:
|
||||
assert(p_name != null, "(%s) missing parameter 'name'" % p_name)
|
||||
assert(p_is_enabled != null, "(%s) missing parameter 'is_enabled'" % p_name)
|
||||
assert(p_runnable != null, "(%s) missing parameter 'runnable'" % p_name)
|
||||
assert(p_shortcut != null, "(%s) missing parameter 'shortcut'" % p_name)
|
||||
self.name = p_name
|
||||
self.is_enabled = p_is_enabled
|
||||
self.shortcut = p_shortcut
|
||||
self.runnable = p_runnable
|
||||
|
||||
|
||||
var name: String:
|
||||
set(value):
|
||||
name = value
|
||||
get:
|
||||
return name
|
||||
|
||||
|
||||
var shortcut: GdUnitShortcut.ShortCut:
|
||||
set(value):
|
||||
shortcut = value
|
||||
get:
|
||||
return shortcut
|
||||
|
||||
|
||||
var is_enabled: Callable:
|
||||
set(value):
|
||||
is_enabled = value
|
||||
get:
|
||||
return is_enabled
|
||||
|
||||
|
||||
var runnable: Callable:
|
||||
set(value):
|
||||
runnable = value
|
||||
get:
|
||||
return runnable
|
||||
@@ -1 +0,0 @@
|
||||
uid://crmuuvbqy4shs
|
||||
42
addons/gdUnit4/src/core/command/GdUnitCommandFileSystem.gd
Normal file
42
addons/gdUnit4/src/core/command/GdUnitCommandFileSystem.gd
Normal file
@@ -0,0 +1,42 @@
|
||||
@abstract class_name GdUnitCommandFileSystem
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
|
||||
func _init(p_id: String, p_shortcut: GdUnitShortcut.ShortCut, test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(p_id, p_shortcut)
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute_tests(paths: PackedStringArray, with_debug: bool) -> void:
|
||||
var suite_scaner := GdUnitTestSuiteScanner.new()
|
||||
var scripts: Array[Script]
|
||||
|
||||
for resource_path in paths:
|
||||
# directories and test-suites are valid to enable the menu
|
||||
if DirAccess.dir_exists_absolute(resource_path):
|
||||
scripts.append_array(suite_scaner.scan_directory(resource_path))
|
||||
continue
|
||||
|
||||
var file_type := resource_path.get_extension()
|
||||
if file_type == "gd" or file_type == "cs":
|
||||
var script := GdUnitTestSuiteScanner.load_with_disabled_warnings(resource_path)
|
||||
|
||||
if GdUnitTestSuiteScanner.is_test_suite(script):
|
||||
scripts.append(script)
|
||||
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverStart.new())
|
||||
var tests_to_execute: Array[GdUnitTestCase] = []
|
||||
for script in scripts:
|
||||
GdUnitTestDiscoverer.discover_tests(script, func(test_case: GdUnitTestCase) -> void:
|
||||
tests_to_execute.append(test_case)
|
||||
GdUnitTestDiscoverSink.discover(test_case)
|
||||
)
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverEnd.new(0, 0))
|
||||
GdUnitTestDiscoverer.console_log_discover_results(tests_to_execute)
|
||||
_test_session_command.execute(tests_to_execute, with_debug)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bjfsokglrqosr
|
||||
@@ -0,0 +1,15 @@
|
||||
class_name GdUnitCommandFileSystemDebugTests
|
||||
extends GdUnitCommandFileSystem
|
||||
|
||||
|
||||
const ID := "Debug FileSystem Tests"
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RUN_TESTSUITE_DEBUG, test_session_command)
|
||||
icon = GdUnitUiTools.get_icon("PlayStart")
|
||||
|
||||
|
||||
func execute(...parameters: Array) -> void:
|
||||
var selected_paths: PackedStringArray = parameters[0]
|
||||
execute_tests(selected_paths, true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ceeexn8cdh4ul
|
||||
@@ -0,0 +1,15 @@
|
||||
class_name GdUnitCommandFileSystemRunTests
|
||||
extends GdUnitCommandFileSystem
|
||||
|
||||
|
||||
const ID := "Run FileSystem Tests"
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RUN_TESTSUITE, test_session_command)
|
||||
icon = GdUnitUiTools.get_icon("Play")
|
||||
|
||||
|
||||
func execute(...parameters: Array) -> void:
|
||||
var selected_paths: PackedStringArray = parameters[0]
|
||||
execute_tests(selected_paths, false)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bv1bu2urk7rby
|
||||
@@ -1,62 +1,11 @@
|
||||
class_name GdUnitCommandHandler
|
||||
extends Object
|
||||
|
||||
signal gdunit_runner_start()
|
||||
signal gdunit_runner_stop(client_id :int)
|
||||
|
||||
|
||||
const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd")
|
||||
|
||||
const CMD_RUN_OVERALL = "Debug Overall TestSuites"
|
||||
const CMD_RUN_TESTCASE = "Run TestCases"
|
||||
const CMD_RUN_TESTCASE_DEBUG = "Run TestCases (Debug)"
|
||||
const CMD_RUN_TESTSUITE = "Run TestSuites"
|
||||
const CMD_RUN_TESTSUITE_DEBUG = "Run TestSuites (Debug)"
|
||||
const CMD_RERUN_TESTS = "ReRun Tests"
|
||||
const CMD_RERUN_TESTS_DEBUG = "ReRun Tests (Debug)"
|
||||
const CMD_STOP_TEST_RUN = "Stop Test Run"
|
||||
const CMD_CREATE_TESTCASE = "Create TestCase"
|
||||
|
||||
const SETTINGS_SHORTCUT_MAPPING := {
|
||||
"N/A" : GdUnitShortcut.ShortCut.NONE,
|
||||
GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST : GdUnitShortcut.ShortCut.RERUN_TESTS,
|
||||
GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG : GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG,
|
||||
GdUnitSettings.SHORTCUT_INSPECTOR_RUN_TEST_OVERALL : GdUnitShortcut.ShortCut.RUN_TESTS_OVERALL,
|
||||
GdUnitSettings.SHORTCUT_INSPECTOR_RUN_TEST_STOP : GdUnitShortcut.ShortCut.STOP_TEST_RUN,
|
||||
GdUnitSettings.SHORTCUT_EDITOR_RUN_TEST : GdUnitShortcut.ShortCut.RUN_TESTCASE,
|
||||
GdUnitSettings.SHORTCUT_EDITOR_RUN_TEST_DEBUG : GdUnitShortcut.ShortCut.RUN_TESTCASE_DEBUG,
|
||||
GdUnitSettings.SHORTCUT_EDITOR_CREATE_TEST : GdUnitShortcut.ShortCut.CREATE_TEST,
|
||||
GdUnitSettings.SHORTCUT_FILESYSTEM_RUN_TEST : GdUnitShortcut.ShortCut.RUN_TESTSUITE,
|
||||
GdUnitSettings.SHORTCUT_FILESYSTEM_RUN_TEST_DEBUG : GdUnitShortcut.ShortCut.RUN_TESTSUITE_DEBUG
|
||||
}
|
||||
|
||||
const CommandMapping := {
|
||||
GdUnitShortcut.ShortCut.RUN_TESTS_OVERALL: GdUnitCommandHandler.CMD_RUN_OVERALL,
|
||||
GdUnitShortcut.ShortCut.RUN_TESTCASE: GdUnitCommandHandler.CMD_RUN_TESTCASE,
|
||||
GdUnitShortcut.ShortCut.RUN_TESTCASE_DEBUG: GdUnitCommandHandler.CMD_RUN_TESTCASE_DEBUG,
|
||||
GdUnitShortcut.ShortCut.RUN_TESTSUITE: GdUnitCommandHandler.CMD_RUN_TESTSUITE,
|
||||
GdUnitShortcut.ShortCut.RUN_TESTSUITE_DEBUG: GdUnitCommandHandler.CMD_RUN_TESTSUITE_DEBUG,
|
||||
GdUnitShortcut.ShortCut.RERUN_TESTS: GdUnitCommandHandler.CMD_RERUN_TESTS,
|
||||
GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG: GdUnitCommandHandler.CMD_RERUN_TESTS_DEBUG,
|
||||
GdUnitShortcut.ShortCut.STOP_TEST_RUN: GdUnitCommandHandler.CMD_STOP_TEST_RUN,
|
||||
GdUnitShortcut.ShortCut.CREATE_TEST: GdUnitCommandHandler.CMD_CREATE_TESTCASE,
|
||||
}
|
||||
|
||||
# the current test runner config
|
||||
var _runner_config := GdUnitRunnerConfig.new()
|
||||
|
||||
# holds the current connected gdUnit runner client id
|
||||
var _client_id: int
|
||||
# if no debug mode we have an process id
|
||||
var _current_runner_process_id: int = 0
|
||||
# hold is current an test running
|
||||
var _is_running: bool = false
|
||||
# holds if the current running tests started in debug mode
|
||||
var _running_debug_mode: bool
|
||||
|
||||
var _commands := {}
|
||||
var _shortcuts := {}
|
||||
|
||||
var _commnand_mappings: Dictionary[String, GdUnitBaseCommand]= {}
|
||||
var test_session_command := GdUnitCommandTestSession.new()
|
||||
|
||||
static func instance() -> GdUnitCommandHandler:
|
||||
return GdUnitSingleton.instance("GdUnitCommandHandler", func() -> GdUnitCommandHandler: return GdUnitCommandHandler.new())
|
||||
@@ -64,28 +13,23 @@ static func instance() -> GdUnitCommandHandler:
|
||||
|
||||
@warning_ignore("return_value_discarded")
|
||||
func _init() -> void:
|
||||
assert_shortcut_mappings(SETTINGS_SHORTCUT_MAPPING)
|
||||
|
||||
GdUnitSignals.instance().gdunit_event.connect(_on_event)
|
||||
GdUnitSignals.instance().gdunit_client_connected.connect(_on_client_connected)
|
||||
GdUnitSignals.instance().gdunit_client_disconnected.connect(_on_client_disconnected)
|
||||
GdUnitSignals.instance().gdunit_settings_changed.connect(_on_settings_changed)
|
||||
# preload previous test execution
|
||||
@warning_ignore("return_value_discarded")
|
||||
_runner_config.load_config()
|
||||
|
||||
init_shortcuts()
|
||||
var is_running := func(_script :Script) -> bool: return _is_running
|
||||
var is_not_running := func(_script :Script) -> bool: return !_is_running
|
||||
register_command(GdUnitCommand.new(CMD_RUN_OVERALL, is_not_running, cmd_run_overall.bind(true), GdUnitShortcut.ShortCut.RUN_TESTS_OVERALL))
|
||||
register_command(GdUnitCommand.new(CMD_RUN_TESTCASE, is_not_running, cmd_editor_run_test.bind(false), GdUnitShortcut.ShortCut.RUN_TESTCASE))
|
||||
register_command(GdUnitCommand.new(CMD_RUN_TESTCASE_DEBUG, is_not_running, cmd_editor_run_test.bind(true), GdUnitShortcut.ShortCut.RUN_TESTCASE_DEBUG))
|
||||
register_command(GdUnitCommand.new(CMD_RUN_TESTSUITE, is_not_running, cmd_run_test_suites.bind(false), GdUnitShortcut.ShortCut.RUN_TESTSUITE))
|
||||
register_command(GdUnitCommand.new(CMD_RUN_TESTSUITE_DEBUG, is_not_running, cmd_run_test_suites.bind(true), GdUnitShortcut.ShortCut.RUN_TESTSUITE_DEBUG))
|
||||
register_command(GdUnitCommand.new(CMD_RERUN_TESTS, is_not_running, cmd_run.bind(false), GdUnitShortcut.ShortCut.RERUN_TESTS))
|
||||
register_command(GdUnitCommand.new(CMD_RERUN_TESTS_DEBUG, is_not_running, cmd_run.bind(true), GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG))
|
||||
register_command(GdUnitCommand.new(CMD_CREATE_TESTCASE, is_not_running, cmd_create_test, GdUnitShortcut.ShortCut.CREATE_TEST))
|
||||
register_command(GdUnitCommand.new(CMD_STOP_TEST_RUN, is_running, cmd_stop.bind(_client_id), GdUnitShortcut.ShortCut.STOP_TEST_RUN))
|
||||
_register_command(test_session_command)
|
||||
_register_command(GdUnitCommandStopTestSession.new(test_session_command))
|
||||
_register_command(GdUnitCommandInspectorRunTests.new(test_session_command))
|
||||
_register_command(GdUnitCommandInspectorDebugTests.new(test_session_command))
|
||||
_register_command(GdUnitCommandInspectorRerunTestsUntilFailure.new(test_session_command))
|
||||
_register_command(GdUnitCommandInspectorTreeCollapse.new())
|
||||
_register_command(GdUnitCommandInspectorTreeExpand.new())
|
||||
_register_command(GdUnitCommandScriptEditorRunTests.new(test_session_command))
|
||||
_register_command(GdUnitCommandScriptEditorDebugTests.new(test_session_command))
|
||||
_register_command(GdUnitCommandScriptEditorCreateTest.new())
|
||||
_register_command(GdUnitCommandFileSystemRunTests.new(test_session_command))
|
||||
_register_command(GdUnitCommandFileSystemDebugTests.new(test_session_command))
|
||||
_register_command(GdUnitCommandRunTestsOverall.new(test_session_command))
|
||||
|
||||
# schedule discover tests if enabled and running inside the editor
|
||||
if Engine.is_editor_hint() and GdUnitSettings.is_test_discover_enabled():
|
||||
@@ -96,298 +40,79 @@ func _init() -> void:
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_PREDELETE:
|
||||
_commands.clear()
|
||||
_shortcuts.clear()
|
||||
for command: GdUnitBaseCommand in _commnand_mappings.values():
|
||||
if Engine.is_editor_hint():
|
||||
EditorInterface.get_command_palette().remove_command("GdUnit4/"+command.id)
|
||||
command.free()
|
||||
_commnand_mappings.clear()
|
||||
|
||||
|
||||
func _do_process() -> void:
|
||||
check_test_run_stopped_manually()
|
||||
|
||||
|
||||
# is checking if the user has press the editor stop scene
|
||||
func check_test_run_stopped_manually() -> void:
|
||||
if is_test_running_but_stop_pressed():
|
||||
# Do stop test execution when the user has stoped the main scene manually
|
||||
if test_session_command._is_debug and test_session_command.is_running() and not EditorInterface.is_playing_scene():
|
||||
if GdUnitSettings.is_verbose_assert_warnings():
|
||||
push_warning("Test Runner scene was stopped manually, force stopping the current test run!")
|
||||
cmd_stop(_client_id)
|
||||
print_debug("Test Runner scene was stopped manually, force stopping the current test run!")
|
||||
command_execute(GdUnitCommandStopTestSession.ID)
|
||||
|
||||
|
||||
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():
|
||||
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():
|
||||
if shortcut == GdUnitShortcut.ShortCut.NONE:
|
||||
continue
|
||||
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:
|
||||
keys = property.value()
|
||||
var inputEvent := create_shortcut_input_even(keys)
|
||||
register_shortcut(shortcut, inputEvent)
|
||||
|
||||
|
||||
func create_shortcut_input_even(key_codes: PackedInt32Array) -> InputEventKey:
|
||||
var inputEvent := InputEventKey.new()
|
||||
inputEvent.pressed = true
|
||||
for key_code in key_codes:
|
||||
match key_code:
|
||||
KEY_ALT:
|
||||
inputEvent.alt_pressed = true
|
||||
KEY_SHIFT:
|
||||
inputEvent.shift_pressed = true
|
||||
KEY_CTRL:
|
||||
inputEvent.ctrl_pressed = true
|
||||
_:
|
||||
inputEvent.keycode = key_code as Key
|
||||
inputEvent.physical_keycode = key_code as Key
|
||||
return inputEvent
|
||||
|
||||
|
||||
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 := get_shortcut_command(p_shortcut)
|
||||
_shortcuts[p_shortcut] = GdUnitShortcutAction.new(p_shortcut, shortcut, command_name)
|
||||
|
||||
|
||||
func get_shortcut(shortcut_type: GdUnitShortcut.ShortCut) -> Shortcut:
|
||||
return get_shortcut_action(shortcut_type).shortcut
|
||||
|
||||
|
||||
func get_shortcut_action(shortcut_type: GdUnitShortcut.ShortCut) -> GdUnitShortcutAction:
|
||||
return _shortcuts.get(shortcut_type)
|
||||
|
||||
|
||||
func get_shortcut_command(p_shortcut: GdUnitShortcut.ShortCut) -> String:
|
||||
return CommandMapping.get(p_shortcut, "unknown command")
|
||||
|
||||
|
||||
func register_command(p_command: GdUnitCommand) -> void:
|
||||
_commands[p_command.name] = p_command
|
||||
|
||||
|
||||
func command(cmd_name: String) -> GdUnitCommand:
|
||||
return _commands.get(cmd_name)
|
||||
|
||||
|
||||
func cmd_run_test_suites(scripts: Array[Script], debug: bool, rerun := false) -> void:
|
||||
# Update test discovery
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverStart.new())
|
||||
var tests_to_execute: Array[GdUnitTestCase] = []
|
||||
for script in scripts:
|
||||
GdUnitTestDiscoverer.discover_tests(script, func(test_case: GdUnitTestCase) -> void:
|
||||
tests_to_execute.append(test_case)
|
||||
GdUnitTestDiscoverSink.discover(test_case)
|
||||
)
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverEnd.new(0, 0))
|
||||
GdUnitTestDiscoverer.console_log_discover_results(tests_to_execute)
|
||||
|
||||
# create new runner runner_config for fresh run otherwise use saved one
|
||||
if not rerun:
|
||||
var result := _runner_config.clear()\
|
||||
.add_test_cases(tests_to_execute)\
|
||||
.save_config()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
return
|
||||
cmd_run(debug)
|
||||
|
||||
|
||||
func cmd_run_test_case(script: Script, test_case: String, test_param_index: int, debug: bool, rerun := false) -> void:
|
||||
# Update test discovery
|
||||
var tests_to_execute: Array[GdUnitTestCase] = []
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverStart.new())
|
||||
GdUnitTestDiscoverer.discover_tests(script, func(test: GdUnitTestCase) -> void:
|
||||
# We filter for a single test
|
||||
if test.test_name == test_case:
|
||||
# We only add selected parameterized test to the execution list
|
||||
if test_param_index == -1:
|
||||
tests_to_execute.append(test)
|
||||
elif test.attribute_index == test_param_index:
|
||||
tests_to_execute.append(test)
|
||||
GdUnitTestDiscoverSink.discover(test)
|
||||
)
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverEnd.new(0, 0))
|
||||
GdUnitTestDiscoverer.console_log_discover_results(tests_to_execute)
|
||||
|
||||
# create new runner config for fresh run otherwise use saved one
|
||||
if not rerun:
|
||||
var result := _runner_config.clear()\
|
||||
.add_test_cases(tests_to_execute)\
|
||||
.save_config()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
return
|
||||
cmd_run(debug)
|
||||
|
||||
|
||||
func cmd_run_tests(tests_to_execute: Array[GdUnitTestCase], debug: bool) -> void:
|
||||
# Save tests to runner config before execute
|
||||
var result := _runner_config.clear()\
|
||||
.add_test_cases(tests_to_execute)\
|
||||
.save_config()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
func command_icon(command_id: String) -> Texture2D:
|
||||
if not _commnand_mappings.has(command_id):
|
||||
push_error("GdUnitCommandHandler:command_icon(): No command id '%s' is registered." % command_id)
|
||||
print_stack()
|
||||
return
|
||||
cmd_run(debug)
|
||||
return _commnand_mappings[command_id].icon
|
||||
|
||||
|
||||
func cmd_run_overall(debug: bool) -> void:
|
||||
var tests_to_execute := await GdUnitTestDiscoverer.run()
|
||||
var result := _runner_config.clear()\
|
||||
.add_test_cases(tests_to_execute)\
|
||||
.save_config()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
func command_shortcut(command_id: String) -> Shortcut:
|
||||
if not _commnand_mappings.has(command_id):
|
||||
push_error("GdUnitCommandHandler:command_shortcut(): No command id '%s' is registered." % command_id)
|
||||
print_stack()
|
||||
return
|
||||
cmd_run(debug)
|
||||
return _commnand_mappings[command_id].shortcut
|
||||
|
||||
|
||||
func cmd_run(debug: bool) -> void:
|
||||
# don't start is already running
|
||||
if _is_running:
|
||||
func command_execute(...parameters: Array) -> void:
|
||||
if parameters.is_empty():
|
||||
push_error("Invalid arguments used on CommandHandler:execute()! Expecting [<command_id, args...>]")
|
||||
print_stack()
|
||||
return
|
||||
|
||||
# save current selected excution config
|
||||
var server_port: int = Engine.get_meta("gdunit_server_port")
|
||||
var result := _runner_config.set_server_port(server_port).save_config()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
var command_id: String = parameters.pop_front()
|
||||
if not _commnand_mappings.has(command_id):
|
||||
push_error("GdUnitCommandHandler:command_execute(): No command id '%s' is registered." % command_id)
|
||||
print_stack()
|
||||
return
|
||||
# before start we have to save all changes
|
||||
ScriptEditorControls.save_all_open_script()
|
||||
gdunit_runner_start.emit()
|
||||
_current_runner_process_id = -1
|
||||
_running_debug_mode = debug
|
||||
if debug:
|
||||
run_debug_mode()
|
||||
else:
|
||||
run_release_mode()
|
||||
await _commnand_mappings[command_id].callv("execute", parameters)
|
||||
|
||||
|
||||
func cmd_stop(client_id: int) -> void:
|
||||
# don't stop if is already stopped
|
||||
if not _is_running:
|
||||
func _register_command(command: GdUnitBaseCommand) -> void:
|
||||
# first verify the command is not already registerd
|
||||
if _commnand_mappings.has(command.id):
|
||||
push_error("GdUnitCommandHandler:_register_command(): Command with id '%s' is already registerd!" % command.id)
|
||||
return
|
||||
_is_running = false
|
||||
gdunit_runner_stop.emit(client_id)
|
||||
if _running_debug_mode:
|
||||
EditorInterface.stop_playing_scene()
|
||||
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:
|
||||
push_error("ERROR checked stopping GdUnit Test Runner. error code: %s" % result)
|
||||
_current_runner_process_id = -1
|
||||
|
||||
|
||||
func cmd_editor_run_test(debug: bool) -> void:
|
||||
if is_active_script_editor():
|
||||
var cursor_line := active_base_editor().get_caret_line()
|
||||
#run test case?
|
||||
var regex := RegEx.new()
|
||||
@warning_ignore("return_value_discarded")
|
||||
regex.compile("(^func[ ,\t])(test_[a-zA-Z0-9_]*)")
|
||||
var result := regex.search(active_base_editor().get_line(cursor_line))
|
||||
if result:
|
||||
var func_name := result.get_string(2).strip_edges()
|
||||
if func_name.begins_with("test_"):
|
||||
cmd_run_test_case(active_script(), func_name, -1, debug)
|
||||
return
|
||||
# otherwise run the full test suite
|
||||
var selected_test_suites: Array[Script] = [active_script()]
|
||||
cmd_run_test_suites(selected_test_suites, debug)
|
||||
|
||||
|
||||
func cmd_create_test() -> void:
|
||||
if not is_active_script_editor():
|
||||
return
|
||||
var cursor_line := active_base_editor().get_caret_line()
|
||||
var result := GdUnitTestSuiteBuilder.create(active_script(), cursor_line)
|
||||
if result.is_error():
|
||||
# show error dialog
|
||||
push_error("Failed to create test case: %s" % result.error_message())
|
||||
return
|
||||
var info: Dictionary = result.value()
|
||||
var script_path: String = info.get("path")
|
||||
var script_line: int = info.get("line")
|
||||
ScriptEditorControls.edit_script(script_path, script_line)
|
||||
_commnand_mappings[command.id] = command
|
||||
if Engine.is_editor_hint():
|
||||
EditorInterface.get_base_control().add_child(command)
|
||||
EditorInterface.get_command_palette().add_command(command.id, "GdUnit4/"+command.id, command.execute, command.shortcut.get_as_text() if command.shortcut else "None")
|
||||
|
||||
|
||||
func cmd_discover_tests() -> void:
|
||||
await GdUnitTestDiscoverer.run()
|
||||
|
||||
|
||||
func run_debug_mode() -> void:
|
||||
EditorInterface.play_custom_scene("res://addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn")
|
||||
_is_running = true
|
||||
|
||||
|
||||
func run_release_mode() -> void:
|
||||
var arguments := Array()
|
||||
if OS.is_stdout_verbose():
|
||||
arguments.append("--verbose")
|
||||
arguments.append("--no-window")
|
||||
arguments.append("--path")
|
||||
arguments.append(ProjectSettings.globalize_path("res://"))
|
||||
arguments.append("res://addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn")
|
||||
_current_runner_process_id = OS.create_process(OS.get_executable_path(), arguments, false);
|
||||
_is_running = true
|
||||
|
||||
|
||||
func is_active_script_editor() -> bool:
|
||||
return EditorInterface.get_script_editor().get_current_editor() != null
|
||||
|
||||
|
||||
func active_base_editor() -> TextEdit:
|
||||
return EditorInterface.get_script_editor().get_current_editor().get_base_editor()
|
||||
|
||||
|
||||
func active_script() -> Script:
|
||||
return EditorInterface.get_script_editor().get_current_script()
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# signals handles
|
||||
################################################################################
|
||||
func _on_event(event: GdUnitEvent) -> void:
|
||||
if event.type() == GdUnitEvent.SESSION_CLOSE:
|
||||
cmd_stop(_client_id)
|
||||
|
||||
|
||||
func _on_stop_pressed() -> void:
|
||||
cmd_stop(_client_id)
|
||||
|
||||
|
||||
func _on_run_pressed(debug := false) -> void:
|
||||
cmd_run(debug)
|
||||
|
||||
|
||||
func _on_run_overall_pressed(_debug := false) -> void:
|
||||
cmd_run_overall(true)
|
||||
command_execute(GdUnitCommandStopTestSession.ID)
|
||||
|
||||
|
||||
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()
|
||||
var input_event := create_shortcut_input_even(value)
|
||||
prints("Shortcut changed: '%s' to '%s'" % [GdUnitShortcut.ShortCut.keys()[shortcut], input_event.as_text()])
|
||||
var action := get_shortcut_action(shortcut)
|
||||
if action != null:
|
||||
action.update_shortcut(input_event)
|
||||
else:
|
||||
register_shortcut(shortcut, input_event)
|
||||
for command: GdUnitBaseCommand in _commnand_mappings.values():
|
||||
command.update_shortcut()
|
||||
|
||||
if property.name() == GdUnitSettings.TEST_DISCOVER_ENABLED:
|
||||
var timer :SceneTreeTimer = (Engine.get_main_loop() as SceneTree).create_timer(3)
|
||||
@warning_ignore("return_value_discarded")
|
||||
@@ -397,12 +122,5 @@ func _on_settings_changed(property: GdUnitProperty) -> void:
|
||||
################################################################################
|
||||
# Network stuff
|
||||
################################################################################
|
||||
func _on_client_connected(client_id: int) -> void:
|
||||
_client_id = client_id
|
||||
|
||||
|
||||
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)
|
||||
_client_id = -1
|
||||
func _on_client_disconnected(_client_id: int) -> void:
|
||||
command_execute(GdUnitCommandStopTestSession.ID)
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dooc00u4rahqp
|
||||
uid://c78scrs3jstsk
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
class_name GdUnitCommandInspectorDebugTests
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
const InspectorTreeMainPanel := preload("res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd")
|
||||
const ID := "Debug Inspector Tests"
|
||||
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG)
|
||||
icon = GdUnitUiTools.get_icon("PlayStart")
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
var base_control := EditorInterface.get_base_control()
|
||||
var inspector: InspectorTreeMainPanel = base_control.get_meta("GdUnit4Inspector")
|
||||
var selected_item := inspector._tree.get_selected()
|
||||
var tests_to_execute := inspector.collect_test_cases(selected_item)
|
||||
|
||||
_test_session_command.execute(tests_to_execute, true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cgge1kdbo3d3s
|
||||
@@ -0,0 +1,57 @@
|
||||
class_name GdUnitCommandInspectorRerunTestsUntilFailure
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
|
||||
signal session_closed()
|
||||
|
||||
|
||||
const InspectorTreeMainPanel := preload("res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd")
|
||||
const ID := "Rerun Inspector Tests Until Failure"
|
||||
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
var _current_execution_count := 0
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RERUN_TESTS_UNTIL_FAILURE)
|
||||
icon = GdUnitUiTools.get_icon("Play")
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
var base_control := EditorInterface.get_base_control()
|
||||
var inspector: InspectorTreeMainPanel = base_control.get_meta("GdUnit4Inspector")
|
||||
var selected_item := inspector._tree.get_selected()
|
||||
var tests_to_execute := inspector.collect_test_cases(selected_item)
|
||||
var rerun_until_failure_count := GdUnitSettings.get_rerun_max_retries()
|
||||
var saved_settings := ProjectSettings.get_setting(GdUnitSettings.TEST_FLAKY_CHECK)
|
||||
ProjectSettings.set_setting(GdUnitSettings.TEST_FLAKY_CHECK, false)
|
||||
|
||||
GdUnitSignals.instance().gdunit_event.connect(_on_test_event)
|
||||
_current_execution_count = 0
|
||||
|
||||
_test_session_command._is_fail_fast = true
|
||||
while _current_execution_count < rerun_until_failure_count:
|
||||
_test_session_command.execute(tests_to_execute, true)
|
||||
await session_closed
|
||||
_test_session_command._is_fail_fast = false
|
||||
|
||||
ProjectSettings.set_setting(GdUnitSettings.TEST_FLAKY_CHECK, saved_settings)
|
||||
GdUnitSignals.instance().gdunit_event.disconnect(_on_test_event)
|
||||
|
||||
|
||||
func _on_test_event(event: GdUnitEvent) -> void:
|
||||
if event.type() == GdUnitEvent.SESSION_START:
|
||||
_current_execution_count += 1
|
||||
GdUnitSignals.instance().gdunit_message.emit("[color=RED]Execution Mode: ReRun until failure! (iteration %d)[/color]" % _current_execution_count)
|
||||
if event.type() == GdUnitEvent.SESSION_CLOSE:
|
||||
session_closed.emit()
|
||||
if event.type() == GdUnitEvent.TESTCASE_AFTER:
|
||||
if not event.is_success():
|
||||
GdUnitSignals.instance().gdunit_message.emit(" [color=RED](iteration: %d)[/color]" % _current_execution_count)
|
||||
_current_execution_count = 9999
|
||||
@@ -0,0 +1 @@
|
||||
uid://djooccc2lximb
|
||||
@@ -0,0 +1,26 @@
|
||||
class_name GdUnitCommandInspectorRunTests
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
const InspectorTreeMainPanel := preload("res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd")
|
||||
const ID := "Run Inspector Tests"
|
||||
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RERUN_TESTS)
|
||||
icon = GdUnitUiTools.get_icon("Play")
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
var base_control := EditorInterface.get_base_control()
|
||||
var inspector: InspectorTreeMainPanel = base_control.get_meta("GdUnit4Inspector")
|
||||
var selected_item := inspector._tree.get_selected()
|
||||
var tests_to_execute := inspector.collect_test_cases(selected_item)
|
||||
_test_session_command.execute(tests_to_execute, false)
|
||||
@@ -0,0 +1 @@
|
||||
uid://4v3l7qmq7kug
|
||||
@@ -0,0 +1,26 @@
|
||||
class_name GdUnitCommandInspectorTreeCollapse
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
const InspectorTreeMainPanel := preload("res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd")
|
||||
const ID := "Inspector Tree Collapse"
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.NONE)
|
||||
icon = GdUnitUiTools.get_icon("CollapseTree")
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
var inspector: InspectorTreeMainPanel = EditorInterface.get_base_control().get_meta("GdUnit4Inspector")
|
||||
var selected_item := inspector._tree.get_selected()
|
||||
if selected_item == null:
|
||||
selected_item = inspector._tree.get_root()
|
||||
else:
|
||||
selected_item = selected_item.get_parent()
|
||||
|
||||
inspector.do_collapse_all(false, selected_item)
|
||||
inspector.do_collapse_all(true, selected_item)
|
||||
@@ -0,0 +1 @@
|
||||
uid://kwhwh58fwv7k
|
||||
@@ -0,0 +1,25 @@
|
||||
class_name GdUnitCommandInspectorTreeExpand
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
const InspectorTreeMainPanel := preload("res://addons/gdUnit4/src/ui/parts/InspectorTreeMainPanel.gd")
|
||||
const ID := "Inspector Tree Expand"
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.NONE)
|
||||
icon = GdUnitUiTools.get_icon("ExpandTree")
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
var inspector: InspectorTreeMainPanel = EditorInterface.get_base_control().get_meta("GdUnit4Inspector")
|
||||
var selected_item := inspector._tree.get_selected()
|
||||
if selected_item == null:
|
||||
selected_item = inspector._tree.get_root()
|
||||
else:
|
||||
selected_item = selected_item.get_parent()
|
||||
|
||||
inspector.do_collapse_all(false, selected_item)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bebld08cdue37
|
||||
@@ -0,0 +1,22 @@
|
||||
class_name GdUnitCommandRunTestsOverall
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
const ID := "Run Tests Overall"
|
||||
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RUN_TESTS_OVERALL)
|
||||
icon = GdUnitUiTools.get_run_overall_icon()
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
var tests_to_execute := await GdUnitTestDiscoverer.run()
|
||||
_test_session_command.execute(tests_to_execute, true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cxw4tubqwvd0l
|
||||
56
addons/gdUnit4/src/core/command/GdUnitCommandScriptEditor.gd
Normal file
56
addons/gdUnit4/src/core/command/GdUnitCommandScriptEditor.gd
Normal file
@@ -0,0 +1,56 @@
|
||||
@abstract class_name GdUnitCommandScriptEditor
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
|
||||
func _init(p_id: String, p_shortcut: GdUnitShortcut.ShortCut, test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(p_id, p_shortcut)
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute_tests(with_debug: bool) -> void:
|
||||
var selected_tests := PackedStringArray()
|
||||
if _is_active_script_editor():
|
||||
var cursor_line := _active_base_editor().get_caret_line()
|
||||
#run test case?
|
||||
var regex := RegEx.new()
|
||||
@warning_ignore("return_value_discarded")
|
||||
regex.compile("(^func[ ,\t])(test_[a-zA-Z0-9_]*)")
|
||||
var result := regex.search(_active_base_editor().get_line(cursor_line))
|
||||
if result:
|
||||
var func_name := result.get_string(2).strip_edges()
|
||||
if func_name.begins_with("test_"):
|
||||
selected_tests.append(func_name)
|
||||
|
||||
var tests_to_execute := _collect_tests(_active_script(), selected_tests)
|
||||
_test_session_command.execute(tests_to_execute, with_debug)
|
||||
|
||||
|
||||
func _collect_tests(script: Script, tests: PackedStringArray) -> Array[GdUnitTestCase]:
|
||||
# Update test discovery
|
||||
var tests_to_execute: Array[GdUnitTestCase] = []
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverStart.new())
|
||||
GdUnitTestDiscoverer.discover_tests(script, func(test: GdUnitTestCase) -> void:
|
||||
if tests.is_empty() or tests.has(test.test_name):
|
||||
tests_to_execute.append(test)
|
||||
GdUnitTestDiscoverSink.discover(test)
|
||||
)
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitEventTestDiscoverEnd.new(0, 0))
|
||||
GdUnitTestDiscoverer.console_log_discover_results(tests_to_execute)
|
||||
return tests_to_execute
|
||||
|
||||
|
||||
func _is_active_script_editor() -> bool:
|
||||
return EditorInterface.get_script_editor().get_current_editor() != null
|
||||
|
||||
|
||||
func _active_base_editor() -> TextEdit:
|
||||
return EditorInterface.get_script_editor().get_current_editor().get_base_editor()
|
||||
|
||||
|
||||
func _active_script() -> Script:
|
||||
return EditorInterface.get_script_editor().get_current_script()
|
||||
@@ -0,0 +1 @@
|
||||
uid://b8ed2knx2w43g
|
||||
@@ -0,0 +1,41 @@
|
||||
class_name GdUnitCommandScriptEditorCreateTest
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
|
||||
const ID := "Create Test"
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.CREATE_TEST)
|
||||
icon = GdUnitUiTools.get_icon("New")
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
if not _is_active_script_editor():
|
||||
return
|
||||
var cursor_line := _active_base_editor().get_caret_line()
|
||||
var result := GdUnitTestSuiteBuilder.create(_active_script(), cursor_line)
|
||||
if result.is_error():
|
||||
# show error dialog
|
||||
push_error("Failed to create test case: %s" % result.error_message())
|
||||
return
|
||||
var info: Dictionary = result.value()
|
||||
var script_path: String = info.get("path")
|
||||
var script_line: int = info.get("line")
|
||||
ScriptEditorControls.edit_script(script_path, script_line)
|
||||
|
||||
|
||||
func _is_active_script_editor() -> bool:
|
||||
return EditorInterface.get_script_editor().get_current_editor() != null
|
||||
|
||||
|
||||
func _active_base_editor() -> TextEdit:
|
||||
return EditorInterface.get_script_editor().get_current_editor().get_base_editor()
|
||||
|
||||
|
||||
func _active_script() -> Script:
|
||||
return EditorInterface.get_script_editor().get_current_script()
|
||||
@@ -0,0 +1 @@
|
||||
uid://be5yc60ppts7a
|
||||
@@ -0,0 +1,14 @@
|
||||
class_name GdUnitCommandScriptEditorDebugTests
|
||||
extends GdUnitCommandScriptEditor
|
||||
|
||||
|
||||
const ID := "Debug ScriptEditor Tests"
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RUN_TESTCASE_DEBUG, test_session_command)
|
||||
icon = GdUnitUiTools.get_icon("PlayStart")
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
execute_tests(true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://8ccganhkrt2o
|
||||
@@ -0,0 +1,14 @@
|
||||
class_name GdUnitCommandScriptEditorRunTests
|
||||
extends GdUnitCommandScriptEditor
|
||||
|
||||
|
||||
const ID := "Run ScriptEditor Tests"
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.RUN_TESTCASE, test_session_command)
|
||||
icon = GdUnitUiTools.get_icon("Play")
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
execute_tests(false)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cnh8uhd8gnxxc
|
||||
@@ -0,0 +1,21 @@
|
||||
class_name GdUnitCommandStopTestSession
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
const ID := "Stop Test Session"
|
||||
|
||||
|
||||
var _test_session_command: GdUnitCommandTestSession
|
||||
|
||||
|
||||
func _init(test_session_command: GdUnitCommandTestSession) -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.STOP_TEST_RUN)
|
||||
icon = GdUnitUiTools.get_icon("Stop")
|
||||
_test_session_command = test_session_command
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _test_session_command.is_running()
|
||||
|
||||
|
||||
func execute(..._parameters: Array) -> void:
|
||||
await _test_session_command.stop()
|
||||
@@ -0,0 +1 @@
|
||||
uid://csffxdh5jm5rn
|
||||
124
addons/gdUnit4/src/core/command/GdUnitCommandTestSession.gd
Normal file
124
addons/gdUnit4/src/core/command/GdUnitCommandTestSession.gd
Normal file
@@ -0,0 +1,124 @@
|
||||
class_name GdUnitCommandTestSession
|
||||
extends GdUnitBaseCommand
|
||||
|
||||
|
||||
const ID := "Start Test Session"
|
||||
|
||||
|
||||
var _current_runner_process_id: int
|
||||
var _is_running: bool
|
||||
var _is_debug: bool
|
||||
var _is_fail_fast: bool
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
super(ID, GdUnitShortcut.ShortCut.NONE)
|
||||
_is_running = false
|
||||
_is_fail_fast = false
|
||||
|
||||
|
||||
func is_running() -> bool:
|
||||
return _is_running
|
||||
|
||||
|
||||
func stop() -> void:
|
||||
if not is_running():
|
||||
return
|
||||
_is_running = false
|
||||
|
||||
if _is_debug:
|
||||
force_pause_scene()
|
||||
|
||||
GdUnitSignals.instance().gdunit_test_session_terminate.emit()
|
||||
# Give the API time to commit terminate to the client
|
||||
await get_tree().create_timer(.5).timeout
|
||||
|
||||
if _is_debug and EditorInterface.is_playing_scene():
|
||||
EditorInterface.stop_playing_scene()
|
||||
# We need finaly to send the test session close event because the current run is hard aborted.
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitSessionClose.new())
|
||||
elif OS.is_process_running(_current_runner_process_id):
|
||||
var result := OS.kill(_current_runner_process_id)
|
||||
if result != OK:
|
||||
push_error("ERROR checked stopping GdUnit Test Runner. error code: %s" % result)
|
||||
_current_runner_process_id = -1
|
||||
# We need finaly to send the test session close event because the current run is hard aborted.
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitSessionClose.new())
|
||||
|
||||
|
||||
## Forces the running scene to unpause when the debugger hits a breakpoint.[br]
|
||||
## [br]
|
||||
## When the Godot debugger stops at a breakpoint during test execution, it blocks[br]
|
||||
## the main thread. This prevents signals and TCP communications from being processed,[br]
|
||||
## which can cause GdUnit4 tests to hang or fail to communicate properly with the[br]
|
||||
## test runner. This function programmatically unpauses the scene to restore[br]
|
||||
## main thread execution while maintaining debugger functionality. [br]
|
||||
## [br]
|
||||
## [b]Technical Background:[/b][br]
|
||||
## - Debugger breakpoints freeze the main thread to allow inspection[br]
|
||||
## - Frozen main thread blocks signal processing and network communications[br]
|
||||
## - GdUnit4 requires active signal/TCP processing for test coordination[br]
|
||||
## - This function finds and triggers the editor's pause button to resume execution[br]
|
||||
## [br]
|
||||
## [b]How It Works:[/b][br]
|
||||
## 1. Locates the EditorRunBar in the Godot editor UI hierarchy[br]
|
||||
## 2. Searches for the pause button by matching its icon[br]
|
||||
## 3. Unpresses the button if it's currently pressed (paused state)[br]
|
||||
## 4. Manually triggers the button's connected callbacks to resume execution[br]
|
||||
func force_pause_scene() -> bool:
|
||||
var nodes := EditorInterface.get_base_control().find_children("*", "EditorRunBar", true, false)
|
||||
if nodes.size() != 1:
|
||||
push_error("GdUnitCommandTestSession:force_pause_scene() Can't find Editor component 'EditorRunBar'")
|
||||
return false
|
||||
var editor_run_bar := nodes[0]
|
||||
var containers := editor_run_bar.find_children("*", "HBoxContainer", true, false)
|
||||
var pause_icon := GdUnitUiTools.get_icon("Pause")
|
||||
|
||||
for container in containers:
|
||||
for child in container.get_children():
|
||||
if child is Button:
|
||||
var button: Button = child
|
||||
if pause_icon == button.icon:
|
||||
button.set_pressed(false)
|
||||
|
||||
var connected_signals := button.get_signal_connection_list("pressed")
|
||||
if not connected_signals.is_empty():
|
||||
for signal_ in connected_signals:
|
||||
var cb: Callable = signal_["callable"]
|
||||
cb.call()
|
||||
return true
|
||||
push_error("GdUnitCommandTestSession:force_pause_scene() Can't find Editor component 'EditorRunBar'")
|
||||
return false
|
||||
|
||||
|
||||
func execute(...parameters: Array) -> void:
|
||||
var tests_to_execute: Array[GdUnitTestCase] = parameters[0]
|
||||
_is_debug = parameters[1]
|
||||
|
||||
_prepare_test_session(tests_to_execute)
|
||||
if _is_debug:
|
||||
EditorInterface.play_custom_scene("res://addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn")
|
||||
else:
|
||||
var arguments := Array()
|
||||
if OS.is_stdout_verbose():
|
||||
arguments.append("--verbose")
|
||||
arguments.append("--no-window")
|
||||
arguments.append("--path")
|
||||
arguments.append(ProjectSettings.globalize_path("res://"))
|
||||
arguments.append("res://addons/gdUnit4/src/core/runners/GdUnitTestRunner.tscn")
|
||||
_current_runner_process_id = OS.create_process(OS.get_executable_path(), arguments, false);
|
||||
_is_running = true
|
||||
|
||||
|
||||
func _prepare_test_session(tests_to_execute: Array[GdUnitTestCase]) -> void:
|
||||
var server_port: int = Engine.get_meta("gdunit_server_port")
|
||||
var result := GdUnitRunnerConfig.new() \
|
||||
.set_server_port(server_port) \
|
||||
.do_fail_fast(_is_fail_fast) \
|
||||
.add_test_cases(tests_to_execute) \
|
||||
.save_config()
|
||||
if result.is_error():
|
||||
push_error(result.error_message())
|
||||
return
|
||||
# before start we have to save all scrpt changes
|
||||
ScriptEditorControls.save_all_open_script()
|
||||
@@ -0,0 +1 @@
|
||||
uid://ch3v5vvl0bt8i
|
||||
@@ -11,6 +11,7 @@ enum ShortCut {
|
||||
RUN_TESTSUITE_DEBUG,
|
||||
RERUN_TESTS,
|
||||
RERUN_TESTS_DEBUG,
|
||||
RERUN_TESTS_UNTIL_FAILURE,
|
||||
STOP_TEST_RUN,
|
||||
CREATE_TEST,
|
||||
}
|
||||
@@ -19,30 +20,50 @@ const DEFAULTS_MACOS := {
|
||||
ShortCut.NONE : [],
|
||||
ShortCut.RUN_TESTCASE : [Key.KEY_META, Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.RUN_TESTCASE_DEBUG : [Key.KEY_META, Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTSUITE : [Key.KEY_META, Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.RUN_TESTSUITE_DEBUG : [Key.KEY_META, Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTSUITE : [Key.KEY_ALT, Key.KEY_META, Key.KEY_F5],
|
||||
ShortCut.RUN_TESTSUITE_DEBUG : [Key.KEY_ALT, Key.KEY_META, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTS_OVERALL : [Key.KEY_ALT, Key.KEY_F7],
|
||||
ShortCut.STOP_TEST_RUN : [Key.KEY_ALT, Key.KEY_F8],
|
||||
ShortCut.RERUN_TESTS : [Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.RERUN_TESTS_DEBUG : [Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RERUN_TESTS_UNTIL_FAILURE : [Key.KEY_ALT, Key.KEY_META, Key.KEY_F5],
|
||||
ShortCut.CREATE_TEST : [Key.KEY_META, Key.KEY_ALT, Key.KEY_F10],
|
||||
}
|
||||
|
||||
const DEFAULTS_WINDOWS := {
|
||||
ShortCut.NONE : [],
|
||||
ShortCut.RUN_TESTCASE : [Key.KEY_CTRL, Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.RUN_TESTCASE_DEBUG : [Key.KEY_CTRL,Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTSUITE : [Key.KEY_CTRL, Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.RUN_TESTSUITE_DEBUG : [Key.KEY_CTRL,Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTCASE_DEBUG : [Key.KEY_CTRL, Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTSUITE : [Key.KEY_ALT, Key.KEY_SHIFT, Key.KEY_F5],
|
||||
ShortCut.RUN_TESTSUITE_DEBUG : [Key.KEY_ALT, Key.KEY_SHIFT, Key.KEY_F6],
|
||||
ShortCut.RUN_TESTS_OVERALL : [Key.KEY_ALT, Key.KEY_F7],
|
||||
ShortCut.STOP_TEST_RUN : [Key.KEY_ALT, Key.KEY_F8],
|
||||
ShortCut.RERUN_TESTS : [Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.RERUN_TESTS_DEBUG : [Key.KEY_ALT, Key.KEY_F6],
|
||||
ShortCut.RERUN_TESTS_UNTIL_FAILURE : [Key.KEY_CTRL, Key.KEY_ALT, Key.KEY_F5],
|
||||
ShortCut.CREATE_TEST : [Key.KEY_CTRL, Key.KEY_ALT, Key.KEY_F10],
|
||||
}
|
||||
|
||||
|
||||
static func default_keys(shortcut :ShortCut) -> PackedInt32Array:
|
||||
const SETTINGS_MAPPING: Dictionary[ShortCut, String] = {
|
||||
ShortCut.RUN_TESTCASE : GdUnitSettings.SHORTCUT_EDITOR_RUN_TEST,
|
||||
ShortCut.RUN_TESTCASE_DEBUG : GdUnitSettings.SHORTCUT_EDITOR_RUN_TEST_DEBUG,
|
||||
ShortCut.CREATE_TEST : GdUnitSettings.SHORTCUT_EDITOR_CREATE_TEST,
|
||||
ShortCut.RERUN_TESTS : GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST,
|
||||
ShortCut.RERUN_TESTS_DEBUG : GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG,
|
||||
ShortCut.RERUN_TESTS_UNTIL_FAILURE : GdUnitSettings.SHORTCUT_INSPECTOR_RERUN_TEST_UNTIL_FAILURE,
|
||||
ShortCut.STOP_TEST_RUN : GdUnitSettings.SHORTCUT_INSPECTOR_RUN_TEST_STOP,
|
||||
ShortCut.RUN_TESTS_OVERALL : GdUnitSettings.SHORTCUT_INSPECTOR_RUN_TEST_OVERALL,
|
||||
ShortCut.RUN_TESTSUITE : GdUnitSettings.SHORTCUT_FILESYSTEM_RUN_TEST,
|
||||
ShortCut.RUN_TESTSUITE_DEBUG : GdUnitSettings.SHORTCUT_FILESYSTEM_RUN_TEST_DEBUG
|
||||
}
|
||||
|
||||
|
||||
static func as_property(sortcut: ShortCut) -> String:
|
||||
return SETTINGS_MAPPING[sortcut]
|
||||
|
||||
|
||||
static func default_keys(shortcut: ShortCut) -> PackedInt32Array:
|
||||
match OS.get_name().to_lower():
|
||||
'windows':
|
||||
return DEFAULTS_WINDOWS[shortcut]
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bsg0clvy7wf0m
|
||||
uid://xmx5cn8rhpa
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
class_name GdUnitShortcutAction
|
||||
extends RefCounted
|
||||
|
||||
|
||||
func _init(p_type :GdUnitShortcut.ShortCut, p_shortcut :Shortcut, p_command :String) -> void:
|
||||
assert(p_type != null, "missing parameter 'type'")
|
||||
assert(p_shortcut != null, "missing parameter 'shortcut'")
|
||||
assert(p_command != null, "missing parameter 'command'")
|
||||
self.type = p_type
|
||||
self.shortcut = p_shortcut
|
||||
self.command = p_command
|
||||
|
||||
|
||||
var type: GdUnitShortcut.ShortCut:
|
||||
set(value):
|
||||
type = value
|
||||
get:
|
||||
return type
|
||||
|
||||
|
||||
var shortcut: Shortcut:
|
||||
set(value):
|
||||
shortcut = value
|
||||
get:
|
||||
return shortcut
|
||||
|
||||
|
||||
var command: String:
|
||||
set(value):
|
||||
command = value
|
||||
get:
|
||||
return command
|
||||
|
||||
|
||||
func update_shortcut(input_event: InputEventKey) -> void:
|
||||
shortcut.set_events([input_event])
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
return "GdUnitShortcutAction: %s (%s) -> %s" % [GdUnitShortcut.ShortCut.keys()[type], shortcut.get_as_text(), command]
|
||||
@@ -1 +0,0 @@
|
||||
uid://cmlh3hniafm5s
|
||||
@@ -1 +1 @@
|
||||
uid://d4lobvde8tufj
|
||||
uid://db25rfeu4v25p
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://i4kgxeu6rjiv
|
||||
uid://dwqwv278b5sji
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cojycdwxjbkf3
|
||||
uid://v1jl5pcf7err
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ct0kk6824vhxf
|
||||
uid://d3defrdskwh0y
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://uakc3vyaaagr
|
||||
uid://xdtvoikcir7n
|
||||
|
||||
@@ -132,7 +132,7 @@ func is_success() -> bool:
|
||||
|
||||
|
||||
func is_warning() -> bool:
|
||||
return _statistics.get(WARNINGS, false)
|
||||
return _statistics.get(WARNINGS, false) or orphan_nodes() > 0
|
||||
|
||||
|
||||
func is_failed() -> bool:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://c4wkq83n4a4bk
|
||||
uid://cgwcvamqj1uyi
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://c8t36rmkcsvqm
|
||||
uid://tu5npta2qjg3
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cg768i3qgef2x
|
||||
uid://dxelfts5smut4
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bt4blgp4lw3p0
|
||||
uid://clm4vcs4ix5yc
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://npuh47e34ud2
|
||||
uid://dyf62y71o1l8m
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://eqiw85rg4fgn
|
||||
uid://dwnfnd5ttpt66
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://hpagtimkbhev
|
||||
uid://b7xtnak82y5mh
|
||||
|
||||
@@ -22,7 +22,6 @@ var _name: String
|
||||
var _test_execution_iteration: int = 0
|
||||
var _flaky_test_check := GdUnitSettings.is_test_flaky_check_enabled()
|
||||
var _flaky_test_retries := GdUnitSettings.get_flaky_max_retries()
|
||||
var _orphans := -1
|
||||
|
||||
|
||||
var error_monitor: GodotGdErrorMonitor = null:
|
||||
@@ -53,7 +52,11 @@ func _init(name: StringName, parent_context: GdUnitExecutionContext = null) -> v
|
||||
_parent_context = parent_context
|
||||
_timer = LocalTime.now()
|
||||
_orphan_monitor = GdUnitOrphanNodesMonitor.new(name)
|
||||
_orphan_monitor.start()
|
||||
|
||||
if parent_context != null:
|
||||
parent_context._orphan_monitor.add_child_monitor(_orphan_monitor)
|
||||
orphan_monitor_start()
|
||||
|
||||
_memory_observer = GdUnitMemoryObserver.new()
|
||||
_report_collector = GdUnitTestReportCollector.new()
|
||||
if parent_context != null:
|
||||
@@ -61,6 +64,8 @@ func _init(name: StringName, parent_context: GdUnitExecutionContext = null) -> v
|
||||
|
||||
|
||||
func dispose() -> void:
|
||||
if test_suite != null:
|
||||
test_suite.free()
|
||||
_timer = null
|
||||
_orphan_monitor = null
|
||||
_report_collector = null
|
||||
@@ -77,6 +82,11 @@ func dispose_sub_contexts() -> void:
|
||||
_sub_context.clear()
|
||||
|
||||
|
||||
func terminate() -> void:
|
||||
if test_case:
|
||||
test_case.do_terminate()
|
||||
|
||||
|
||||
static func of(pe: GdUnitExecutionContext) -> GdUnitExecutionContext:
|
||||
var context := GdUnitExecutionContext.new(pe._test_case_name, pe)
|
||||
context._test_case_name = pe._test_case_name
|
||||
@@ -84,16 +94,9 @@ static func of(pe: GdUnitExecutionContext) -> GdUnitExecutionContext:
|
||||
return context
|
||||
|
||||
|
||||
static func of_test_suite(p_test_suite: GdUnitTestSuite) -> GdUnitExecutionContext:
|
||||
assert(p_test_suite, "test_suite is null")
|
||||
var context := GdUnitExecutionContext.new(p_test_suite.get_name())
|
||||
context.test_suite = p_test_suite
|
||||
return context
|
||||
|
||||
|
||||
static func of_test_case(pe: GdUnitExecutionContext, p_test_case: _TestCase) -> GdUnitExecutionContext:
|
||||
assert(p_test_case, "test_case is null")
|
||||
var context := GdUnitExecutionContext.new(p_test_case.get_name(), pe)
|
||||
var context := GdUnitExecutionContext.new(p_test_case.test_name(), pe)
|
||||
context.test_case = p_test_case
|
||||
return context
|
||||
|
||||
@@ -124,7 +127,7 @@ func error_monitor_start() -> void:
|
||||
|
||||
|
||||
func error_monitor_stop() -> void:
|
||||
await error_monitor.scan()
|
||||
error_monitor.stop()
|
||||
for error_report in error_monitor.to_reports():
|
||||
if error_report.is_error():
|
||||
_report_collector.push_back(error_report)
|
||||
@@ -134,6 +137,10 @@ func orphan_monitor_start() -> void:
|
||||
_orphan_monitor.start()
|
||||
|
||||
|
||||
func orphan_monitor_collect() -> void:
|
||||
_orphan_monitor.collect()
|
||||
|
||||
|
||||
func orphan_monitor_stop() -> void:
|
||||
_orphan_monitor.stop()
|
||||
|
||||
@@ -165,8 +172,8 @@ func calculate_statistics(reports_: Array[GdUnitReport]) -> Dictionary:
|
||||
var error_count := GdUnitTestReportCollector.count_errors(reports_)
|
||||
var warn_count := GdUnitTestReportCollector.count_warnings(reports_)
|
||||
var skip_count := GdUnitTestReportCollector.count_skipped(reports_)
|
||||
var orphan_count := GdUnitTestReportCollector.count_orphans(reports_)
|
||||
var is_failed := !is_success()
|
||||
var orphan_count := _count_orphans()
|
||||
var elapsed_time := _timer.elapsed_since_ms()
|
||||
var retries := 1 if _parent_context == null else _sub_context.size()
|
||||
# Mark as flaky if it is successful, but errors were counted
|
||||
@@ -213,22 +220,6 @@ func is_interupted() -> bool:
|
||||
return false if test_case == null else test_case.is_interupted()
|
||||
|
||||
|
||||
func _count_orphans() -> int:
|
||||
if _orphans != -1:
|
||||
return _orphans
|
||||
|
||||
var orphans := 0
|
||||
for c in _sub_context:
|
||||
if _orphan_monitor.orphan_nodes() != c._orphan_monitor.orphan_nodes():
|
||||
orphans += c._count_orphans()
|
||||
|
||||
_orphans = _orphan_monitor.orphan_nodes()
|
||||
if _orphan_monitor.orphan_nodes() != orphans:
|
||||
_orphans -= orphans
|
||||
|
||||
return _orphans
|
||||
|
||||
|
||||
func sum(accum: int, number: int) -> int:
|
||||
return accum + number
|
||||
|
||||
@@ -251,19 +242,33 @@ func gc(gc_orphan_check: GC_ORPHANS_CHECK = GC_ORPHANS_CHECK.NONE) -> void:
|
||||
await _memory_observer.gc()
|
||||
orphan_monitor_stop()
|
||||
|
||||
var orphans := _count_orphans()
|
||||
match(gc_orphan_check):
|
||||
GC_ORPHANS_CHECK.SUITE_HOOK_AFTER:
|
||||
if orphans > 0:
|
||||
reports().push_front(GdUnitReport.new() \
|
||||
.create(GdUnitReport.WARN, 1, GdAssertMessages.orphan_detected_on_suite_setup(orphans)))
|
||||
_orphan_monitor.collect()
|
||||
var orphan_infos := _orphan_monitor.detected_orphans()
|
||||
if orphan_infos.is_empty():
|
||||
return
|
||||
reports().push_front(GdUnitReport.new() \
|
||||
.create(GdUnitReport.ORPHAN, 1, GdAssertMessages.orphan_detected_on_suite_setup(orphan_infos))
|
||||
.with_current_value(orphan_infos.size()))
|
||||
|
||||
GC_ORPHANS_CHECK.TEST_HOOK_AFTER:
|
||||
if orphans > 0:
|
||||
_orphan_monitor.collect()
|
||||
var orphans := _orphan_monitor.detected_orphans()
|
||||
if not orphans.is_empty():
|
||||
reports().push_front(GdUnitReport.new()\
|
||||
.create(GdUnitReport.WARN, 1, GdAssertMessages.orphan_detected_on_test_setup(orphans)))
|
||||
.create(GdUnitReport.ORPHAN, 1, GdAssertMessages.orphan_detected_on_test_setup(orphans))
|
||||
.with_current_value(orphans.size()))
|
||||
|
||||
GC_ORPHANS_CHECK.TEST_CASE:
|
||||
if orphans > 0:
|
||||
var orphans := _orphan_monitor.detected_orphans()
|
||||
if orphans.is_empty():
|
||||
var orphans_count := _orphan_monitor.orphans_count()
|
||||
if orphans_count > 0:
|
||||
reports().push_front(GdUnitReport.new() \
|
||||
.create(GdUnitReport.ORPHAN, test_case.line_number(), GdAssertMessages.orphan_warning(orphans_count))
|
||||
.with_current_value(orphans_count))
|
||||
else:
|
||||
reports().push_front(GdUnitReport.new()\
|
||||
.create(GdUnitReport.WARN, test_case.line_number(), GdAssertMessages.orphan_detected_on_test(orphans)))
|
||||
.create(GdUnitReport.ORPHAN, test_case.line_number(), GdAssertMessages.orphan_detected_on_test(orphans))
|
||||
.with_current_value(orphans.size()))
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dm5otinunwsc1
|
||||
uid://cbumcrr7mlbl2
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ibpnqu61f7yw
|
||||
uid://bgatcioxigsa3
|
||||
|
||||
@@ -22,6 +22,10 @@ static func __filter_is_skipped(report :GdUnitReport) -> bool:
|
||||
return report.is_skipped()
|
||||
|
||||
|
||||
static func __filter_is_orphan(report: GdUnitReport) -> bool:
|
||||
return report.is_orphan()
|
||||
|
||||
|
||||
static func count_failures(reports_: Array[GdUnitReport]) -> int:
|
||||
return reports_.filter(__filter_is_failure).size()
|
||||
|
||||
@@ -38,6 +42,17 @@ static func count_skipped(reports_: Array[GdUnitReport]) -> int:
|
||||
return reports_.filter(__filter_is_skipped).size()
|
||||
|
||||
|
||||
static func count_orphans(reports_: Array[GdUnitReport]) -> int:
|
||||
var orphan_reports := reports_.filter(__filter_is_orphan)
|
||||
if orphan_reports.is_empty():
|
||||
return 0
|
||||
## Collect orphan count from the reports
|
||||
var orphans := 0
|
||||
for report: GdUnitReport in orphan_reports:
|
||||
orphans += report._current_value
|
||||
return orphans
|
||||
|
||||
|
||||
func has_failures() -> bool:
|
||||
return _reports.any(__filter_is_failure)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cl13ejhh26vv7
|
||||
uid://ds05ko0pefbe
|
||||
|
||||
@@ -7,37 +7,45 @@ class_name GdUnitTestSuiteExecutor
|
||||
var _assertions := GdUnitAssertions.new()
|
||||
var _executeStage := GdUnitTestSuiteExecutionStage.new()
|
||||
var _debug_mode : bool
|
||||
var _terminated := false
|
||||
|
||||
func _init(debug_mode :bool = false) -> void:
|
||||
func _init(debug_mode: bool = false) -> void:
|
||||
_executeStage.set_debug_mode(debug_mode)
|
||||
_debug_mode = debug_mode
|
||||
GdUnitSignals.instance().gdunit_test_session_terminate.connect(_on_testsession_terminated)
|
||||
|
||||
|
||||
func execute(test_suite :GdUnitTestSuite) -> void:
|
||||
var orphan_detection_enabled := GdUnitSettings.is_verbose_orphans()
|
||||
if not orphan_detection_enabled:
|
||||
prints("!!! Reporting orphan nodes is disabled. Please check GdUnit settings.")
|
||||
|
||||
(Engine.get_main_loop() as SceneTree).root.call_deferred("add_child", test_suite)
|
||||
await (Engine.get_main_loop() as SceneTree).process_frame
|
||||
await _executeStage.execute(GdUnitExecutionContext.of_test_suite(test_suite))
|
||||
func _on_testsession_terminated() -> void:
|
||||
_terminated = true
|
||||
GdUnitThreadManager.interrupt()
|
||||
|
||||
|
||||
func run_and_wait(tests: Array[GdUnitTestCase]) -> void:
|
||||
if !_debug_mode:
|
||||
GdUnitSignals.instance().gdunit_event.emit(GdUnitInit.new())
|
||||
|
||||
var orphan_detection_enabled := GdUnitSettings.is_verbose_orphans()
|
||||
if not orphan_detection_enabled:
|
||||
prints("!!! Reporting orphan nodes is disabled. Please check GdUnit settings.")
|
||||
|
||||
# first we group all tests by resource path
|
||||
var grouped_by_suites := GdArrayTools.group_by(tests, func(test: GdUnitTestCase) -> String:
|
||||
return test.suite_resource_path
|
||||
)
|
||||
var scanner := GdUnitTestSuiteScanner.new()
|
||||
for suite_path: String in grouped_by_suites.keys():
|
||||
if _terminated:
|
||||
break
|
||||
@warning_ignore("unsafe_call_argument")
|
||||
var suite_tests: Array[GdUnitTestCase] = Array(grouped_by_suites[suite_path], TYPE_OBJECT, "RefCounted", GdUnitTestCase)
|
||||
var script := GdUnitTestSuiteScanner.load_with_disabled_warnings(suite_path)
|
||||
if script.get_class() == "GDScript":
|
||||
var context := GdUnitExecutionContext.new(suite_path)
|
||||
var test_suite := scanner.load_suite(script as GDScript, suite_tests)
|
||||
await execute(test_suite)
|
||||
context.test_suite = test_suite
|
||||
(Engine.get_main_loop() as SceneTree).root.add_child(test_suite)
|
||||
await _executeStage.execute(context)
|
||||
context.dispose()
|
||||
else:
|
||||
await GdUnit4CSharpApiLoader.execute(suite_tests)
|
||||
if !_debug_mode:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://hl8otc6pepsh
|
||||
uid://b45ihvou3jfe2
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ddknkun7aw51d
|
||||
uid://nhg6vtb5bgn0
|
||||
|
||||
@@ -10,10 +10,11 @@ func _init(call_stage := true) -> void:
|
||||
_call_stage = call_stage
|
||||
|
||||
|
||||
func _execute(context :GdUnitExecutionContext) -> void:
|
||||
func _execute(context: GdUnitExecutionContext) -> void:
|
||||
var test_suite := context.test_suite
|
||||
|
||||
if _call_stage:
|
||||
@warning_ignore("redundant_await")
|
||||
await test_suite.before_test()
|
||||
|
||||
context.error_monitor_start()
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://c8gq3sb8q6xih
|
||||
uid://dyr1fyhd3oi26
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://brfrhige0dbmm
|
||||
uid://kkmwmd1wsfgp
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://vs73mmj8rsbs
|
||||
uid://csqrlovyndxqm
|
||||
|
||||
@@ -4,7 +4,7 @@ class_name GdUnitTestSuiteBeforeStage
|
||||
extends IGdUnitExecutionStage
|
||||
|
||||
|
||||
func _execute(context :GdUnitExecutionContext) -> void:
|
||||
func _execute(context: GdUnitExecutionContext) -> void:
|
||||
var test_suite := context.test_suite
|
||||
|
||||
fire_event(GdUnitEvent.new()\
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ce78xguk84kwb
|
||||
uid://bs0orggd2ej7y
|
||||
|
||||
@@ -28,9 +28,10 @@ func _execute(context :GdUnitExecutionContext) -> void:
|
||||
if not is_instance_valid(test_case):
|
||||
continue
|
||||
context.test_suite.set_active_test_case(test_case.test_name())
|
||||
await _stage_test.execute(GdUnitExecutionContext.of_test_case(context, test_case))
|
||||
var test_case_context := GdUnitExecutionContext.of_test_case(context, test_case)
|
||||
await _stage_test.execute(test_case_context)
|
||||
# stop on first error or if fail fast is enabled
|
||||
if _fail_fast and not context.is_success():
|
||||
if test_case.is_terminated() or (_fail_fast and not test_case_context.is_success()):
|
||||
break
|
||||
if test_case.is_interupted():
|
||||
# it needs to go this hard way to kill the outstanding awaits of a test case when the test timed out
|
||||
@@ -39,9 +40,8 @@ func _execute(context :GdUnitExecutionContext) -> void:
|
||||
context.test_suite = await clone_test_suite(context.test_suite)
|
||||
await _stage_after.execute(context)
|
||||
GdUnitMemoryObserver.unguard_instance(context.test_suite.__awaiter)
|
||||
|
||||
await (Engine.get_main_loop() as SceneTree).process_frame
|
||||
context.test_suite.free()
|
||||
context.dispose()
|
||||
|
||||
|
||||
# clones a test suite and moves the test cases to new instance
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bfbyfr8ocwivm
|
||||
uid://rteudd6jx3n1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user