chore(client): add gdUnit4 test framework addon
Vendor gdUnit4 for Godot 4 client testing (D-030). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
class_name GdUnitContextMenuItem
|
||||
|
||||
|
||||
var command_id: String:
|
||||
set(value):
|
||||
command_id = value
|
||||
get:
|
||||
return command_id
|
||||
|
||||
var name: StringName:
|
||||
set(value):
|
||||
name = value
|
||||
get:
|
||||
return name
|
||||
|
||||
var visible: Callable:
|
||||
set(value):
|
||||
visible = value
|
||||
get:
|
||||
return visible
|
||||
|
||||
var icon: Texture2D:
|
||||
get:
|
||||
return GdUnitCommandHandler.instance().command_icon(command_id)
|
||||
|
||||
|
||||
func _init(p_command_id: String, p_name: StringName, p_is_visible: Callable) -> void:
|
||||
assert(p_command_id != null and not p_command_id.is_empty(), "(%s) missing command id " % p_command_id)
|
||||
assert(p_is_visible != null, "(%s) missing parameter 'GdUnitCommand'" % p_name)
|
||||
|
||||
self.command_id = p_command_id
|
||||
self.name = p_name
|
||||
self.visible = p_is_visible
|
||||
|
||||
|
||||
func shortcut() -> Shortcut:
|
||||
return GdUnitCommandHandler.instance().command_shortcut(command_id)
|
||||
|
||||
|
||||
func is_visible(...args: Array) -> bool:
|
||||
return visible.callv(args)
|
||||
|
||||
|
||||
func execute(...args: Array) -> void:
|
||||
GdUnitCommandHandler.instance().command_execute(command_id, args)
|
||||
@@ -0,0 +1 @@
|
||||
uid://c4i0p5jpownix
|
||||
@@ -0,0 +1,37 @@
|
||||
@tool
|
||||
extends EditorContextMenuPlugin
|
||||
|
||||
var _context_menus: Array[GdUnitContextMenuItem] = []
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var is_test_suite := func is_visible(script: Script, is_ts: bool) -> bool:
|
||||
if script == null:
|
||||
return false
|
||||
return GdUnitTestSuiteScanner.is_test_suite(script) == is_ts
|
||||
_context_menus.append(GdUnitContextMenuItem.new(
|
||||
GdUnitCommandFileSystemRunTests.ID,
|
||||
"Run Testsuites",
|
||||
is_test_suite.bind(true)
|
||||
))
|
||||
_context_menus.append(GdUnitContextMenuItem.new(
|
||||
GdUnitCommandFileSystemDebugTests.ID,
|
||||
"Debug Testsuites",
|
||||
is_test_suite.bind(true)
|
||||
))
|
||||
|
||||
# setup shortcuts
|
||||
for menu_item in _context_menus:
|
||||
if menu_item.shortcut():
|
||||
var cb := func call(...files: Array) -> void:
|
||||
var paths: Array = files[0]
|
||||
menu_item.execute.callv(paths)
|
||||
add_menu_shortcut(menu_item.shortcut(), cb)
|
||||
|
||||
|
||||
func _popup_menu(paths: PackedStringArray) -> void:
|
||||
for menu_item in _context_menus:
|
||||
if menu_item.shortcut():
|
||||
add_context_menu_item_from_shortcut(menu_item.name, menu_item.shortcut(), menu_item.icon)
|
||||
else:
|
||||
add_context_menu_item(menu_item.name, menu_item.execute.bindv(paths).unbind(1), menu_item.icon)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ld10hjfqv3c3
|
||||
@@ -0,0 +1,63 @@
|
||||
@tool
|
||||
class_name GdUnitInspectorContextMenu
|
||||
extends PopupMenu
|
||||
|
||||
|
||||
const CONTEXT_MENU_RUN_ID = 0
|
||||
const CONTEXT_MENU_DEBUG_ID = 1
|
||||
const CONTEXT_MENU_RERUN_UNTIL_ID = 2
|
||||
# id 3 is the seperator
|
||||
const CONTEXT_MENU_COLLAPSE_ALL = 4
|
||||
const CONTEXT_MENU_EXPAND_ALL = 5
|
||||
|
||||
|
||||
var command_handler: GdUnitCommandHandler
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not Engine.is_editor_hint():
|
||||
return
|
||||
command_handler = GdUnitCommandHandler.instance()
|
||||
_setup_item(CONTEXT_MENU_RUN_ID, "Run Tests", GdUnitCommandInspectorRunTests.ID)
|
||||
_setup_item(CONTEXT_MENU_DEBUG_ID, "Debug Tests", GdUnitCommandInspectorDebugTests.ID)
|
||||
_setup_item(CONTEXT_MENU_RERUN_UNTIL_ID, "Run Tests Until Fail", GdUnitCommandInspectorRerunTestsUntilFailure.ID)
|
||||
_setup_item(CONTEXT_MENU_EXPAND_ALL, "Expand All", GdUnitCommandInspectorTreeExpand.ID)
|
||||
_setup_item(CONTEXT_MENU_COLLAPSE_ALL, "Collapse All", GdUnitCommandInspectorTreeCollapse.ID)
|
||||
|
||||
|
||||
func _setup_item(item_id: int, item_name: String, command_id: String) -> void:
|
||||
set_item_text(item_id, item_name)
|
||||
set_item_icon(item_id, command_handler.command_icon(command_id))
|
||||
set_item_shortcut(item_id, command_handler.command_shortcut(command_id))
|
||||
|
||||
|
||||
func disable_items() -> void:
|
||||
set_item_disabled(CONTEXT_MENU_RUN_ID, true)
|
||||
set_item_disabled(CONTEXT_MENU_DEBUG_ID, true)
|
||||
set_item_disabled(CONTEXT_MENU_RERUN_UNTIL_ID, true)
|
||||
|
||||
|
||||
func enable_items() -> void:
|
||||
set_item_disabled(CONTEXT_MENU_RUN_ID, false)
|
||||
set_item_disabled(CONTEXT_MENU_DEBUG_ID, false)
|
||||
set_item_disabled(CONTEXT_MENU_RERUN_UNTIL_ID, false)
|
||||
|
||||
|
||||
func _on_tree_item_mouse_selected(mouse_position: Vector2, mouse_button_index: int, source: Tree) -> void:
|
||||
if mouse_button_index == MOUSE_BUTTON_RIGHT:
|
||||
position = source.get_screen_position() + mouse_position
|
||||
popup()
|
||||
|
||||
|
||||
func _on_index_pressed(index: int) -> void:
|
||||
match index:
|
||||
CONTEXT_MENU_RUN_ID:
|
||||
command_handler.command_execute(GdUnitCommandInspectorRunTests.ID)
|
||||
CONTEXT_MENU_DEBUG_ID:
|
||||
command_handler.command_execute(GdUnitCommandInspectorDebugTests.ID)
|
||||
CONTEXT_MENU_RERUN_UNTIL_ID:
|
||||
command_handler.command_execute(GdUnitCommandInspectorRerunTestsUntilFailure.ID)
|
||||
CONTEXT_MENU_EXPAND_ALL:
|
||||
command_handler.command_execute(GdUnitCommandInspectorTreeExpand.ID)
|
||||
CONTEXT_MENU_COLLAPSE_ALL:
|
||||
command_handler.command_execute(GdUnitCommandInspectorTreeCollapse.ID)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bxy2decxu8axg
|
||||
@@ -0,0 +1,70 @@
|
||||
[gd_scene format=3 uid="uid://bjcc71p2h1trr"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gdUnit4/src/ui/menu/GdUnitInspectorContextMenu.gd" id="1_0x0vc"]
|
||||
|
||||
[sub_resource type="DPITexture" id="DPITexture_miuuy"]
|
||||
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path fill=\"#e0e0e0\" d=\"M4 12a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 4 4z\"/></svg>
|
||||
"
|
||||
saturation = 2.0
|
||||
color_map = {
|
||||
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
|
||||
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
|
||||
Color(1, 0.8666667, 0.39607844, 1): Color(0.83, 0.78, 0.62, 1)
|
||||
}
|
||||
|
||||
[sub_resource type="DPITexture" id="DPITexture_ern2r"]
|
||||
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path fill=\"#e0e0e0\" d=\"M3 3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm4.975 0A1 1 0 0 0 7 3.998v8a1 1 0 0 0 1.625.781l5-4a1 1 0 0 0 0-1.56l-5-4A1 1 0 0 0 7.975 3z\"/></svg>
|
||||
"
|
||||
saturation = 2.0
|
||||
color_map = {
|
||||
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
|
||||
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
|
||||
Color(1, 0.8666667, 0.39607844, 1): Color(0.83, 0.78, 0.62, 1)
|
||||
}
|
||||
|
||||
[sub_resource type="DPITexture" id="DPITexture_qdci2"]
|
||||
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path fill=\"#e0e0e0\" d=\"m8 9.669-3.536 2.583H7v2.537h2v-2.537h2.536zm0-3.314L4.464 3.772H7V1.235h2v2.537h2.536zm-7.296.73h14.591v1.831H.704z\"/></svg>
|
||||
"
|
||||
saturation = 2.0
|
||||
color_map = {
|
||||
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
|
||||
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
|
||||
Color(1, 0.8666667, 0.39607844, 1): Color(0.83, 0.78, 0.62, 1)
|
||||
}
|
||||
|
||||
[sub_resource type="DPITexture" id="DPITexture_hed0i"]
|
||||
_source = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"><path fill=\"#e0e0e0\" d=\"m8 16-3.5-2.5H7V11h2v2.5h2.5zM8 0 4.5 2.5H7V5h2V2.5h2.5zM1 7h14v2H1z\"/></svg>
|
||||
"
|
||||
saturation = 2.0
|
||||
color_map = {
|
||||
Color(1, 0.37254903, 0.37254903, 1): Color(1, 0.47, 0.42, 1),
|
||||
Color(0.37254903, 1, 0.5921569, 1): Color(0.45, 0.95, 0.5, 1),
|
||||
Color(1, 0.8666667, 0.39607844, 1): Color(0.83, 0.78, 0.62, 1)
|
||||
}
|
||||
|
||||
[node name="contextMenu" type="PopupMenu" unique_id=1824556050]
|
||||
auto_translate_mode = 2
|
||||
oversampling_override = 1.0
|
||||
size = Vector2i(241, 170)
|
||||
visible = true
|
||||
item_count = 6
|
||||
item_0/text = "Run Tests"
|
||||
item_0/icon = SubResource("DPITexture_miuuy")
|
||||
item_0/id = 0
|
||||
item_1/text = "Debug Tests"
|
||||
item_1/icon = SubResource("DPITexture_ern2r")
|
||||
item_1/id = 1
|
||||
item_2/text = "Run Tests Until Fail"
|
||||
item_2/icon = SubResource("DPITexture_miuuy")
|
||||
item_2/id = 2
|
||||
item_3/id = 3
|
||||
item_3/separator = true
|
||||
item_4/text = "Collapse All"
|
||||
item_4/icon = SubResource("DPITexture_qdci2")
|
||||
item_4/id = 4
|
||||
item_5/text = "Expand All"
|
||||
item_5/icon = SubResource("DPITexture_hed0i")
|
||||
item_5/id = 5
|
||||
script = ExtResource("1_0x0vc")
|
||||
|
||||
[connection signal="index_pressed" from="." to="." method="_on_index_pressed"]
|
||||
@@ -0,0 +1,41 @@
|
||||
@tool
|
||||
extends EditorContextMenuPlugin
|
||||
|
||||
|
||||
var _context_menus: Array[GdUnitContextMenuItem] = []
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var is_test_suite := func is_visible(script: Script, is_ts: bool) -> bool:
|
||||
return GdUnitTestSuiteScanner.is_test_suite(script) == is_ts
|
||||
_context_menus.append(GdUnitContextMenuItem.new(
|
||||
GdUnitCommandScriptEditorRunTests.ID,
|
||||
"Run Tests",
|
||||
is_test_suite.bind(true)
|
||||
))
|
||||
_context_menus.append(GdUnitContextMenuItem.new(
|
||||
GdUnitCommandScriptEditorDebugTests.ID,
|
||||
"Debug Tests",
|
||||
is_test_suite.bind(true)
|
||||
))
|
||||
_context_menus.append(GdUnitContextMenuItem.new(
|
||||
GdUnitCommandScriptEditorCreateTest.ID,
|
||||
"Create Test",
|
||||
is_test_suite.bind(false)
|
||||
))
|
||||
|
||||
# setup shortcuts
|
||||
for menu_item in _context_menus:
|
||||
if menu_item.shortcut():
|
||||
add_menu_shortcut(menu_item.shortcut(), menu_item.execute.unbind(1))
|
||||
|
||||
|
||||
func _popup_menu(_paths: PackedStringArray) -> void:
|
||||
var current_script := EditorInterface.get_script_editor().get_current_script()
|
||||
|
||||
for menu_item in _context_menus:
|
||||
if menu_item.is_visible(current_script):
|
||||
if menu_item.shortcut():
|
||||
add_context_menu_item_from_shortcut(menu_item.name, menu_item.shortcut())
|
||||
else:
|
||||
add_context_menu_item(menu_item.name, menu_item.execute.unbind(1))
|
||||
@@ -0,0 +1 @@
|
||||
uid://6d0lvpnuj4wn
|
||||
Reference in New Issue
Block a user