summaryrefslogtreecommitdiff
path: root/addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd
diff options
context:
space:
mode:
authorradiohotline <radoihotline@disroot.rg>2026-08-25 16:33:56 +0300
committerradiohotline <radoihotline@disroot.rg>2026-08-25 16:33:56 +0300
commita89e744ed0e8c759caf041a580112365bbfe4303 (patch)
treedd61e320904176995727e86a857d00c90d4933ba /addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd
parent6d53d8cac78250dc888aa49d5f9d4175c6652feb (diff)
escoria updateHEADmain
Diffstat (limited to 'addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd')
-rw-r--r--addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd191
1 files changed, 191 insertions, 0 deletions
diff --git a/addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd b/addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd
new file mode 100644
index 0000000..5a9bdcb
--- /dev/null
+++ b/addons/gdUnit4/src/core/hooks/GdUnitTestSessionHookService.gd
@@ -0,0 +1,191 @@
+class_name GdUnitTestSessionHookService
+extends Object
+
+
+var enigne_hooks: Array[GdUnitTestSessionHook] = []:
+ get:
+ return enigne_hooks
+ set(value):
+ enigne_hooks.append(value)
+
+
+var _save_settings: bool = false
+
+
+static func instance() -> GdUnitTestSessionHookService:
+ return GdUnitSingleton.instance("GdUnitTestSessionHookService", func()->GdUnitTestSessionHookService:
+ GdUnitSignals.instance().gdunit_message.emit("Installing GdUnit4 session system hooks.")
+ var service := GdUnitTestSessionHookService.new()
+ # Register default system hooks here
+ service._save_settings = false
+ service.register(GdUnitHtmlReporterTestSessionHook.new())
+ service.register(GdUnitXMLReporterTestSessionHook.new())
+ service.load_hook_settings()
+ service._save_settings = true
+ return service
+ )
+
+
+static func contains_hook(current: GdUnitTestSessionHook, other: GdUnitTestSessionHook) -> bool:
+ return current.get_script().resource_path == other.get_script().resource_path
+
+
+func find_custom(hook: GdUnitTestSessionHook) -> int:
+ for index in enigne_hooks.size():
+ if contains_hook.call(enigne_hooks[index], hook):
+ return index
+ return -1
+
+
+func load_hook(hook_resourc_path: String) -> GdUnitResult:
+ if !FileAccess.file_exists(hook_resourc_path):
+ return GdUnitResult.error("The hook '%s' not exists." % hook_resourc_path)
+ var script: GDScript = load(hook_resourc_path)
+ if script.get_base_script() != GdUnitTestSessionHook:
+ return GdUnitResult.error("The hook '%s' must inhertit from 'GdUnitTestSessionHook'." % hook_resourc_path)
+
+ return GdUnitResult.success(script.new())
+
+
+func enable_hook(hook: GdUnitTestSessionHook, enabled: bool) -> void:
+ _enable_hook(hook, enabled)
+ GdUnitSignals.instance().gdunit_message.emit("Session hook '{name}' {enabled}.".format({
+ "name": hook.name,
+ "enabled": "enabled" if enabled else "disabled"})
+ )
+ save_hock_setttings()
+
+
+func register(hook: GdUnitTestSessionHook, enabled: bool = true) -> GdUnitResult:
+ if find_custom(hook) != -1:
+ return GdUnitResult.error("A hook instance of '%s' is already registered." % hook.get_script().resource_path)
+
+ _enable_hook(hook, enabled)
+ enigne_hooks.append(hook)
+ save_hock_setttings()
+ GdUnitSignals.instance().gdunit_message.emit("Session hook '%s' installed." % hook.name)
+
+ return GdUnitResult.success()
+
+
+func unregister(hook: GdUnitTestSessionHook) -> GdUnitResult:
+ var hook_index := find_custom(hook)
+ if hook_index == -1:
+ return GdUnitResult.error("The hook instance of '%s' is NOT registered." % hook.get_script().resource_path)
+
+ enigne_hooks.remove_at(hook_index)
+ save_hock_setttings()
+ return GdUnitResult.success()
+
+
+func move_before(hook: GdUnitTestSessionHook, before: GdUnitTestSessionHook) -> void:
+ var before_index := find_custom(before)
+ var hook_index := find_custom(hook)
+
+ # Verify the hook to move is behind the hook to be moved
+ if before_index >= hook_index:
+ return
+
+ enigne_hooks.remove_at(hook_index)
+ enigne_hooks.insert(before_index, hook)
+ save_hock_setttings()
+
+
+func move_after(hook: GdUnitTestSessionHook, after: GdUnitTestSessionHook) -> void:
+ var after_index := find_custom(after)
+ var hook_index := find_custom(hook)
+
+ # Verify the hook to move is before the hook to be moved
+ if after_index <= hook_index:
+ return
+
+ enigne_hooks.remove_at(hook_index)
+ enigne_hooks.insert(after_index, hook)
+ save_hock_setttings()
+
+
+func execute_startup(session: GdUnitTestSession) -> GdUnitResult:
+ return await execute("startup", session)
+
+
+func execute_shutdown(session: GdUnitTestSession) -> GdUnitResult:
+ return await execute("shutdown", session, true)
+
+
+func execute(hook_func: String, session: GdUnitTestSession, reverse := false) -> GdUnitResult:
+ var failed_hook_calls: Array[GdUnitResult] = []
+
+ for hook_index in enigne_hooks.size():
+ var index := enigne_hooks.size()-hook_index-1 if reverse else hook_index
+ var hook: = enigne_hooks[index]
+ if not is_enabled(hook):
+ continue
+ if OS.is_stdout_verbose():
+ GdUnitSignals.instance().gdunit_message.emit("Session hook '%s' > %s()" % [hook.name, hook_func])
+ var result: GdUnitResult = await hook.call(hook_func, session)
+ if result == null:
+ failed_hook_calls.push_back(GdUnitResult.error("Result is null! Check '%s'" % hook.get_script().resource_path))
+ elif result.is_error():
+ failed_hook_calls.push_back(result)
+
+ if failed_hook_calls.is_empty():
+ return GdUnitResult.success()
+
+ var errors := failed_hook_calls.map(func(result: GdUnitResult) -> String:
+ return "Hook call '%s' failed with error: '%s'" % [hook_func, result.error_message()]
+ )
+ return GdUnitResult.error( "\n".join(errors))
+
+
+func save_hock_setttings() -> void:
+ if not _save_settings:
+ return
+
+ var hooks_to_save: Dictionary[String, bool] = {}
+ for hook in enigne_hooks:
+ var enabled: bool = hook.get_meta("enabled")
+ hooks_to_save[hook.get_script().resource_path] = enabled
+
+ GdUnitSettings.set_session_hooks(hooks_to_save)
+
+
+func load_hook_settings() -> void:
+ var hooks_resource_paths := GdUnitSettings.get_session_hooks()
+ if hooks_resource_paths.is_empty():
+ return
+
+ for hock_path: String in hooks_resource_paths.keys():
+ var enabled := hooks_resource_paths[hock_path]
+
+ # Do not reinstall already installed hooks
+ var existing_hook: GdUnitTestSessionHook = enigne_hooks.filter(func(element: GdUnitTestSessionHook) -> bool:
+ return element.get_script().resource_path == hock_path
+ ).front()
+ # Applay enabled settings
+ if existing_hook != null:
+ _enable_hook(existing_hook, enabled)
+ continue
+
+ # Load additional hooks
+ var result := load_hook(hock_path)
+ if result.is_error():
+ push_error(result.error_message())
+ continue
+
+ GdUnitSignals.instance().gdunit_message.emit("Installing GdUnit4 session hooks.")
+ var hook: GdUnitTestSessionHook = result.value()
+
+ result = register(hook, enabled)
+ if result.is_error():
+ push_error(result.error_message())
+ continue
+
+
+static func is_enabled(hook: GdUnitTestSessionHook) -> bool:
+ if hook.has_meta("enabled"):
+ return hook.get_meta("enabled")
+ return true
+
+
+func _enable_hook(hook: GdUnitTestSessionHook, enabled: bool) -> void:
+ hook.set_meta("enabled", enabled)