Godot 4 automatic changes

This commit is contained in:
Daniel Inkpen 2022-11-09 20:57:46 +00:00
parent 8b5caafbc7
commit cdbf3f2adc
75 changed files with 1034 additions and 952 deletions

View file

@ -1,11 +1,11 @@
tool
@tool
extends "../../terminal.gd"
signal exited(exit_code, signum)
var editor_settings: EditorSettings
onready var pty = $PTY
@onready var pty = $PTY
# Sets terminal colors according to a dictionary that maps terminal color names
@ -25,7 +25,7 @@ func _ready():
# Get colors from TextEdit theme. Created using the default (Adaptive) theme
# for reference, but will probably cause strange results if using another theme
# better to use a dedicated terminal theme, rather than relying on this.
# better to use a dedicated terminal theme, rather than relying checked this.
_set_terminal_colors(
{
"black": "caret_background_color",

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
control = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
control = true

View file

@ -12,48 +12,48 @@ enum CWDType {
### Shortcuts ###
export(ShortCut) var new_terminal_shortcut = preload("./default_new_terminal_shortcut.tres")
export(ShortCut) var kill_terminal_shortcut = preload("./default_kill_terminal_shortcut.tres")
export(ShortCut) var copy_shortcut = preload("./default_copy_shortcut.tres")
export(ShortCut) var paste_shortcut = preload("./default_paste_shortcut.tres")
@export var new_terminal_shortcut: Shortcut = preload("./default_new_terminal_shortcut.tres")
@export var kill_terminal_shortcut: Shortcut = preload("./default_kill_terminal_shortcut.tres")
@export var copy_shortcut: Shortcut = preload("./default_copy_shortcut.tres")
@export var paste_shortcut: Shortcut = preload("./default_paste_shortcut.tres")
export(ShortCut) var next_tab_shortcut = preload("./default_tab_right_shortcut.tres")
export(ShortCut) var previous_tab_shortcut = preload("./default_tab_left_shortcut.tres")
@export var next_tab_shortcut: Shortcut = preload("./default_tab_right_shortcut.tres")
@export var previous_tab_shortcut: Shortcut = preload("./default_tab_left_shortcut.tres")
### Scroll settings ###
# The maximum amount of lines the terminal keeps in its buffer.
export var scrollback_buffer_lines := 1000
@export var scrollback_buffer_lines := 1000
# If true, mouse wheel up and down can be used to scroll the terminal.
export var mouse_wheel_scroll := true
@export var mouse_wheel_scroll := true
# Whether or not to display scroll bar.
export var show_scroll_bar := true
@export var show_scroll_bar := true
# Copy/paste settings.
export var copy_on_selection := false
@export var copy_on_selection := false
# Font settings.
export var font_size: int = 14
export var letter_spacing: int = 0
export var line_height: float = 1.2
export var ctrl_scroll_to_resize_font := true
@export var font_size: int = 14
@export var letter_spacing: int = 0
@export var line_height: float = 1.2
@export var ctrl_scroll_to_resize_font := true
# Bell settings.
export var visual_bell := true
export var audio_bell := true
export var bell_sound: AudioStream
@export var visual_bell := true
@export var audio_bell := true
@export var bell_sound: AudioStream
# Exec args.
export(FileType) var file_type := FileType.USE_SHELL_ENV
export var custom_file := "/bin/sh"
@export var file_type: FileType := FileType.USE_SHELL_ENV
@export var custom_file := "/bin/sh"
export(CWDType) var cwd_type := CWDType.USE_PROJECT_DIRECTORY
export var custom_cwd := ""
@export var cwd_type: CWDType := CWDType.USE_PROJECT_DIRECTORY
@export var custom_cwd := ""
export var args := PoolStringArray()
@export var args := PackedStringArray()
export var use_os_env := true
export var extra_env := {
@export var use_os_env := true
@export var extra_env := {
TERM = "xterm-256color",
COLORTERM = "truecolor",
}

View file

@ -4,7 +4,7 @@
# These snippets are copyright of their authors and released under the MIT license:
# - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License).
# - Copyright (c) 2014-2021 Godot Engine contributors (MIT License).
tool
@tool
extends Control
const EditorTerminal := preload("./editor_terminal.tscn")
@ -23,23 +23,23 @@ enum TerminalPopupMenuOptions {
}
# Has access to the EditorSettings singleton so it can dynamically generate the
# terminal color scheme based on editor theme settings.
# terminal color scheme based checked editor theme settings.
var editor_plugin: EditorPlugin
var editor_interface: EditorInterface
onready var editor_settings: EditorSettings = editor_interface.get_editor_settings()
onready var tabs: Tabs = $VBoxContainer/TabbarContainer/Tabs
onready var tabbar_container: HBoxContainer = $VBoxContainer/TabbarContainer
onready var add_button: ToolButton = $VBoxContainer/TabbarContainer/Tabs/AddButton
onready var tab_container: TabContainer = $VBoxContainer/TabContainer
onready var terminal_popup_menu: PopupMenu = $VBoxContainer/TerminalPopupMenu
@onready var editor_settings: EditorSettings = editor_interface.get_editor_settings()
@onready var tabs: TabBar = $VBoxContainer/TabbarContainer/TabBar
@onready var tabbar_container: HBoxContainer = $VBoxContainer/TabbarContainer
@onready var add_button: Button = $VBoxContainer/TabbarContainer/TabBar/AddButton
@onready var tab_container: TabContainer = $VBoxContainer/TabContainer
@onready var terminal_popup_menu: PopupMenu = $VBoxContainer/TerminalPopupMenu
# Size label.
# Used to show the size of the terminal (rows/cols) and panel (pixels) when resized.
onready var size_label: Label = $SizeLabel
onready var size_label_timer: Timer = $SizeLabel/SizeLabelTimer
@onready var size_label: Label = $SizeLabel
@onready var size_label_timer: Timer = $SizeLabel/SizeLabelTimer
onready var ready := true
@onready var ready := true
var _theme := Theme.new()
var _settings: TerminalSettings
@ -47,7 +47,7 @@ var _tab_container_min_size
func _ready():
tab_container.add_stylebox_override("panel", get_stylebox("background", "EditorStyles"))
tab_container.add_theme_stylebox_override("panel", get_stylebox("background", "EditorStyles"))
_update_settings()
@ -76,10 +76,10 @@ func _update_settings() -> void:
if editor_interface.has_method("get_editor_scale"):
editor_scale = editor_interface.get_editor_scale()
rect_min_size = Vector2(0, tabbar_container.rect_size.y + 182) * editor_scale
rect_size.y = 415
minimum_size = Vector2(0, tabbar_container.size.y + 182) * editor_scale
size.y = 415
tabs.tab_close_display_policy = Tabs.CLOSE_BUTTON_SHOW_ALWAYS
tabs.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ALWAYS
# Update shortcuts.
if _settings.new_terminal_shortcut:
@ -104,13 +104,13 @@ func _update_settings() -> void:
func _update_terminal_tabs():
# Wait a couple of frames to allow everything to resize before updating.
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
await get_tree().idle_frame
await get_tree().idle_frame
if tabs.get_offset_buttons_visible():
# Move add button to fixed position on the tabbar.
# Move add button to fixed position checked the tabbar.
if add_button.get_parent() == tabs:
add_button.rect_position = Vector2.ZERO
add_button.position = Vector2.ZERO
tabs.remove_child(add_button)
tabbar_container.add_child(add_button)
tabbar_container.move_child(add_button, 0)
@ -122,7 +122,7 @@ func _update_terminal_tabs():
var last_tab := Rect2()
if tabs.get_tab_count() > 0:
last_tab = tabs.get_tab_rect(tabs.get_tab_count() - 1)
add_button.rect_position = Vector2(
add_button.position = Vector2(
last_tab.position.x + last_tab.size.x + 3, last_tab.position.y
)
@ -132,12 +132,12 @@ func _update_terminal_tabs():
func _on_AddButton_pressed():
var shell = OS.get_environment("SHELL") if OS.has_environment("SHELL") else "sh"
var terminal := EditorTerminal.instance()
var terminal := EditorTerminal.instantiate()
tabs.add_tab(shell.get_file())
terminal.editor_settings = editor_settings
terminal.set_anchors_preset(PRESET_WIDE)
terminal.connect("gui_input", self, "_on_TabContainer_gui_input")
terminal.connect("exited", self, "_on_Terminal_exited", [terminal])
terminal.connect("gui_input",Callable(self,"_on_TabContainer_gui_input"))
terminal.connect("exited",Callable(self,"_on_Terminal_exited").bind(terminal))
tab_container.add_child(terminal)
terminal.pty.fork(shell)
terminal.grab_focus()
@ -172,7 +172,7 @@ func _notification(what):
_update_terminal_tabs()
NOTIFICATION_RESIZED:
_update_terminal_tabs()
NOTIFICATION_WM_FOCUS_IN:
NOTIFICATION_APPLICATION_FOCUS_IN:
_update_terminal_tabs()
@ -182,7 +182,7 @@ func _input(event: InputEvent) -> void:
# Global shortcut to open new terminal and make terminal panel visible.
if _settings.new_terminal_shortcut and _settings.new_terminal_shortcut.shortcut:
if event.shortcut_match(_settings.new_terminal_shortcut.shortcut):
if event.is_match(_settings.new_terminal_shortcut.shortcut):
get_tree().set_input_as_handled()
editor_plugin.make_bottom_panel_item_visible(self)
_on_AddButton_pressed()
@ -194,38 +194,38 @@ func _input(event: InputEvent) -> void:
):
# Kill terminal.
if _settings.kill_terminal_shortcut and _settings.kill_terminal_shortcut.shortcut:
if event.shortcut_match(_settings.kill_terminal_shortcut.shortcut):
if event.is_match(_settings.kill_terminal_shortcut.shortcut):
get_tree().set_input_as_handled()
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.KILL_TERMINAL)
# Copy.
if _settings.copy_shortcut and _settings.copy_shortcut.shortcut:
if event.shortcut_match(_settings.copy_shortcut.shortcut):
if event.is_match(_settings.copy_shortcut.shortcut):
get_tree().set_input_as_handled()
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.COPY)
# Paste.
if _settings.paste_shortcut and _settings.paste_shortcut.shortcut:
if event.shortcut_match(_settings.paste_shortcut.shortcut):
if event.is_match(_settings.paste_shortcut.shortcut):
get_tree().set_input_as_handled()
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.PASTE)
# Next tab.
if _settings.next_tab_shortcut and _settings.next_tab_shortcut.shortcut:
if event.shortcut_match(_settings.next_tab_shortcut.shortcut):
if event.is_match(_settings.next_tab_shortcut.shortcut):
get_tree().set_input_as_handled()
tabs.current_tab = min(tabs.current_tab + 1, tabs.get_tab_count() - 1)
# Previous tab.
if _settings.previous_tab_shortcut and _settings.previous_tab_shortcut.shortcut:
if event.shortcut_match(_settings.previous_tab_shortcut.shortcut):
if event.is_match(_settings.previous_tab_shortcut.shortcut):
get_tree().set_input_as_handled()
tabs.current_tab = max(tabs.current_tab - 1, 0)
func _on_TabContainer_gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT:
terminal_popup_menu.rect_position = event.global_position
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT:
terminal_popup_menu.position = event.global_position
terminal_popup_menu.popup()
@ -243,7 +243,7 @@ func _on_TerminalPopupMenu_id_pressed(id):
for i in OS.clipboard.length():
var event = InputEventKey.new()
event.unicode = ord(OS.clipboard[i])
event.pressed = true
event.button_pressed = true
terminal._gui_input(event)
TerminalPopupMenuOptions.COPY_ALL:
OS.clipboard = terminal.copy_all()
@ -262,7 +262,7 @@ func _on_Panel_resized():
if not size_label:
return
var size = tab_container.rect_size
var size = tab_container.size
if tabs.get_tab_count() > 0:
var terminal = tab_container.get_child(tabs.current_tab)
var cols = terminal.get_cols()

View file

@ -4,7 +4,7 @@
[sub_resource type="Image" id=6]
data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"data": PackedByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "LumAlpha8",
"height": 16,
"mipmaps": false,
@ -20,14 +20,14 @@ size = Vector2( 16, 16 )
[sub_resource type="StyleBoxTexture" id=3]
texture = SubResource( 2 )
region_rect = Rect2( 0, 0, 16, 16 )
margin_left = 2.0
margin_right = 2.0
margin_top = 2.0
margin_bottom = 2.0
offset_left = 2.0
offset_right = 2.0
offset_top = 2.0
offset_bottom = 2.0
[sub_resource type="Image" id=7]
data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"data": PackedByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
@ -43,8 +43,8 @@ size = Vector2( 16, 16 )
[node name="Panel" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_top = -3.0
rect_min_size = Vector2( 0, 34 )
offset_top = -3.0
minimum_size = Vector2( 0, 34 )
custom_styles/panel = SubResource( 3 )
script = ExtResource( 1 )
__meta__ = {
@ -54,48 +54,48 @@ __meta__ = {
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
rect_min_size = Vector2( 0, 24 )
minimum_size = Vector2( 0, 24 )
custom_constants/separation = 0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TabbarContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_right = 1024.0
margin_bottom = 24.0
offset_right = 1024.0
offset_bottom = 24.0
[node name="Tabs" type="Tabs" parent="VBoxContainer/TabbarContainer"]
margin_right = 1024.0
margin_bottom = 24.0
[node name="TabBar" type="TabBar" parent="VBoxContainer/TabbarContainer"]
offset_right = 1024.0
offset_bottom = 24.0
size_flags_horizontal = 3
tab_align = 0
tab_alignment = 0
tab_close_display_policy = 1
drag_to_rearrange_enabled = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AddButton" type="ToolButton" parent="VBoxContainer/TabbarContainer/Tabs"]
margin_left = 3.0
margin_right = 31.0
margin_bottom = 24.0
hint_tooltip = "Add a new scene."
[node name="AddButton" type="Button" parent="VBoxContainer/TabbarContainer/TabBar"]
offset_left = 3.0
offset_right = 31.0
offset_bottom = 24.0
tooltip_text = "Add a new scene."
icon = SubResource( 5 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PopupMenu" type="PopupMenu" parent="VBoxContainer/TabbarContainer"]
margin_left = 906.0
margin_right = 1024.0
margin_bottom = 88.0
offset_left = 906.0
offset_right = 1024.0
offset_bottom = 88.0
items = [ "Kill", null, 0, false, false, 0, 0, null, "", false, "Kill Others", null, 0, false, false, 1, 0, null, "", false, "Kill to the Right", null, 0, false, false, 2, 0, null, "", false, "Kill All", null, 0, false, false, 3, 0, null, "", false ]
[node name="TabContainer" type="TabContainer" parent="VBoxContainer"]
margin_top = 24.0
margin_right = 1024.0
margin_bottom = 603.0
rect_clip_content = true
offset_top = 24.0
offset_right = 1024.0
offset_bottom = 603.0
clip_contents = true
size_flags_vertical = 3
custom_constants/top_margin = 0
custom_constants/side_margin = 0
@ -103,8 +103,8 @@ custom_styles/panel = SubResource( 3 )
tabs_visible = false
[node name="TerminalPopupMenu" type="PopupMenu" parent="VBoxContainer"]
margin_right = 193.0
margin_bottom = 160.0
offset_right = 193.0
offset_bottom = 160.0
size_flags_horizontal = 0
size_flags_vertical = 0
items = [ "New Terminal", null, 0, false, false, 0, 0, null, "", false, "", null, 0, false, true, 1, 0, null, "", true, "Copy", null, 0, false, false, 2, 0, null, "", false, "Paste", null, 0, false, false, 3, 0, null, "", false, "Copy All", null, 0, false, false, 4, 0, null, "", false, "", null, 0, false, false, 5, 0, null, "", true, "Clear", null, 0, false, false, 6, 0, null, "", false, "Kill Terminal", null, 0, false, false, 7, 0, null, "", false ]
@ -118,10 +118,10 @@ anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -52.0
margin_top = -15.5
margin_right = 52.0
margin_bottom = 15.5
offset_left = -52.0
offset_top = -15.5
offset_right = 52.0
offset_bottom = 15.5
text = "Size: %d rows; %d cols
(%d x %d)"
align = 1
@ -133,10 +133,10 @@ __meta__ = {
show_behind_parent = true
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -5.0
margin_top = -5.0
margin_right = 5.0
margin_bottom = 5.0
offset_left = -5.0
offset_top = -5.0
offset_right = 5.0
offset_bottom = 5.0
grow_horizontal = 2
grow_vertical = 2
__meta__ = {
@ -146,10 +146,10 @@ __meta__ = {
[node name="SizeLabelTimer" type="Timer" parent="SizeLabel"]
[connection signal="resized" from="." to="." method="_on_Panel_resized"]
[connection signal="reposition_active_tab_request" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_reposition_active_tab_request"]
[connection signal="tab_changed" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_changed"]
[connection signal="tab_close" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_close"]
[connection signal="pressed" from="VBoxContainer/TabbarContainer/Tabs/AddButton" to="." method="_on_AddButton_pressed"]
[connection signal="reposition_active_tab_request" from="VBoxContainer/TabbarContainer/TabBar" to="." method="_on_Tabs_reposition_active_tab_request"]
[connection signal="tab_changed" from="VBoxContainer/TabbarContainer/TabBar" to="." method="_on_Tabs_tab_changed"]
[connection signal="tab_closed" from="VBoxContainer/TabbarContainer/TabBar" to="." method="_on_Tabs_tab_close"]
[connection signal="pressed" from="VBoxContainer/TabbarContainer/TabBar/AddButton" to="." method="_on_AddButton_pressed"]
[connection signal="gui_input" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_gui_input"]
[connection signal="id_pressed" from="VBoxContainer/TerminalPopupMenu" to="." method="_on_TerminalPopupMenu_id_pressed"]
[connection signal="timeout" from="SizeLabel/SizeLabelTimer" to="." method="_on_SizeLabelTimer_timeout"]

View file

@ -1,34 +1,34 @@
tool
@tool
extends EditorImportPlugin
const Asciicast = preload("../resources/asciicast.gd")
func get_importer_name():
func _get_importer_name():
return "godot_xterm"
func get_visible_name():
func _get_visible_name():
return "asciicast"
func get_recognized_extensions():
func _get_recognized_extensions():
return ["cast"]
func get_save_extension():
func _get_save_extension():
return "res"
func get_resource_type():
func _get_resource_type():
return "Animation"
func get_import_options(preset):
func _get_import_options(preset):
return []
func get_preset_count():
func _get_preset_count():
return 0
@ -45,29 +45,31 @@ func import(source_file, save_path, options, r_platform_variant, r_gen_files):
asciicast.add_track(Animation.TYPE_METHOD, 0)
asciicast.track_set_path(0, ".")
var frame = {"time": 0.0, "data": {"method": "write", "args": [PoolByteArray()]}}
var frame = {"time": 0.0, "data": {"method": "write", "args": [PackedByteArray()]}}
while not file.eof_reached():
var line = file.get_line()
if line == "":
continue
var p = JSON.parse(line)
var test_json_conv = JSON.new()
test_json_conv.parse(line)
var p = test_json_conv.get_data()
if typeof(p.result) != TYPE_ARRAY:
continue
var event_type: String = p.result[1]
var event_data: PoolByteArray = p.result[2].to_utf8()
var event_data: PackedByteArray = p.result[2].to_utf8_buffer()
# Asciicast recordings have a resolution of 0.000001, however animation
# track keys only have a resolution of 0.01, therefore we must combine
# events that would occur in the same keyframe, otherwise only the last
# event is inserted and the previous events are overwritten.
var time = stepify(p.result[0], 0.01)
var time = snapped(p.result[0], 0.01)
if event_type == "o":
if time == frame.time:
asciicast.track_remove_key_at_position(0, time)
asciicast.track_remove_key_at_time(0, time)
frame.data.args[0] = frame.data.args[0] + event_data
else:
frame.time = time
@ -77,4 +79,4 @@ func import(source_file, save_path, options, r_platform_variant, r_gen_files):
asciicast.length = frame.time
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], asciicast)
return ResourceSaver.save("%s.%s" % [save_path, _get_save_extension()], asciicast)

View file

@ -1,34 +1,34 @@
tool
@tool
extends EditorImportPlugin
const XrdbTheme := preload("../resources/xrdb_theme.gd")
func get_importer_name():
func _get_importer_name():
return "godot_xterm_xrdb_importer"
func get_visible_name():
func _get_visible_name():
return "xrdb_theme"
func get_recognized_extensions():
func _get_recognized_extensions():
return ["xrdb", "Xresources", "xresources"]
func get_save_extension():
func _get_save_extension():
return "res"
func get_resource_type():
func _get_resource_type():
return "Theme"
func get_import_options(preset):
func _get_import_options(preset):
return []
func get_preset_count():
func _get_preset_count():
return 0
@ -121,4 +121,4 @@ func import(source_file, save_path, options, r_platform_variant, r_gen_files):
"cursor_text_color":
theme.set_color("cursor_text", "Terminal", color)
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], theme)
return ResourceSaver.save("%s.%s" % [save_path, _get_save_extension()], theme)

View file

@ -1,6 +1,6 @@
# Copyright (c) 2021, Leroy Hopson (MIT License)
tool
@tool
extends Object
# Wrapper around libuv utility functions.
# GDNative does not currently support registering static functions so we fake it.
@ -23,9 +23,9 @@ static func get_cwd() -> String:
static func get_windows_build_number() -> int:
assert(OS.get_name() == "Windows", "This function is only supported on Windows.")
assert(OS.get_name() == "Windows") #,"This function is only supported checked Windows.")
var release: String = LibuvUtils.new().get_os_release()
assert(false, "Not implemented.")
assert(false) #,"Not implemented.")
return 0
@ -35,4 +35,4 @@ static func kill(pid: int, signum: int):
static func new():
assert(false, "Abstract sealed (i.e. static) class should not be instantiated.")
assert(false) #,"Abstract sealed (i.e. static) class should not be instantiated.")

View file

@ -1,4 +1,4 @@
tool
@tool
extends Node
signal data_received(data)
@ -20,5 +20,5 @@ func _not_implemented() -> int:
if stack.size() >= 2 and "function" in stack[1]:
method = "%s()" % stack[1].function
push_error("Method %s not implemented on the current platform (%s)." % [method, OS.get_name()])
push_error("Method %s not implemented checked the current platform (%s)." % [method, OS.get_name()])
return ERR_METHOD_NOT_FOUND

View file

@ -3,7 +3,7 @@
# Copyright (c) 2016, Daniel Imms (MIT License).
# Copyright (c) 2018, Microsoft Corporation (MIT License).
# Copyright (c) 2021-2022, Leroy Hopson (MIT License).
tool
@tool
extends "../pty_native.gd"
const LibuvUtils := preload("../libuv_utils.gd")
@ -18,7 +18,7 @@ const DEFAULT_ENV := {TERM = DEFAULT_NAME, COLORTERM = "truecolor"}
const FALLBACK_FILE = "sh"
## Default messages to indicate PAUSE/RESUME for automatic flow control.
## To avoid conflicts with rebound XON/XOFF control codes (such as on-my-zsh),
## To avoid conflicts with rebound XON/XOFF control codes (such as checked-my-zsh),
## the sequences can be customized in IPtyForkOptions.
#const FLOW_CONTROL_PAUSE = char(0x13) # defaults to XOFF
#const FLOW_CONTROL_RESUME = char(0x11) # defaults to XON
@ -35,7 +35,7 @@ enum Signal {
SIGFPE = 8, # Erroneous arithmetic operation
SIGKILL = 9, # Kill (cannot be caught or ignored)
SIGSEGV = 11, # Invalid memory reference
SIGPIPE = 13, # Write on a pipe with no one to read it
SIGPIPE = 13, # Write checked a pipe with no one to read it
SIGALRM = 14, # Alarm clock
SIGTERM = 15, # Termination signal
}
@ -62,18 +62,18 @@ var uid: int
var gid: int
var _fd: int = -1
var _exit_cb: FuncRef
var _exit_cb: Callable
# Writes data to the socket.
# data: The data to write.
func write(data) -> void:
assert(
data is PoolByteArray or data is String,
"Invalid type for argument 'data'. Should be of type PoolByteArray or String"
data is PackedByteArray or data is String,
"Invalid type for argument 'data'. Should be of type PackedByteArray or String"
)
if _pipe:
_pipe.write(data if data is PoolByteArray else data.to_utf8())
_pipe.write(data if data is PackedByteArray else data.to_utf8_buffer())
func resize(cols: int, rows: int) -> void:
@ -88,14 +88,14 @@ func kill(signum: int = Signal.SIGHUP) -> void:
LibuvUtils.kill(_pid, signum)
func _parse_env(env: Dictionary = {}) -> PoolStringArray:
func _parse_env(env: Dictionary = {}) -> PackedStringArray:
var keys := env.keys()
var pairs := PoolStringArray()
var pairs := PackedStringArray()
for key in keys:
var value = env[key]
var valid = key is String and value is String
assert(valid, "Env key/value pairs must be of type String/String.")
assert(valid) #,"Env key/value pairs must be of type String/String.")
if not valid:
push_warning("Skipping invalid env key/value pair.")
@ -113,7 +113,7 @@ func _process(_delta):
func fork(
file: String = OS.get_environment("SHELL"),
args: PoolStringArray = PoolStringArray(),
args: PackedStringArray = PackedStringArray(),
cwd = LibuvUtils.get_cwd(),
cols: int = DEFAULT_COLS,
rows: int = DEFAULT_ROWS,
@ -122,18 +122,18 @@ func fork(
utf8 = true
) -> int:
# File.
if file.empty():
if file.is_empty():
file = FALLBACK_FILE
# Environment variables.
# If we are using OS env vars, sanitize them to remove variables that might confuse our terminal.
# If we are using OS env vars, sanitize them to remove_at variables that might confuse our terminal.
var final_env := _sanitize_env(LibuvUtils.get_os_environ()) if use_os_env else {}
for key in env.keys():
final_env[key] = env[key]
var parsed_env: PoolStringArray = _parse_env(final_env)
var parsed_env: PackedStringArray = _parse_env(final_env)
# Exit callback.
_exit_cb = FuncRef.new()
_exit_cb = Callable.new()
_exit_cb.set_instance(self)
_exit_cb.set_function("_on_exit")
@ -157,7 +157,7 @@ func fork(
_pipe.open(_fd)
# Must connect to signal AFTER opening, otherwise we will get error ENOTSOCK.
_pipe.connect("data_received", self, "_on_pipe_data_received")
_pipe.connect("data_received",Callable(self,"_on_pipe_data_received"))
return OK

View file

@ -1,2 +1,2 @@
tool
extends Viewport
@tool
extends SubViewport

View file

@ -4,10 +4,10 @@
[sub_resource type="GDScript" id=1]
script/source = "tool
extends Viewport
extends SubViewport
"
[node name="Viewport" type="Viewport"]
[node name="SubViewport" type="SubViewport"]
size = Vector2( 2, 2 )
own_world = true
transparent_bg = true
@ -22,8 +22,8 @@ script = SubResource( 1 )
[node name="Terminal" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = -2.0
margin_bottom = -2.0
offset_right = -2.0
offset_bottom = -2.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false

View file

@ -1,4 +1,4 @@
tool
@tool
extends EditorPlugin
var pty_supported := OS.get_name() in ["X11", "Server", "OSX"]
@ -31,7 +31,7 @@ func _enter_tree():
"X11", "Server", "OSX":
pty_script = load("%s/pty.gd" % base_dir)
add_custom_type("PTY", "Node", pty_script, pty_icon)
terminal_panel = preload("./editor_plugins/terminal/terminal_panel.tscn").instance()
terminal_panel = preload("./editor_plugins/terminal/terminal_panel.tscn").instantiate()
terminal_panel.editor_plugin = self
terminal_panel.editor_interface = get_editor_interface()
add_control_to_bottom_panel(terminal_panel, "Terminal")

View file

@ -3,7 +3,7 @@
# Copyright (c) 2016, Daniel Imms (MIT License).
# Copyright (c) 2018, Microsoft Corporation (MIT License).
# Copyright (c) 2021-2022, Leroy Hopson (MIT License).
tool
@tool
extends Node
const _LibuvUtils := preload("./nodes/pty/libuv_utils.gd")
@ -23,23 +23,39 @@ const Signal = _PTYUnix.Signal
signal data_received(data)
signal exited(exit_code, signum)
export(NodePath) var terminal_path := NodePath() setget set_terminal_path
@export var terminal_path: NodePath := NodePath() :
get:
return terminal_path # TODOConverter40 Non existent get function
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_terminal_path
var _terminal: _Terminal = null setget _set_terminal
var _terminal: _Terminal = null :
get:
return _terminal # TODOConverter40 Non existent get function
set(mod_value):
mod_value # TODOConverter40 Copy here content of _set_terminal
# The column size in characters.
export(int) var cols: int = DEFAULT_COLS setget set_cols, get_cols
@export var cols: int: int = DEFAULT_COLS :
get:
return cols # TODOConverter40 Copy here content of get_cols
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_cols
# The row size in characters.
export(int) var rows: int = DEFAULT_ROWS setget set_rows, get_rows
@export var rows: int: int = DEFAULT_ROWS :
get:
return rows # TODOConverter40 Copy here content of get_rows
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_rows
# Environment to be set for the child program.
export(Dictionary) var env := DEFAULT_ENV
@export var env: Dictionary := DEFAULT_ENV
# If true the environment variables in the env Dictionary will be merged with
# the environment variables of the operating system (e.g. printenv), with the
# former taking precedence in the case of conflicts.
export(bool) var use_os_env := true
@export var use_os_env: bool := true
var _cols := DEFAULT_COLS
var _rows := DEFAULT_ROWS
@ -52,10 +68,10 @@ func _init():
"X11", "Server", "OSX":
_pty_native = _PTYUnix.new()
_:
push_error("PTY is not support on current platform (%s)." % os_name)
push_error("PTY is not support checked current platform (%s)." % os_name)
_pty_native.connect("data_received", self, "_on_pty_native_data_received")
_pty_native.connect("exited", self, "_on_pty_native_exited")
_pty_native.connect("data_received",Callable(self,"_on_pty_native_data_received"))
_pty_native.connect("exited",Callable(self,"_on_pty_native_exited"))
add_child(_pty_native)
@ -92,9 +108,9 @@ func _set_terminal(value: _Terminal):
# Disconect the current terminal, if any.
if _terminal:
disconnect("data_received", _terminal, "write")
_terminal.disconnect("data_sent", self, "write")
_terminal.disconnect("size_changed", self, "resizev")
disconnect("data_received",Callable(_terminal,"write"))
_terminal.disconnect("data_sent",Callable(self,"write"))
_terminal.disconnect("size_changed",Callable(self,"resizev"))
_terminal = value
@ -103,12 +119,12 @@ func _set_terminal(value: _Terminal):
# Connect the new terminal.
resize(_terminal.get_cols(), _terminal.get_rows())
if not _terminal.is_connected("size_changed", self, "resizev"):
_terminal.connect("size_changed", self, "resizev")
if not _terminal.is_connected("data_sent", self, "write"):
_terminal.connect("data_sent", self, "write")
if not is_connected("data_received", _terminal, "write"):
connect("data_received", _terminal, "write")
if not _terminal.is_connected("size_changed",Callable(self,"resizev")):
_terminal.connect("size_changed",Callable(self,"resizev"))
if not _terminal.is_connected("data_sent",Callable(self,"write")):
_terminal.connect("data_sent",Callable(self,"write"))
if not is_connected("data_received",Callable(_terminal,"write")):
connect("data_received",Callable(_terminal,"write"))
# Writes data to the socket.
@ -138,7 +154,7 @@ func resizev(size: Vector2) -> void:
# Kill the pty.
# sigint: The signal to send. By default this is SIGHUP.
# This is not supported on Windows.
# This is not supported checked Windows.
func kill(signum: int = Signal.SIGHUP) -> void:
_pty_native.kill(signum)
@ -153,7 +169,7 @@ func _notification(what: int):
func fork(
file: String = OS.get_environment("SHELL"),
args: PoolStringArray = PoolStringArray(),
args: PackedStringArray = PackedStringArray(),
cwd = _LibuvUtils.get_cwd(),
cols: int = _cols,
rows: int = _rows,

View file

@ -3,11 +3,11 @@ extends Animation
signal data_written(data)
signal data_read(data)
export(int) var version: int = 2
@export var version: int: int = 2
# Initial terminal width (number of columns).
export(int) var width: int
@export var width: int: int
# Initial terminal height (number of rows).
export(int) var height: int
@export var height: int: int
func get_class() -> String:
@ -15,7 +15,7 @@ func get_class() -> String:
func is_class(name) -> bool:
return name == get_class() or .is_class(name)
return name == get_class() or super.is_class(name)
func _init():

View file

@ -6,4 +6,4 @@ func get_class() -> String:
func is_class(name) -> bool:
return name == get_class() or .is_class(name)
return name == get_class() or super.is_class(name)

View file

@ -4,7 +4,7 @@
# These snippets are copyright of their authors and released under the MIT license:
# - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License).
# - Copyright (c) 2014-2021 Godot Engine contributors (MIT License).
tool
@tool
extends Control
signal data_sent(data)
@ -24,28 +24,32 @@ enum SelectionMode {
POINTER,
}
export(UpdateMode) var update_mode = UpdateMode.AUTO setget set_update_mode
@export var update_mode: UpdateMode = UpdateMode.AUTO :
get:
return update_mode # TODOConverter40 Non existent get function
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_update_mode
# If true, text in the terminal will be copied to the clipboard when selected.
export(bool) var copy_on_selection
@export var copy_on_selection: bool
# Bell
# If muted, the "bell" signal will not be emitted when the bell "\u0007" character
# is written to the terminal.
export var bell_muted := false
@export var bell_muted := false
# Amount of time in seconds that must pass before emitting a new "bell" signal.
# This can be useful in cases where the bell character is being written too
# frequently such as `while true; do echo -e "\a"; done`.
export var bell_cooldown: float = 0.1
@export var bell_cooldown: float = 0.1
export var blink_on_time: float = 0.6
export var blink_off_time: float = 0.3
@export var blink_on_time: float = 0.6
@export var blink_off_time: float = 0.3
var _cols := 2
var _rows := 2
var _default_theme: Theme = preload("./themes/default.tres")
var _viewport: Viewport = preload("./nodes/terminal/viewport.tscn").instance()
var _viewport: SubViewport = preload("./nodes/terminal/viewport.tscn").instantiate()
var _native_terminal: Control = _viewport.get_node("Terminal")
var _screen := TextureRect.new()
@ -73,11 +77,11 @@ func get_rows() -> int:
func write(data) -> void:
assert(
data is PoolByteArray or data is String,
"Invalid type for argument 'data'. Should be of type PoolByteArray or String."
data is PackedByteArray or data is String,
"Invalid type for argument 'data'. Should be of type PackedByteArray or String."
)
# Will be cleared when _flush() is called after VisualServer emits the "frame_pre_draw" signal.
# Will be cleared when _flush() is called after RenderingServer emits the "frame_pre_draw" signal.
_buffer.push_back(data)
# Ensure redraw is requested if terminal is visible.
@ -87,16 +91,16 @@ func write(data) -> void:
func _flush():
for data in _buffer:
_native_terminal.write(data if data is PoolByteArray else data.to_utf8())
_native_terminal.write(data if data is PackedByteArray else data.to_utf8_buffer())
_native_terminal.update()
_buffer.clear()
func clear() -> void:
var initial_size = _native_terminal.rect_size
_native_terminal.rect_size.y = _native_terminal.cell_size.y
var initial_size = _native_terminal.size
_native_terminal.size.y = _native_terminal.cell_size.y
_native_terminal.clear_sb()
_native_terminal.rect_size = initial_size
_native_terminal.size = initial_size
func copy_selection() -> String:
@ -111,22 +115,22 @@ func _ready():
_update_theme()
_native_terminal.update_mode = update_mode
_native_terminal.connect("data_sent", self, "_on_data_sent")
_native_terminal.connect("key_pressed", self, "_on_key_pressed")
_native_terminal.connect("size_changed", self, "_on_size_changed")
_native_terminal.connect("data_sent",Callable(self,"_on_data_sent"))
_native_terminal.connect("key_pressed",Callable(self,"_on_key_pressed"))
_native_terminal.connect("size_changed",Callable(self,"_on_size_changed"))
_viewport.size = rect_size
_viewport.render_target_update_mode = Viewport.UPDATE_ALWAYS
_viewport.size = size
_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
_screen.set_anchors_preset(PRESET_WIDE)
_screen.texture = _viewport.get_texture()
_native_terminal.connect("bell", self, "_on_bell")
_native_terminal.connect("bell",Callable(self,"_on_bell"))
_bell_timer.one_shot = true
add_child(_bell_timer)
_selection_timer.wait_time = 0.05
_selection_timer.connect("timeout", self, "_on_selection_held")
_selection_timer.connect("timeout",Callable(self,"_on_selection_held"))
add_child(_viewport)
add_child(_screen)
@ -138,31 +142,31 @@ func _ready():
# we make all the draw_* calls caused by writing. We need to use signals
# here rather than yield otherwise we will sometimes get a "Resumed
# function after yield but class instance is gone" error.
VisualServer.connect("frame_pre_draw", self, "_flush")
RenderingServer.connect("frame_pre_draw",Callable(self,"_flush"))
func _update_theme():
# Themes are not propagated through the Viewport, so in order for theme
# Themes are not propagated through the SubViewport, so in order for theme
# inheritance to work we can pass through the theme variables manually.
for color in _default_theme.get_color_list("Terminal"):
var c: Color
if has_color(color, "Terminal"):
if has_theme_color(color, "Terminal"):
c = get_color(color, "Terminal")
else:
c = _default_theme.get_color(color, "Terminal")
_native_terminal.add_color_override(color, c)
_native_terminal.add_theme_color_override(color, c)
for font in _default_theme.get_font_list("Terminal"):
var f: Font
if has_font(font, "Terminal"):
if has_theme_font(font, "Terminal"):
f = get_font(font, "Terminal")
elif has_font("regular", "Terminal"):
elif has_theme_font("regular", "Terminal"):
f = get_font("regular", "Terminal")
else:
if _default_theme.has_font(font, "Terminal"):
if _default_theme.has_theme_font(font, "Terminal"):
f = _default_theme.get_font(font, "Terminal")
else:
f = _default_theme.get_font(font, "regular")
_native_terminal.add_font_override(font, f)
_native_terminal.add_theme_font_override(font, f)
_native_terminal._update_theme()
_native_terminal._update_size()
@ -180,7 +184,7 @@ func _gui_input(event):
# Return to bottom of scrollback buffer if we scrolled up. Ignore modifier
# keys pressed in isolation or if Ctrl+Shift modifier keys are pressed.
if (
not event.scancode in [KEY_ALT, KEY_SHIFT, KEY_CONTROL, KEY_META, KEY_MASK_CMD]
not event.scancode in [KEY_ALT, KEY_SHIFT, KEY_CTRL, KEY_META, KEY_MASK_CMD]
and not (event.control and event.shift)
):
_native_terminal.sb_reset()
@ -197,7 +201,7 @@ func _handle_mouse_wheel(event: InputEventMouseButton):
if not event or not event.is_pressed():
return
if event.button_index == BUTTON_WHEEL_UP:
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
if event.alt:
# Scroll 5 times as fast as normal (like TextEdit).
_native_terminal.sb_up(15 * event.factor)
@ -205,7 +209,7 @@ func _handle_mouse_wheel(event: InputEventMouseButton):
# Scroll 3 lines.
_native_terminal.sb_up(3 * event.factor)
if event.button_index == BUTTON_WHEEL_DOWN:
if event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
if event.alt:
# Scroll 5 times as fast as normal (like TextEdit).
_native_terminal.sb_down(15 * event.factor)
@ -216,7 +220,7 @@ func _handle_mouse_wheel(event: InputEventMouseButton):
func _handle_selection(event: InputEventMouse):
if event is InputEventMouseButton:
if not event or not event.is_pressed() or not event.button_index == BUTTON_LEFT:
if not event or not event.is_pressed() or not event.button_index == MOUSE_BUTTON_LEFT:
return
if _selecting:
@ -230,7 +234,7 @@ func _handle_selection(event: InputEventMouse):
elif event is InputEventMouseMotion:
if (
event.button_mask & BUTTON_MASK_LEFT
event.button_mask & MOUSE_BUTTON_MASK_LEFT
and _selecting_mode != SelectionMode.NONE
and not _selecting
):
@ -240,7 +244,7 @@ func _handle_selection(event: InputEventMouse):
func _on_selection_held() -> void:
if not Input.is_mouse_button_pressed(BUTTON_LEFT) or _selecting_mode == SelectionMode.NONE:
if not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) or _selecting_mode == SelectionMode.NONE:
if copy_on_selection:
var selection = _native_terminal.copy_selection()
OS.set_clipboard(selection)
@ -255,18 +259,18 @@ func _on_selection_held() -> void:
func _notification(what: int) -> void:
match what:
NOTIFICATION_RESIZED:
_viewport.size = rect_size
_viewport.size = size
_refresh()
NOTIFICATION_THEME_CHANGED:
_update_theme()
_refresh()
func _on_data_sent(data: PoolByteArray):
func _on_data_sent(data: PackedByteArray):
emit_signal("data_sent", data)
func _on_key_pressed(data: PoolByteArray, event: InputEventKey):
func _on_key_pressed(data: PackedByteArray, event: InputEventKey):
emit_signal("key_pressed", data.get_string_from_utf8(), event)

View file

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="DynamicFont" id=1]
[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="FontFile" id=1]
[resource]
default_font = ExtResource( 1 )

View file

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="DynamicFont" id=4]
[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="FontFile" id=4]
[resource]
default_font = ExtResource( 4 )

View file

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=2]
[sub_resource type="DynamicFont" id=1]
[sub_resource type="FontFile" id=1]
size = 14
extra_spacing_bottom = 1

View file

@ -1,6 +1,6 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[gd_resource type="FontFile" load_steps=2 format=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=4]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="FontFile" id=4]
[resource]
size = 14

View file

@ -1,4 +1,4 @@
extends Reference
extends RefCounted
# Control Sequence Introducer
const CSI = "\u001b["
@ -17,24 +17,24 @@ class ANSIColor:
# colors of the selected terminal theme. Whereas Color will set
# the exact color specified regardless of theme.
const black = {fg = 30, bg = 40}
const red = {fg = 31, bg = 41}
const green = {fg = 32, bg = 42}
const yellow = {fg = 33, bg = 43}
const blue = {fg = 34, bg = 44}
const magenta = {fg = 35, bg = 45}
const cyan = {fg = 36, bg = 46}
const white = {fg = 37, bg = 47}
const bright_black = {fg = 90, bg = 100}
const black = {fg = 30, panel = 40}
const red = {fg = 31, panel = 41}
const green = {fg = 32, panel = 42}
const yellow = {fg = 33, panel = 43}
const blue = {fg = 34, panel = 44}
const magenta = {fg = 35, panel = 45}
const cyan = {fg = 36, panel = 46}
const white = {fg = 37, panel = 47}
const bright_black = {fg = 90, panel = 100}
const gray = bright_black
const grey = bright_black
const bright_red = {fg = 91, bg = 101}
const bright_green = {fg = 92, bg = 102}
const bright_yellow = {fg = 93, bg = 103}
const bright_blue = {fg = 94, bg = 104}
const bright_magenta = {fg = 95, bg = 105}
const bright_cyan = {fg = 96, bg = 106}
const bright_white = {fg = 97, bg = 107}
const bright_red = {fg = 91, panel = 101}
const bright_green = {fg = 92, panel = 102}
const bright_yellow = {fg = 93, panel = 103}
const bright_blue = {fg = 94, panel = 104}
const bright_magenta = {fg = 95, panel = 105}
const bright_cyan = {fg = 96, panel = 106}
const bright_white = {fg = 97, panel = 107}
func _init():
assert(
@ -46,23 +46,23 @@ class ANSIColor:
var terminal
func _init(p_terminal: Control) -> void:
func _init(p_terminal: Control):
if p_terminal:
terminal = p_terminal
func write_string(string: String, color: Color = Color.white) -> void:
func write_string(string: String, color: Color = Color.WHITE) -> void:
if color:
var fg = "\u001b[38;2;%d;%d;%dm" % [color.r8, color.g8, color.b8]
terminal.write(fg.to_utf8())
terminal.write(fg.to_utf8_buffer())
terminal.write(string.to_utf8())
terminal.write(string.to_utf8_buffer())
# Reset color back to default.
terminal.write("\u001b[0m".to_utf8())
terminal.write("\u001b[0m".to_utf8_buffer())
# tput_* functions based on the tput command.
# tput_* functions based checked the tput command.
# See: https://man7.org/linux/man-pages/man1/tput.1.html for more info.
@ -88,8 +88,8 @@ func setaf(color) -> void:
func setab(color) -> void:
if color is Color:
terminal.write("\u001b[48;2;%d;%d;%dm" % [color.r8, color.g8, color.b8])
elif "bg" in color and color.bg is int:
terminal.write("\u001b[%dm" % color.bg)
elif "panel" in color and color.panel is int:
terminal.write("\u001b[%dm" % color.panel)
else:
push_error("Invalid color: %s" % color)

View file

@ -1,8 +1,8 @@
extends Panel
onready var _script_list = $ScriptsList
onready var _nav_container = $VBox/BottomPanel/VBox/HBox/Navigation
onready var _nav = {
@onready var _script_list = $ScriptsList
@onready var _nav_container = $VBox/BottomPanel/VBox/HBox/Node3D
@onready var _nav = {
container = _nav_container,
prev = _nav_container.get_node("VBox/HBox/Previous"),
next = _nav_container.get_node("VBox/HBox/Next"),
@ -11,14 +11,14 @@ onready var _nav = {
run_single = _nav_container.get_node("VBox/HBox/RunSingleScript")
}
onready var _progress_container = $VBox/BottomPanel/VBox/HBox/Progress
onready var _progress = {
@onready var _progress_container = $VBox/BottomPanel/VBox/HBox/Progress
@onready var _progress = {
script = _progress_container.get_node("ScriptProgress"),
script_xy = _progress_container.get_node("ScriptProgress/xy"),
test = _progress_container.get_node("TestProgress"),
test_xy = _progress_container.get_node("TestProgress/xy")
}
onready var _summary = {
@onready var _summary = {
control = $VBox/TitleBar/HBox/Summary,
failing = $VBox/TitleBar/HBox/Summary/Failing,
passing = $VBox/TitleBar/HBox/Summary/Passing,
@ -27,21 +27,21 @@ onready var _summary = {
pass_count = 0
}
onready var _extras = $ExtraOptions
onready var _ignore_pauses = $ExtraOptions/IgnorePause
onready var _continue_button = $VBox/BottomPanel/VBox/HBox/Continue/Continue
onready var _text_box = $VBox/TextDisplay/RichTextLabel
onready var _text_box_container = $VBox/TextDisplay
onready var _log_level_slider = $VBox/BottomPanel/VBox/HBox2/LogLevelSlider
onready var _resize_handle = $ResizeHandle
onready var _current_script = $VBox/BottomPanel/VBox/HBox2/CurrentScriptLabel
onready var _title_replacement = $VBox/TitleBar/HBox/TitleReplacement
@onready var _extras = $ExtraOptions
@onready var _ignore_pauses = $ExtraOptions/IgnorePause
@onready var _continue_button = $VBox/BottomPanel/VBox/HBox/Continue/Continue
@onready var _text_box = $VBox/TextDisplay/RichTextLabel
@onready var _text_box_container = $VBox/TextDisplay
@onready var _log_level_slider = $VBox/BottomPanel/VBox/HBox2/LogLevelSlider
@onready var _resize_handle = $ResizeHandle
@onready var _current_script = $VBox/BottomPanel/VBox/HBox2/CurrentScriptLabel
@onready var _title_replacement = $VBox/TitleBar/HBox/TitleReplacement
onready var _titlebar = {
@onready var _titlebar = {
bar = $VBox/TitleBar, time = $VBox/TitleBar/HBox/Time, label = $VBox/TitleBar/HBox/Title
}
onready var _user_files = $UserFileViewer
@onready var _user_files = $UserFileViewer
var _mouse = {down = false, in_title = false, down_pos = null, in_handle = false}
@ -94,7 +94,7 @@ func elapsed_time_as_str():
func _process(_delta):
if _is_running:
_time = OS.get_ticks_msec() - _start_time
_time = Time.get_ticks_msec() - _start_time
_titlebar.time.set_text(str("t: ", elapsed_time_as_str()))
@ -106,9 +106,9 @@ func _draw(): # needs get_size()
var grab_line_color = Color(.4, .4, .4)
if _resize_handle.visible:
for i in range(1, 10):
var x = rect_size - Vector2(i * line_space, grab_margin)
var y = rect_size - Vector2(grab_margin, i * line_space)
draw_line(x, y, grab_line_color, 1, true)
var x = size - Vector2(i * line_space, grab_margin)
var y = size - Vector2(grab_margin, i * line_space)
draw_line(x,y,grab_line_color,1)
func _on_Maximize_draw():
@ -213,9 +213,9 @@ func _input(event):
if _mouse.in_handle:
if event is InputEventMouseMotion and _mouse.down:
var new_size = rect_size + event.position - _mouse.down_pos
var new_size = size + event.position - _mouse.down_pos
var new_mouse_down_pos = event.position
rect_size = new_size
size = new_size
_mouse.down_pos = new_mouse_down_pos
_pre_maximize_rect = get_rect()
@ -248,8 +248,8 @@ func _on_Maximize_pressed():
maximize()
else:
compact_mode(false)
rect_size = _pre_maximize_rect.size
rect_position = _pre_maximize_rect.position
size = _pre_maximize_rect.size
position = _pre_maximize_rect.position
func _on_Minimize_pressed():
@ -274,7 +274,7 @@ func _on_UserFiles_pressed():
# ####################
func _run_mode(is_running = true):
if is_running:
_start_time = OS.get_ticks_msec()
_start_time = Time.get_ticks_msec()
_time = 0.0
clear_summary()
_is_running = is_running
@ -373,7 +373,7 @@ func set_log_level(value):
func set_ignore_pause(should):
_ignore_pauses.pressed = should
_ignore_pauses.button_pressed = should
func get_ignore_pause():
@ -454,17 +454,17 @@ func clear_summary():
func maximize():
if is_inside_tree():
var vp_size_offset = get_tree().root.get_viewport().get_visible_rect().size
rect_size = vp_size_offset / get_scale()
size = vp_size_offset / get_scale()
set_position(Vector2(0, 0))
func clear_text():
_text_box.bbcode_text = ""
_text_box.text = ""
func scroll_to_bottom():
pass
#_text_box.cursor_set_line(_gui.get_text_box().get_line_count())
#_text_box.set_caret_line(_gui.get_text_box().get_line_count())
func _set_font_size_for_rtl(rtl, new_size):
@ -539,11 +539,11 @@ func compact_mode(should):
_title_replacement.visible = should
if should:
rect_min_size = min_sizes.compact
rect_size = rect_min_size
minimum_size = min_sizes.compact
size = minimum_size
else:
rect_min_size = min_sizes.full
rect_size = min_sizes.full
minimum_size = min_sizes.full
size = min_sizes.full
goto_bottom_right_corner()
@ -553,4 +553,4 @@ func set_script_path(text):
func goto_bottom_right_corner():
rect_position = get_tree().root.get_viewport().get_visible_rect().size - rect_size
position = get_tree().root.get_viewport().get_visible_rect().size - size

View file

@ -26,15 +26,15 @@ corner_radius_top_left = 20
corner_radius_top_right = 20
[node name="Gut" type="Panel"]
margin_right = 740.0
margin_bottom = 300.0
rect_min_size = Vector2( 740, 300 )
offset_right = 740.0
offset_bottom = 300.0
minimum_size = Vector2( 740, 300 )
custom_styles/panel = SubResource( 1 )
script = ExtResource( 1 )
[node name="UserFileViewer" parent="." instance=ExtResource( 6 )]
margin_top = 388.0
margin_bottom = 818.0
offset_top = 388.0
offset_bottom = 818.0
[node name="VBox" type="VBoxContainer" parent="."]
anchor_right = 1.0
@ -44,9 +44,9 @@ __meta__ = {
}
[node name="TitleBar" type="Panel" parent="VBox"]
margin_right = 740.0
margin_bottom = 30.0
rect_min_size = Vector2( 0, 30 )
offset_right = 740.0
offset_bottom = 30.0
minimum_size = Vector2( 0, 30 )
theme = SubResource( 3 )
__meta__ = {
"_edit_group_": true,
@ -61,9 +61,9 @@ __meta__ = {
}
[node name="Summary" type="Control" parent="VBox/TitleBar/HBox"]
margin_right = 110.0
margin_bottom = 30.0
rect_min_size = Vector2( 110, 0 )
offset_right = 110.0
offset_bottom = 30.0
minimum_size = Vector2( 110, 0 )
mouse_filter = 2
__meta__ = {
"_edit_use_anchors_": false
@ -71,10 +71,10 @@ __meta__ = {
[node name="Passing" type="Label" parent="VBox/TitleBar/HBox/Summary"]
visible = false
margin_left = 5.0
margin_top = 7.0
margin_right = 45.0
margin_bottom = 21.0
offset_left = 5.0
offset_top = 7.0
offset_right = 45.0
offset_bottom = 21.0
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "0"
align = 1
@ -85,20 +85,20 @@ __meta__ = {
[node name="Failing" type="Label" parent="VBox/TitleBar/HBox/Summary"]
visible = false
margin_left = 100.0
margin_top = 7.0
margin_right = 140.0
margin_bottom = 21.0
offset_left = 100.0
offset_top = 7.0
offset_right = 140.0
offset_bottom = 21.0
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "0"
align = 1
valign = 1
[node name="AssertCount" type="Label" parent="VBox/TitleBar/HBox/Summary"]
margin_left = 5.0
margin_top = 7.0
margin_right = 165.0
margin_bottom = 21.0
offset_left = 5.0
offset_top = 7.0
offset_right = 165.0
offset_bottom = 21.0
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "Assert count"
__meta__ = {
@ -107,18 +107,18 @@ __meta__ = {
[node name="TitleReplacement" type="CenterContainer" parent="VBox/TitleBar/HBox"]
visible = false
margin_left = 114.0
margin_right = 352.0
margin_bottom = 30.0
rect_min_size = Vector2( 5, 0 )
offset_left = 114.0
offset_right = 352.0
offset_bottom = 30.0
minimum_size = Vector2( 5, 0 )
mouse_filter = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Title" type="Label" parent="VBox/TitleBar/HBox"]
margin_left = 114.0
margin_right = 598.0
margin_bottom = 30.0
offset_left = 114.0
offset_right = 598.0
offset_bottom = 30.0
size_flags_horizontal = 3
size_flags_vertical = 7
custom_colors/font_color = Color( 0, 0, 0, 1 )
@ -130,10 +130,10 @@ __meta__ = {
}
[node name="Time" type="Label" parent="VBox/TitleBar/HBox"]
margin_left = 602.0
margin_top = 8.0
margin_right = 654.0
margin_bottom = 22.0
offset_left = 602.0
offset_top = 8.0
offset_right = 654.0
offset_bottom = 22.0
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "9999.99"
valign = 1
@ -142,17 +142,17 @@ __meta__ = {
}
[node name="CC" type="CenterContainer" parent="VBox/TitleBar/HBox"]
margin_left = 658.0
margin_right = 663.0
margin_bottom = 30.0
rect_min_size = Vector2( 5, 0 )
offset_left = 658.0
offset_right = 663.0
offset_bottom = 30.0
minimum_size = Vector2( 5, 0 )
mouse_filter = 2
[node name="Minimize" type="Button" parent="VBox/TitleBar/HBox"]
margin_left = 667.0
margin_right = 697.0
margin_bottom = 30.0
rect_min_size = Vector2( 30, 0 )
offset_left = 667.0
offset_right = 697.0
offset_bottom = 30.0
minimum_size = Vector2( 30, 0 )
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "N"
flat = true
@ -161,10 +161,10 @@ __meta__ = {
}
[node name="Maximize" type="Button" parent="VBox/TitleBar/HBox"]
margin_left = 701.0
margin_right = 731.0
margin_bottom = 30.0
rect_min_size = Vector2( 30, 0 )
offset_left = 701.0
offset_right = 731.0
offset_bottom = 30.0
minimum_size = Vector2( 30, 0 )
custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "X"
flat = true
@ -173,16 +173,16 @@ __meta__ = {
}
[node name="CC2" type="CenterContainer" parent="VBox/TitleBar/HBox"]
margin_left = 735.0
margin_right = 740.0
margin_bottom = 30.0
rect_min_size = Vector2( 5, 0 )
offset_left = 735.0
offset_right = 740.0
offset_bottom = 30.0
minimum_size = Vector2( 5, 0 )
mouse_filter = 2
[node name="TextDisplay" type="ColorRect" parent="VBox"]
margin_top = 34.0
margin_right = 740.0
margin_bottom = 176.0
offset_top = 34.0
offset_right = 740.0
offset_bottom = 176.0
size_flags_horizontal = 3
size_flags_vertical = 3
color = Color( 0, 0, 0, 1 )
@ -193,8 +193,8 @@ __meta__ = {
[node name="RichTextLabel" type="RichTextLabel" parent="VBox/TextDisplay"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 10.0
rect_min_size = Vector2( 0, 116 )
offset_left = 10.0
minimum_size = Vector2( 0, 116 )
focus_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
@ -209,17 +209,17 @@ __meta__ = {
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_top = -25.0
offset_top = -25.0
bbcode_enabled = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="BottomPanel" type="ColorRect" parent="VBox"]
margin_top = 180.0
margin_right = 740.0
margin_bottom = 300.0
rect_min_size = Vector2( 0, 120 )
offset_top = 180.0
offset_right = 740.0
offset_bottom = 300.0
minimum_size = Vector2( 0, 120 )
size_flags_horizontal = 9
size_flags_vertical = 9
color = Color( 1, 1, 1, 0 )
@ -232,28 +232,28 @@ __meta__ = {
}
[node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox"]
margin_right = 740.0
margin_bottom = 80.0
offset_right = 740.0
offset_bottom = 80.0
size_flags_horizontal = 3
[node name="CC1" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_right = 5.0
margin_bottom = 80.0
rect_min_size = Vector2( 5, 0 )
offset_right = 5.0
offset_bottom = 80.0
minimum_size = Vector2( 5, 0 )
[node name="Progress" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 9.0
margin_right = 179.0
margin_bottom = 80.0
rect_min_size = Vector2( 170, 0 )
offset_left = 9.0
offset_right = 179.0
offset_bottom = 80.0
minimum_size = Vector2( 170, 0 )
alignment = 1
[node name="TestProgress" type="ProgressBar" parent="VBox/BottomPanel/VBox/HBox/Progress"]
margin_top = 11.0
margin_right = 100.0
margin_bottom = 36.0
rect_min_size = Vector2( 100, 25 )
hint_tooltip = "Test progress for the current script."
offset_top = 11.0
offset_right = 100.0
offset_bottom = 36.0
minimum_size = Vector2( 100, 25 )
tooltip_text = "Test progress for the current script."
size_flags_horizontal = 0
step = 1.0
__meta__ = {
@ -261,10 +261,10 @@ __meta__ = {
}
[node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox/Progress/TestProgress"]
margin_left = 107.5
margin_top = 3.0
margin_right = 172.5
margin_bottom = 18.0
offset_left = 107.5
offset_top = 3.0
offset_right = 172.5
offset_bottom = 18.0
text = "Tests"
valign = 1
__meta__ = {
@ -283,11 +283,11 @@ __meta__ = {
}
[node name="ScriptProgress" type="ProgressBar" parent="VBox/BottomPanel/VBox/HBox/Progress"]
margin_top = 40.0
margin_right = 100.0
margin_bottom = 65.0
rect_min_size = Vector2( 100, 25 )
hint_tooltip = "Overall progress of executing tests."
offset_top = 40.0
offset_right = 100.0
offset_bottom = 65.0
minimum_size = Vector2( 100, 25 )
tooltip_text = "Overall progress of executing tests."
size_flags_horizontal = 0
step = 1.0
__meta__ = {
@ -295,10 +295,10 @@ __meta__ = {
}
[node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox/Progress/ScriptProgress"]
margin_left = 107.0
margin_top = 3.5
margin_right = 172.0
margin_bottom = 18.5
offset_left = 107.0
offset_top = 3.5
offset_right = 172.0
offset_bottom = 18.5
text = "Scripts"
valign = 1
__meta__ = {
@ -317,39 +317,39 @@ __meta__ = {
}
[node name="CenterContainer" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox/Progress"]
margin_top = 69.0
margin_right = 170.0
margin_bottom = 69.0
offset_top = 69.0
offset_right = 170.0
offset_bottom = 69.0
[node name="CC2" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 183.0
margin_right = 226.0
margin_bottom = 80.0
rect_min_size = Vector2( 5, 0 )
offset_left = 183.0
offset_right = 226.0
offset_bottom = 80.0
minimum_size = Vector2( 5, 0 )
size_flags_horizontal = 3
[node name="Navigation" type="Panel" parent="VBox/BottomPanel/VBox/HBox"]
[node name="Node3D" type="Panel" parent="VBox/BottomPanel/VBox/HBox"]
self_modulate = Color( 1, 1, 1, 0 )
margin_left = 230.0
margin_right = 580.0
margin_bottom = 80.0
rect_min_size = Vector2( 350, 80 )
offset_left = 230.0
offset_right = 580.0
offset_bottom = 80.0
minimum_size = Vector2( 350, 80 )
__meta__ = {
"_edit_group_": true,
"_edit_use_anchors_": false
}
[node name="VBox" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Navigation"]
[node name="VBox" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Node3D"]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="CurrentScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox"]
margin_right = 350.0
margin_bottom = 38.0
hint_tooltip = "Select a script to run. You can run just this script, or this script and all scripts after using the run buttons."
[node name="CurrentScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox"]
offset_right = 350.0
offset_bottom = 38.0
tooltip_text = "Select a script to run. You can run just this script, or this script and all scripts after using the run buttons."
size_flags_horizontal = 3
size_flags_vertical = 3
text = "res://test/unit/test_gut.gd"
@ -358,17 +358,17 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox"]
margin_top = 42.0
margin_right = 350.0
margin_bottom = 80.0
[node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox"]
offset_top = 42.0
offset_right = 350.0
offset_bottom = 80.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Previous" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"]
margin_right = 84.0
margin_bottom = 38.0
hint_tooltip = "Previous script in the list."
[node name="Previous" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
offset_right = 84.0
offset_bottom = 38.0
tooltip_text = "Previous script in the list."
size_flags_horizontal = 3
size_flags_vertical = 3
text = "|<"
@ -376,11 +376,11 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Next" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"]
margin_left = 88.0
margin_right = 173.0
margin_bottom = 38.0
hint_tooltip = "Next script in the list.
[node name="Next" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
offset_left = 88.0
offset_right = 173.0
offset_bottom = 38.0
tooltip_text = "Next script in the list.
"
size_flags_horizontal = 3
size_flags_vertical = 3
@ -389,11 +389,11 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Run" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"]
margin_left = 177.0
margin_right = 261.0
margin_bottom = 38.0
hint_tooltip = "Run the currently selected item and all after it."
[node name="Run" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
offset_left = 177.0
offset_right = 261.0
offset_bottom = 38.0
tooltip_text = "Run the currently selected item and all after it."
size_flags_horizontal = 3
size_flags_vertical = 3
text = ">"
@ -401,11 +401,11 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="RunSingleScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"]
margin_left = 265.0
margin_right = 350.0
margin_bottom = 38.0
hint_tooltip = "Run the currently selected item.
[node name="RunSingleScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
offset_left = 265.0
offset_right = 350.0
offset_bottom = 38.0
tooltip_text = "Run the currently selected item.
If the selected item has Inner Test Classes
then they will all be run. If the selected item
@ -418,25 +418,25 @@ __meta__ = {
}
[node name="CC3" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 584.0
margin_right = 627.0
margin_bottom = 80.0
rect_min_size = Vector2( 5, 0 )
offset_left = 584.0
offset_right = 627.0
offset_bottom = 80.0
minimum_size = Vector2( 5, 0 )
size_flags_horizontal = 3
[node name="Continue" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox"]
self_modulate = Color( 1, 1, 1, 0 )
margin_left = 631.0
margin_right = 731.0
margin_bottom = 80.0
offset_left = 631.0
offset_right = 731.0
offset_bottom = 80.0
alignment = 1
[node name="ShowExtras" type="Button" parent="VBox/BottomPanel/VBox/HBox/Continue"]
margin_right = 50.0
margin_bottom = 35.0
rect_min_size = Vector2( 50, 35 )
rect_pivot_offset = Vector2( 35, 20 )
hint_tooltip = "Show/hide additional options."
offset_right = 50.0
offset_bottom = 35.0
minimum_size = Vector2( 50, 35 )
pivot_offset = Vector2( 35, 20 )
tooltip_text = "Show/hide additional options."
size_flags_horizontal = 0
toggle_mode = true
text = "_"
@ -445,11 +445,11 @@ __meta__ = {
}
[node name="Continue" type="Button" parent="VBox/BottomPanel/VBox/HBox/Continue"]
margin_top = 39.0
margin_right = 100.0
margin_bottom = 79.0
rect_min_size = Vector2( 100, 40 )
hint_tooltip = "When a pause_before_teardown is encountered this button will be enabled and must be pressed to continue running tests."
offset_top = 39.0
offset_right = 100.0
offset_bottom = 79.0
minimum_size = Vector2( 100, 40 )
tooltip_text = "When a pause_before_teardown is encountered this button will be enabled and must be pressed to continue running tests."
disabled = true
text = "Continue"
__meta__ = {
@ -457,26 +457,26 @@ __meta__ = {
}
[node name="CC4" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 735.0
margin_right = 740.0
margin_bottom = 80.0
rect_min_size = Vector2( 5, 0 )
offset_left = 735.0
offset_right = 740.0
offset_bottom = 80.0
minimum_size = Vector2( 5, 0 )
[node name="HBox2" type="HBoxContainer" parent="VBox/BottomPanel/VBox"]
margin_top = 84.0
margin_right = 740.0
margin_bottom = 114.0
offset_top = 84.0
offset_right = 740.0
offset_bottom = 114.0
[node name="CC" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox2"]
margin_right = 5.0
margin_bottom = 30.0
rect_min_size = Vector2( 5, 0 )
offset_right = 5.0
offset_bottom = 30.0
minimum_size = Vector2( 5, 0 )
[node name="LogLevelSlider" type="HSlider" parent="VBox/BottomPanel/VBox/HBox2"]
margin_left = 9.0
margin_right = 109.0
margin_bottom = 30.0
rect_min_size = Vector2( 100, 30 )
offset_left = 9.0
offset_right = 109.0
offset_bottom = 30.0
minimum_size = Vector2( 100, 30 )
size_flags_vertical = 3
max_value = 2.0
tick_count = 3
@ -486,10 +486,10 @@ __meta__ = {
}
[node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox2/LogLevelSlider"]
margin_left = 4.0
margin_top = -17.0
margin_right = 85.0
margin_bottom = 7.0
offset_left = 4.0
offset_top = -17.0
offset_right = 85.0
offset_bottom = 7.0
text = "Log Level"
valign = 1
__meta__ = {
@ -497,16 +497,16 @@ __meta__ = {
}
[node name="CenterContainer" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox2"]
margin_left = 113.0
margin_right = 163.0
margin_bottom = 30.0
rect_min_size = Vector2( 50, 0 )
offset_left = 113.0
offset_right = 163.0
offset_bottom = 30.0
minimum_size = Vector2( 50, 0 )
[node name="CurrentScriptLabel" type="Label" parent="VBox/BottomPanel/VBox/HBox2"]
margin_left = 167.0
margin_top = 8.0
margin_right = 740.0
margin_bottom = 22.0
offset_left = 167.0
offset_top = 8.0
offset_right = 740.0
offset_bottom = 22.0
size_flags_horizontal = 3
size_flags_vertical = 6
text = "res://test/unit/test_something.gd"
@ -517,10 +517,10 @@ __meta__ = {
[node name="ScriptsList" type="ItemList" parent="."]
visible = false
anchor_bottom = 1.0
margin_left = 179.0
margin_top = 40.0
margin_right = 619.0
margin_bottom = -110.0
offset_left = 179.0
offset_top = 40.0
offset_right = 619.0
offset_bottom = -110.0
allow_reselect = true
__meta__ = {
"_edit_use_anchors_": false
@ -536,44 +536,44 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -212.0
margin_top = -260.0
margin_right = -2.0
margin_bottom = -106.0
offset_left = -212.0
offset_top = -260.0
offset_right = -2.0
offset_bottom = -106.0
custom_styles/panel = SubResource( 8 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="IgnorePause" type="CheckBox" parent="ExtraOptions"]
margin_left = 17.5
margin_top = 4.5
margin_right = 162.5
margin_bottom = 29.5
rect_scale = Vector2( 1.2, 1.2 )
hint_tooltip = "Ignore all calls to pause_before_teardown."
offset_left = 17.5
offset_top = 4.5
offset_right = 162.5
offset_bottom = 29.5
scale = Vector2( 1.2, 1.2 )
tooltip_text = "Ignore all calls to pause_before_teardown."
text = "Ignore Pauses"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Copy" type="Button" parent="ExtraOptions"]
margin_left = 15.0
margin_top = 40.0
margin_right = 195.0
margin_bottom = 80.0
hint_tooltip = "Copy all output to the clipboard."
offset_left = 15.0
offset_top = 40.0
offset_right = 195.0
offset_bottom = 80.0
tooltip_text = "Copy all output to the clipboard."
text = "Copy to Clipboard"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="UserFiles" type="Button" parent="ExtraOptions"]
margin_left = 15.0
margin_top = 90.0
margin_right = 195.0
margin_bottom = 130.0
hint_tooltip = "Copy all output to the clipboard."
offset_left = 15.0
offset_top = 90.0
offset_right = 195.0
offset_bottom = 130.0
tooltip_text = "Copy all output to the clipboard."
text = "View User Files"
__meta__ = {
"_edit_use_anchors_": false
@ -584,8 +584,8 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -40.0
margin_top = -40.0
offset_left = -40.0
offset_top = -40.0
__meta__ = {
"_edit_use_anchors_": false
}
@ -597,11 +597,11 @@ __meta__ = {
[connection signal="draw" from="VBox/TitleBar/HBox/Maximize" to="." method="_on_Maximize_draw"]
[connection signal="pressed" from="VBox/TitleBar/HBox/Maximize" to="." method="_on_Maximize_pressed"]
[connection signal="gui_input" from="VBox/TextDisplay/RichTextLabel" to="." method="_on_RichTextLabel_gui_input"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/CurrentScript" to="." method="_on_CurrentScript_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/Previous" to="." method="_on_Previous_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/Next" to="." method="_on_Next_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/Run" to="." method="_on_Run_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/RunSingleScript" to="." method="_on_RunSingleScript_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/CurrentScript" to="." method="_on_CurrentScript_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/Previous" to="." method="_on_Previous_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/Next" to="." method="_on_Next_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/Run" to="." method="_on_Run_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/RunSingleScript" to="." method="_on_RunSingleScript_pressed"]
[connection signal="draw" from="VBox/BottomPanel/VBox/HBox/Continue/ShowExtras" to="." method="_on_ShowExtras_draw"]
[connection signal="toggled" from="VBox/BottomPanel/VBox/HBox/Continue/ShowExtras" to="." method="_on_ShowExtras_toggled"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Continue/Continue" to="." method="_on_Continue_pressed"]

View file

@ -1,6 +1,6 @@
extends WindowDialog
extends Window
onready var rtl = $TextDisplay/RichTextLabel
@onready var rtl = $TextDisplay/RichTextLabel
var _has_opened_file = false

View file

@ -2,12 +2,12 @@
[ext_resource path="res://addons/gut/UserFileViewer.gd" type="Script" id=1]
[node name="UserFileViewer" type="WindowDialog"]
margin_top = 20.0
margin_right = 800.0
margin_bottom = 450.0
rect_min_size = Vector2( 800, 180 )
popup_exclusive = true
[node name="UserFileViewer" type="Window"]
offset_top = 20.0
offset_right = 800.0
offset_bottom = 450.0
minimum_size = Vector2( 800, 180 )
exclusive = true
window_title = "View File"
resizable = true
script = ExtResource( 1 )
@ -16,11 +16,11 @@ __meta__ = {
}
[node name="FileDialog" type="FileDialog" parent="."]
margin_right = 416.0
margin_bottom = 184.0
rect_min_size = Vector2( 400, 140 )
rect_scale = Vector2( 2, 2 )
popup_exclusive = true
offset_right = 416.0
offset_bottom = 184.0
minimum_size = Vector2( 400, 140 )
scale = Vector2( 2, 2 )
exclusive = true
window_title = "Open a File"
resizable = true
mode = 0
@ -35,9 +35,9 @@ __meta__ = {
[node name="TextDisplay" type="ColorRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_right = -10.0
margin_bottom = -65.0
offset_left = 8.0
offset_right = -10.0
offset_bottom = -65.0
color = Color( 0.2, 0.188235, 0.188235, 1 )
__meta__ = {
"_edit_use_anchors_": false
@ -47,7 +47,7 @@ __meta__ = {
anchor_right = 1.0
anchor_bottom = 1.0
focus_mode = 2
text = "In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used before final copy is available, but it may also be used to temporarily replace copy in a process called greeking, which allows designers to consider form without the meaning of the text influencing the design.
text = "In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying checked meaningful content. Lorem ipsum may be used before final copy is available, but it may also be used to temporarily replace copy in a process called greeking, which allows designers to consider form without the meaning of the text influencing the design.
Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a first-century BCE text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical, improper Latin.
@ -62,11 +62,11 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -158.0
margin_top = -50.0
margin_right = -84.0
margin_bottom = -30.0
rect_scale = Vector2( 2, 2 )
offset_left = -158.0
offset_top = -50.0
offset_right = -84.0
offset_bottom = -30.0
scale = Vector2( 2, 2 )
text = "Open File"
[node name="Home" type="Button" parent="."]
@ -74,11 +74,11 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -478.0
margin_top = -50.0
margin_right = -404.0
margin_bottom = -30.0
rect_scale = Vector2( 2, 2 )
offset_left = -478.0
offset_top = -50.0
offset_right = -404.0
offset_bottom = -30.0
scale = Vector2( 2, 2 )
text = "Home"
__meta__ = {
"_edit_use_anchors_": false
@ -87,11 +87,11 @@ __meta__ = {
[node name="Copy" type="Button" parent="."]
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 160.0
margin_top = -50.0
margin_right = 234.0
margin_bottom = -30.0
rect_scale = Vector2( 2, 2 )
offset_left = 160.0
offset_top = -50.0
offset_right = 234.0
offset_bottom = -30.0
scale = Vector2( 2, 2 )
text = "Copy"
__meta__ = {
"_edit_use_anchors_": false
@ -102,21 +102,21 @@ anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -318.0
margin_top = -50.0
margin_right = -244.0
margin_bottom = -30.0
rect_scale = Vector2( 2, 2 )
offset_left = -318.0
offset_top = -50.0
offset_right = -244.0
offset_bottom = -30.0
scale = Vector2( 2, 2 )
text = "End"
[node name="Close" type="Button" parent="."]
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 10.0
margin_top = -50.0
margin_right = 80.0
margin_bottom = -30.0
rect_scale = Vector2( 2, 2 )
offset_left = 10.0
offset_top = -50.0
offset_right = 80.0
offset_bottom = -30.0
scale = Vector2( 2, 2 )
text = "Close"
[connection signal="file_selected" from="FileDialog" to="." method="_on_FileDialog_file_selected"]

View file

@ -34,7 +34,7 @@ var _to_queue_free = []
func add_free(thing):
if typeof(thing) == TYPE_OBJECT:
if !thing is Reference:
if !thing is RefCounted:
_to_free.append(thing)

View file

@ -1,7 +1,23 @@
var are_equal = null setget set_are_equal, get_are_equal
var summary = null setget set_summary, get_summary
var max_differences = 30 setget set_max_differences, get_max_differences
var differences = {} setget set_differences, get_differences
var are_equal = null :
get:
return are_equal # TODOConverter40 Copy here content of get_are_equal
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_are_equal
var summary = null :
get:
return summary # TODOConverter40 Copy here content of get_summary
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_summary
var max_differences = 30 :
get:
return max_differences # TODOConverter40 Copy here content of get_max_differences
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_max_differences
var differences = {} :
get:
return differences # TODOConverter40 Copy here content of get_differences
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_differences
func _block_set(which, val):

View file

@ -74,7 +74,7 @@ func _invalidate():
differences = null
func _init(v1, v2, diff_type = DEEP):
func _init(v1,v2,diff_type = DEEP):
_value_1 = v1
_value_2 = v2
_diff_type = diff_type
@ -130,7 +130,7 @@ func _diff_dictionary(d1, d2):
if !d2.has(key):
differences[key] = _compare.simple(d1[key], _compare.MISSING, "key")
else:
d2_keys.remove(d2_keys.find(key))
d2_keys.remove_at(d2_keys.find(key))
var result = null
if _diff_type == DEEP:

View file

@ -120,7 +120,7 @@ class ObjectInfo:
var _singleton_instance = null
var _singleton_name = null
func _init(path, subpath = null):
func _init(path,subpath = null):
_path = path
if subpath != null:
_subpaths = Array(subpath.split("/"))
@ -154,7 +154,7 @@ class ObjectInfo:
return _path
func get_subpath():
return PoolStringArray(_subpaths).join("/")
return "/".join(PackedStringArray(_subpaths))
func has_subpath():
return _subpaths.size() != 0
@ -173,7 +173,7 @@ class ObjectInfo:
var inst = native_class.new()
_native_class_name = inst.get_class()
_path = _native_class_name
if !inst is Reference:
if !inst is RefCounted:
inst.free()
func get_native_class_name():
@ -195,7 +195,7 @@ class ObjectInfo:
func get_extends_text():
var extend = null
if is_singleton():
extend = str("# Double of singleton ", _singleton_name, ", base class is Reference")
extend = str("# Double of singleton ", _singleton_name, ", base class is RefCounted")
elif is_native():
var native = get_native_class_name()
if native.begins_with("_"):
@ -214,8 +214,8 @@ class ObjectInfo:
return ""
# do not include constants defined in the super class which for
# singletons stubs is Reference.
var exclude_constants = Array(ClassDB.class_get_integer_constant_list("Reference"))
# singletons stubs is RefCounted.
var exclude_constants = Array(ClassDB.class_get_integer_constant_list("RefCounted"))
var text = str("# -----\n# ", _singleton_name, " Constants\n# -----\n")
var constants = ClassDB.class_get_integer_constant_list(_singleton_name)
for c in constants:
@ -283,17 +283,17 @@ class FileOrString:
func open(path, mode):
_path = path
if _do_file:
return .open(path, mode)
return super.open(path, mode)
else:
return OK
func close():
if _do_file:
return .close()
return super.close()
func store_string(s):
if _do_file:
.store_string(s)
super.store_string(s)
_contents += s
func get_contents():
@ -326,7 +326,7 @@ class PackedSceneDouble:
_script = obj
func instance(edit_state = 0):
var inst = _scene.instance(edit_state)
var inst = _scene.instantiate(edit_state)
if _script != null:
inst.set_script(_script)
return inst
@ -462,7 +462,7 @@ func _double_scene_and_script(scene_info):
var to_return = PackedSceneDouble.new()
to_return.load_scene(scene_info.get_path())
var inst = load(scene_info.get_path()).instance()
var inst = load(scene_info.get_path()).instantiate()
var script_path = null
if inst.get_script():
script_path = inst.get_script().get_path()
@ -484,7 +484,7 @@ func _get_methods(object_info):
var script_methods = ScriptMethods.new()
var methods = obj.get_method_list()
if !object_info.is_singleton() and !(obj is Reference):
if !object_info.is_singleton() and !(obj is RefCounted):
obj.free()
# first pass is for local methods only
@ -723,13 +723,13 @@ func clear_output_directory():
var d = Directory.new()
var result = d.open(_output_dir)
# BIG GOTCHA HERE. If it cannot open the dir w/ erro 31, then the
# directory becomes res:// and things go on normally and gut clears out
# directory becomes res:// and things go checked normally and gut clears out
# out res:// which is SUPER BAD.
if result == OK:
d.list_dir_begin(true)
d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
var f = d.get_next()
while f != "":
d.remove(f)
d.remove_at(f)
f = d.get_next()
did = true
return did
@ -739,7 +739,7 @@ func delete_output_directory():
var did = clear_output_directory()
if did:
var d = Directory.new()
d.remove(_output_dir)
d.remove_at(_output_dir)
func add_ignored_method(path, method_name):

View file

@ -16,7 +16,7 @@ var _wrote_results = false
# play_custom_scene
var _cmdln_mode = false
onready var _gut_layer = $GutLayer
@onready var _gut_layer = $GutLayer
func _ready():
@ -24,8 +24,8 @@ func _ready():
_gut_config = GutConfig.new()
_gut_config.load_options(RUNNER_JSON_PATH)
# The command line will call run_tests on its own. When used from the panel
# we have to kick off the tests ourselves b/c there's no way I know of to
# The command line will call run_tests checked its own. When used from the panel
# we have to kick unchecked the tests ourselves b/c there's no way I know of to
# interact with the scene that was run via play_custom_scene.
if !_cmdln_mode:
call_deferred("run_tests")
@ -58,7 +58,7 @@ func run_tests():
func _write_results():
# bbcode_text appears to be empty. I'm not 100% sure why. Until that is
# text appears to be empty. I'm not 100% sure why. Until that is
# figured out we have to just get the text which stinks.
var content = _gut.get_gui().get_text_box().text

View file

@ -35,23 +35,71 @@ extends Control
var _select_script = ""
var _tests_like = ""
var _inner_class_name = ""
var _should_maximize = false setget set_should_maximize, get_should_maximize
var _log_level = 1 setget set_log_level, get_log_level
var _disable_strict_datatype_checks = false setget disable_strict_datatype_checks, is_strict_datatype_checks_disabled
var _should_maximize = false :
get:
return _should_maximize # TODOConverter40 Copy here content of get_should_maximize
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_should_maximize
var _log_level = 1 :
get:
return _log_level # TODOConverter40 Copy here content of get_log_level
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_log_level
var _disable_strict_datatype_checks = false :
get:
return _disable_strict_datatype_checks # TODOConverter40 Copy here content of is_strict_datatype_checks_disabled
set(mod_value):
mod_value # TODOConverter40 Copy here content of disable_strict_datatype_checks
var _test_prefix = "test_"
var _file_prefix = "test_"
var _file_extension = ".gd"
var _inner_class_prefix = "Test"
var _temp_directory = "user://gut_temp_directory"
var _export_path = "" setget set_export_path, get_export_path
var _include_subdirectories = false setget set_include_subdirectories, get_include_subdirectories
var _double_strategy = 1 setget set_double_strategy, get_double_strategy
var _pre_run_script = "" setget set_pre_run_script, get_pre_run_script
var _post_run_script = "" setget set_post_run_script, get_post_run_script
var _color_output = false setget set_color_output, get_color_output
var _junit_xml_file = "" setget set_junit_xml_file, get_junit_xml_file
var _junit_xml_timestamp = false setget set_junit_xml_timestamp, get_junit_xml_timestamp
var _add_children_to = self setget set_add_children_to, get_add_children_to
var _export_path = "" :
get:
return _export_path # TODOConverter40 Copy here content of get_export_path
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_export_path
var _include_subdirectories = false :
get:
return _include_subdirectories # TODOConverter40 Copy here content of get_include_subdirectories
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_include_subdirectories
var _double_strategy = 1 :
get:
return _double_strategy # TODOConverter40 Copy here content of get_double_strategy
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_double_strategy
var _pre_run_script = "" :
get:
return _pre_run_script # TODOConverter40 Copy here content of get_pre_run_script
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_pre_run_script
var _post_run_script = "" :
get:
return _post_run_script # TODOConverter40 Copy here content of get_post_run_script
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_post_run_script
var _color_output = false :
get:
return _color_output # TODOConverter40 Copy here content of get_color_output
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_color_output
var _junit_xml_file = "" :
get:
return _junit_xml_file # TODOConverter40 Copy here content of get_junit_xml_file
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_junit_xml_file
var _junit_xml_timestamp = false :
get:
return _junit_xml_timestamp # TODOConverter40 Copy here content of get_junit_xml_timestamp
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_junit_xml_timestamp
var _add_children_to = self :
get:
return _add_children_to # TODOConverter40 Copy here content of get_add_children_to
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_add_children_to
# -- End Settings --
# ###########################
@ -135,14 +183,14 @@ const SIGNAL_STOP_YIELD_BEFORE_TEARDOWN = "stop_yield_before_teardown"
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
var _should_print_versions = true # used to cut down on output in tests.
var _should_print_versions = true # used to cut down checked output in tests.
func _init():
_before_all_test_obj.name = "before_all"
_after_all_test_obj.name = "after_all"
# When running tests for GUT itself, _utils has been setup to always return
# a new logger so this does not set the gut instance on the base logger
# a new logger so this does not set the gut instance checked the base logger
# when creating test instances of GUT.
_lgr.set_gut(self)
@ -156,13 +204,13 @@ func _init():
_doubler.set_spy(_spy)
_doubler.set_gut(self)
# TODO remove these, universal logger should fix this.
# TODO remove_at these, universal logger should fix this.
_doubler.set_logger(_lgr)
_spy.set_logger(_lgr)
_stubber.set_logger(_lgr)
_test_collector.set_logger(_lgr)
_gui = load("res://addons/gut/GutScene.tscn").instance()
_gui = load("res://addons/gut/GutScene.tscn").instantiate()
func _physics_process(delta):
@ -198,7 +246,7 @@ func _ready():
add_child(_yield_timer)
_yield_timer.set_one_shot(true)
_yield_timer.connect("timeout", self, "_yielding_callback")
_yield_timer.connect("timeout",Callable(self,"_yielding_callback"))
_setup_gui()
@ -255,16 +303,16 @@ func _setup_gui():
# This is how we get the size of the control to translate to the gui when
# the scene is run. This is also another reason why the min_rect_size
# must match between both gut and the gui.
_gui.rect_size = self.rect_size
_gui.size = self.size
add_child(_gui)
_gui.set_anchor(MARGIN_RIGHT, ANCHOR_END)
_gui.set_anchor(MARGIN_BOTTOM, ANCHOR_END)
_gui.connect("run_single_script", self, "_on_run_one")
_gui.connect("run_script", self, "_on_new_gui_run_script")
_gui.connect("end_pause", self, "_on_new_gui_end_pause")
_gui.connect("ignore_pause", self, "_on_new_gui_ignore_pause")
_gui.connect("log_level_changed", self, "_on_log_level_changed")
var _foo = connect("tests_finished", _gui, "end_run")
_gui.connect("run_single_script",Callable(self,"_on_run_one"))
_gui.connect("run_script",Callable(self,"_on_new_gui_run_script"))
_gui.connect("end_pause",Callable(self,"_on_new_gui_end_pause"))
_gui.connect("ignore_pause",Callable(self,"_on_new_gui_ignore_pause"))
_gui.connect("log_level_changed",Callable(self,"_on_log_level_changed"))
var _foo = connect("tests_finished",Callable(_gui,"end_run"))
func _add_scripts_to_gui():
@ -321,8 +369,8 @@ func _on_log_level_changed(value):
# with set_yield_time()
#
# signal_watcher._on_watched_signal supports up to 9 additional arguments.
# This is the most number of parameters GUT supports on signals. The comment
# on _on_watched_signal explains reasoning.
# This is the most number of parameters GUT supports checked signals. The comment
# checked _on_watched_signal explains reasoning.
# ------------------------------------------------------------------------------
func _yielding_callback(
from_obj = false,
@ -521,7 +569,7 @@ func _end_run():
# then move the cursor. I found this workaround through trial and error.
_yield_between.timer.set_wait_time(0.1)
_yield_between.timer.start()
yield(_yield_between.timer, "timeout")
await _yield_between.timer.timeout
_gui.scroll_to_bottom()
_is_running = false
@ -554,7 +602,7 @@ func _export_junit_xml():
if _junit_xml_timestamp:
var ext = "." + output_file.get_extension()
output_file = output_file.replace(ext, str("_", OS.get_unix_time(), ext))
output_file = output_file.replace(ext, str("_", Time.get_unix_time_from_system(), ext))
var f_result = exporter.write_file(self, output_file)
if f_result == OK:
@ -592,7 +640,7 @@ func _print_script_heading(script):
# ------------------------------------------------------------------------------
# Just gets more logic out of _test_the_scripts. Decides if we should yield after
# this test based on flags and counters.
# this test based checked flags and counters.
# ------------------------------------------------------------------------------
func _should_yield_now():
var should = (
@ -639,7 +687,7 @@ func _wait_for_done(result):
var print_after = 3
# callback method sets waiting to false.
result.connect(COMPLETED, self, "_on_test_script_yield_completed")
result.connect(COMPLETED,Callable(self,"_on_test_script_yield_completed"))
if !_was_yield_method_called:
_lgr.log("-- Yield detected, waiting --", _lgr.fmts.yellow)
@ -652,7 +700,7 @@ func _wait_for_done(result):
iter_counter += 1
_lgr.yield_text("waiting" + dots)
_wait_timer.start()
yield(_wait_timer, "timeout")
await _wait_timer.timeout
dots += "."
if dots.length() > 5:
dots = ""
@ -690,7 +738,7 @@ func _call_deprecated_script_method(script, method, alt):
func _get_indexes_matching_script_name(name):
var indexes = [] # empty runs all
for i in range(_test_collector.scripts.size()):
if _test_collector.scripts[i].get_filename().find(name) != -1:
if _test_collector.scripts[i].get_scene_file_path().find(name) != -1:
indexes.append(i)
return indexes
@ -714,8 +762,8 @@ func _run_parameterized_test(test_script, test_name):
_lgr.warn("Test did not assert")
if _is_function_state(script_result):
# _run_tests does _wait_for_done so just wait on it to complete
yield(script_result, COMPLETED)
# _run_tests does _wait_for_done so just wait checked it to complete
await script_result.COMPLETED
if _parameter_handler == null:
_lgr.error(
@ -737,8 +785,8 @@ func _run_parameterized_test(test_script, test_name):
var cur_assert_count = _current_test.assert_count
script_result = _run_test(test_script, test_name)
if _is_function_state(script_result):
# _run_tests does _wait_for_done so just wait on it to complete
yield(script_result, COMPLETED)
# _run_tests does _wait_for_done so just wait checked it to complete
await script_result.COMPLETED
if _current_test.assert_count == cur_assert_count and !_current_test.pending:
_lgr.warn("Test did not assert")
@ -758,7 +806,7 @@ func _run_test(script_inst, test_name):
_call_deprecated_script_method(script_inst, "setup", "before_each")
var before_each_result = script_inst.before_each()
if _is_function_state(before_each_result):
yield(_wait_for_done(before_each_result), COMPLETED)
await _wait_for_done(before_each_result).COMPLETED
# When the script yields it will return a GDScriptFunctionState object
script_result = script_inst.call(test_name)
@ -770,13 +818,13 @@ func _run_test(script_inst, test_name):
# possible since we only know what the yield was for except when yield_for
# and yield_to are used.
if _is_function_state(script_result):
yield(_wait_for_done(script_result), COMPLETED)
await _wait_for_done(script_result).COMPLETED
# if the test called pause_before_teardown then yield until
# the continue button is pressed.
if _pause_before_teardown and !_ignore_pause_before_teardown:
_gui.pause()
yield(_wait_for_continue_button(), SIGNAL_STOP_YIELD_BEFORE_TEARDOWN)
await _wait_for_continue_button().SIGNAL_STOP_YIELD_BEFORE_TEARDOWN
script_inst.clear_signal_watcher()
@ -784,7 +832,7 @@ func _run_test(script_inst, test_name):
_call_deprecated_script_method(script_inst, "teardown", "after_each")
var after_each_result = script_inst.after_each()
if _is_function_state(after_each_result):
yield(_wait_for_done(after_each_result), COMPLETED)
await _wait_for_done(after_each_result).COMPLETED
# Free up everything in the _autofree. Yield for a bit if we
# have anything with a queue_free so that they have time to
@ -792,7 +840,7 @@ func _run_test(script_inst, test_name):
var aqf_count = _autofree.get_queue_free_count()
_autofree.free_all()
if aqf_count > 0:
yield(_do_yield_between(), "timeout")
await _do_yield_between().timeout
test_summary.orphans = _orphan_counter.get_counter("test")
if _log_level > 0:
@ -802,7 +850,7 @@ func _run_test(script_inst, test_name):
# ------------------------------------------------------------------------------
# Calls after_all on the passed in test script and takes care of settings so all
# Calls after_all checked the passed in test script and takes care of settings so all
# logger output appears indented and with a proper heading
#
# Calls both pre-all-tests methods until prerun_setup is removed
@ -819,14 +867,14 @@ func _call_before_all(test_script):
var result = test_script.before_all()
if _is_function_state(result):
yield(_wait_for_done(result), COMPLETED)
await _wait_for_done(result).COMPLETED
_lgr.dec_indent()
_current_test = null
# ------------------------------------------------------------------------------
# Calls after_all on the passed in test script and takes care of settings so all
# Calls after_all checked the passed in test script and takes care of settings so all
# logger output appears indented and with a proper heading
#
# Calls both post-all-tests methods until postrun_teardown is removed.
@ -843,7 +891,7 @@ func _call_after_all(test_script):
var result = test_script.after_all()
if _is_function_state(result):
yield(_wait_for_done(result), COMPLETED)
await _wait_for_done(result).COMPLETED
_lgr.dec_indent()
_current_test = null
@ -902,7 +950,7 @@ func _test_the_scripts(indexes = []):
# yield between test scripts so things paint
if _yield_between.should:
yield(_do_yield_between(), "timeout")
await _do_yield_between().timeout
# !!!
# Hack so there isn't another indent to this monster of a method. if
@ -915,7 +963,7 @@ func _test_the_scripts(indexes = []):
var before_all_result = _call_before_all(test_script)
if _is_function_state(before_all_result):
# _call_before_all calls _wait for done, just wait for that to finish
yield(before_all_result, COMPLETED)
await before_all_result.COMPLETED
_gui.set_progress_test_max(the_script.tests.size()) # New way
@ -933,7 +981,7 @@ func _test_the_scripts(indexes = []):
):
# yield so things paint
if _should_yield_now():
yield(_do_yield_between(), "timeout")
await _do_yield_between().timeout
if _current_test.arg_count > 1:
_lgr.error(
@ -952,7 +1000,7 @@ func _test_the_scripts(indexes = []):
if _is_function_state(script_result):
# _run_test calls _wait for done, just wait for that to finish
yield(script_result, COMPLETED)
await script_result.COMPLETED
if _current_test.assert_count == 0 and !_current_test.pending:
_lgr.warn("Test did not assert")
@ -968,13 +1016,13 @@ func _test_the_scripts(indexes = []):
var after_all_result = _call_after_all(test_script)
if _is_function_state(after_all_result):
# _call_after_all calls _wait for done, just wait for that to finish
yield(after_all_result, COMPLETED)
await after_all_result.COMPLETED
_log_test_children_warning(test_script)
# This might end up being very resource intensive if the scripts
# don't clean up after themselves. Might have to consolidate output
# into some other structure and kill the script objects with
# test_script.free() instead of remove child.
# test_script.free() instead of remove_at child.
_add_children_to.remove_child(test_script)
_lgr.set_indent_level(0)
@ -1061,7 +1109,7 @@ func _get_files(path, prefix, suffix):
var d = Directory.new()
d.open(path)
# true parameter tells list_dir_begin not to include "." and ".." directories.
d.list_dir_begin(true)
d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
# Traversing a directory is kinda odd. You have to start the process of listing
# the contents of a directory with list_dir_begin then use get_next until it
@ -1098,7 +1146,7 @@ func _get_files(path, prefix, suffix):
# ------------------------------------------------------------------------------
# Conditionally prints the text to the console/results variable based on the
# Conditionally prints the text to the console/results variable based checked the
# current log level and what level is passed in. Whenever currently in a test,
# the text will be indented under the test. It can be further indented if
# desired.
@ -1287,7 +1335,7 @@ func is_strict_datatype_checks_disabled():
# you want to watch a test play out onscreen or inspect results.
# ------------------------------------------------------------------------------
func end_yielded_test():
_lgr.deprecated("end_yielded_test is no longer necessary, you can remove it.")
_lgr.deprecated("end_yielded_test is no longer necessary, you can remove_at it.")
# ------------------------------------------------------------------------------
@ -1385,7 +1433,7 @@ func pause_before_teardown():
# ------------------------------------------------------------------------------
# For batch processing purposes, you may want to ignore any calls to
# pause_before_teardown that you forgot to remove.
# pause_before_teardown that you forgot to remove_at.
# ------------------------------------------------------------------------------
func set_ignore_pause_before_teardown(should_ignore):
_ignore_pause_before_teardown = should_ignore
@ -1413,7 +1461,7 @@ func get_yield_between_tests():
# ------------------------------------------------------------------------------
# Call _process or _fixed_process, if they exist, on obj and all it's children
# Call _process or _fixed_process, if they exist, checked obj and all it's children
# and their children and so and so forth. Delta will be passed through to all
# the _process or _fixed_process methods.
# ------------------------------------------------------------------------------
@ -1431,10 +1479,10 @@ func simulate(obj, times, delta):
# ------------------------------------------------------------------------------
# Starts an internal timer with a timeout of the passed in time. A 'timeout'
# signal will be sent when the timer ends. Returns itself so that it can be
# used in a call to yield...cutting down on lines of code.
# used in a call to yield...cutting down checked lines of code.
#
# Example, yield to the Gut object for 10 seconds:
# yield(gut.set_yield_time(10), 'timeout')
# await gut.set_yield_time(10).timeout
# ------------------------------------------------------------------------------
func set_yield_time(time, text = ""):
_yield_timer.set_wait_time(time)
@ -1474,7 +1522,7 @@ func set_yield_frames(frames, text = ""):
# number of seconds, whichever comes first.
# ------------------------------------------------------------------------------
func set_yield_signal_or_time(obj, signal_name, max_wait, text = ""):
obj.connect(signal_name, self, "_yielding_callback", [true])
obj.connect(signal_name,Callable(self,"_yielding_callback").bind(true))
_yielding_to.obj = obj
_yielding_to.signal_name = signal_name
@ -1518,7 +1566,7 @@ func file_delete(path):
var d = Directory.new()
var result = d.open(path.get_base_dir())
if result == OK:
d.remove(path)
d.remove_at(path)
# ------------------------------------------------------------------------------
@ -1527,7 +1575,7 @@ func file_delete(path):
func is_file_empty(path):
var f = File.new()
f.open(path, f.READ)
var empty = f.get_len() == 0
var empty = f.get_length() == 0
f.close()
return empty
@ -1552,14 +1600,14 @@ func directory_delete_files(path):
# Traversing a directory is kinda odd. You have to start the process of listing
# the contents of a directory with list_dir_begin then use get_next until it
# returns an empty string. Then I guess you should end it.
d.list_dir_begin()
d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
var thing = d.get_next() # could be a dir or a file or something else maybe?
var full_path = ""
while thing != "":
full_path = path + "/" + thing
#file_exists returns fasle for directories
if d.file_exists(full_path):
d.remove(full_path)
d.remove_at(full_path)
thing = d.get_next()
d.list_dir_end()

View file

@ -122,7 +122,7 @@ class OptionResolver:
# ------------------------------------------------------------------------------
# Here starts the actual script that uses the Options class to kick off Gut
# Here starts the actual script that uses the Options class to kick unchecked Gut
# and run your tests.
# ------------------------------------------------------------------------------
var _utils = load("res://addons/gut/utils.gd").get_instance()
@ -284,24 +284,24 @@ func _print_gutconfigs(values):
var header = """Here is a sample of a full .gutconfig.json file.
You do not need to specify all values in your own file. The values supplied in
this sample are what would be used if you ran gut w/o the -gprint_gutconfig_sample
option (option priority: command-line, .gutconfig, default)."""
option (option priority: command-line, super.gutconfig, default)."""
print("\n", header.replace("\n", " "), "\n\n")
var resolved = values
# remove some options that don't make sense to be in config
# remove_at some options that don't make sense to be in config
resolved.erase("config_file")
resolved.erase("show_help")
print(
"Here's a config with all the properties set based off of your current command and config."
"Here's a config with all the properties set based unchecked of your current command and config."
)
print(JSON.print(resolved, " "))
print(JSON.stringify(resolved, " "))
for key in resolved:
resolved[key] = null
print("\n\nAnd here's an empty config for you fill in what you want.")
print(JSON.print(resolved, " "))
print(JSON.stringify(resolved, " "))
# parse options and run Gut
@ -332,7 +332,7 @@ func _run_gut():
(
"All command line options and where they are specified. "
+ 'The "final" value shows which value will actually be used '
+ "based on order of precedence (default < .gutconfig < cmd line)."
+ "based checked order of precedence (default < super.gutconfig < cmd line)."
+ "\n"
)
)
@ -345,7 +345,7 @@ func _run_gut():
_final_opts = opt_resolver.get_resolved_values()
_gut_config.options = _final_opts
var runner = GutRunner.instance()
var runner = GutRunner.instantiate()
runner.set_cmdln_mode(true)
runner.set_gut_config(_gut_config)

View file

@ -2,7 +2,7 @@ var Gut = load("res://addons/gut/gut.gd")
# Do not want a ref to _utils here due to use by editor plugin.
# _utils needs to be split so that constants and what not do not
# have to rely on the weird singleton thing I made.
# have to rely checked the weird singleton thing I made.
enum DOUBLE_STRATEGY { FULL, PARTIAL }
var valid_fonts = ["AnonymousPro", "CourierPro", "LobsterTwo", "Default"]
@ -68,7 +68,9 @@ func _load_options_from_config_file(file_path, into):
var json = f.get_as_text()
f.close()
var results = JSON.parse(json)
var test_json_conv = JSON.new()
test_json_conv.parse(json)
var results = test_json_conv.get_data()
# SHORTCIRCUIT
if results.error != OK:
print("\n\n", "!! ERROR parsing file: ", file_path)
@ -87,7 +89,7 @@ func _load_options_from_config_file(file_path, into):
func write_options(path):
var content = JSON.print(options, " ")
var content = JSON.stringify(options, " ")
var f = File.new()
var result = f.open(path, f.WRITE)

View file

@ -48,7 +48,7 @@
static func _to_scancode(which):
var key_code = which
if typeof(key_code) == TYPE_STRING:
key_code = key_code.to_upper().to_ascii()[0]
key_code = key_code.to_upper().to_ascii_buffer()[0]
return key_code
@ -57,7 +57,7 @@ static func new_mouse_button_event(position, global_position, pressed, button_in
event.position = position
if global_position != null:
event.global_position = global_position
event.pressed = pressed
event.button_pressed = pressed
event.button_index = button_index
return event
@ -66,14 +66,14 @@ static func new_mouse_button_event(position, global_position, pressed, button_in
static func key_up(which):
var event = InputEventKey.new()
event.scancode = _to_scancode(which)
event.pressed = false
event.button_pressed = false
return event
static func key_down(which):
var event = InputEventKey.new()
event.scancode = _to_scancode(which)
event.pressed = true
event.button_pressed = true
return event
@ -88,33 +88,33 @@ static func action_down(which, strength = 1.0):
var event = InputEventAction.new()
event.action = which
event.strength = strength
event.pressed = true
event.button_pressed = true
return event
static func mouse_left_button_down(position, global_position = null):
var event = new_mouse_button_event(position, global_position, true, BUTTON_LEFT)
var event = new_mouse_button_event(position, global_position, true, MOUSE_BUTTON_LEFT)
return event
static func mouse_left_button_up(position, global_position = null):
var event = new_mouse_button_event(position, global_position, false, BUTTON_LEFT)
var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_LEFT)
return event
static func mouse_double_click(position, global_position = null):
var event = new_mouse_button_event(position, global_position, false, BUTTON_LEFT)
var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_LEFT)
event.doubleclick = true
return event
static func mouse_right_button_down(position, global_position = null):
var event = new_mouse_button_event(position, global_position, true, BUTTON_RIGHT)
var event = new_mouse_button_event(position, global_position, true, MOUSE_BUTTON_RIGHT)
return event
static func mouse_right_button_up(position, global_position = null):
var event = new_mouse_button_event(position, global_position, false, BUTTON_RIGHT)
var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_RIGHT)
return event

View file

@ -71,7 +71,7 @@ class InputQueueItem:
if _waited_frames >= frame_delay:
emit_signal("event_ready")
func _init(t_delay, f_delay):
func _init(t_delay,f_delay):
time_delay = t_delay
frame_delay = f_delay
_is_ready = time_delay == 0 and frame_delay == 0
@ -90,7 +90,7 @@ class InputQueueItem:
_delay_started = true
if time_delay > 0:
var t = _delay_timer(time_delay)
t.connect("timeout", self, "_on_time_timeout")
t.connect("timeout",Callable(self,"_on_time_timeout"))
# ##############################################################################
@ -99,7 +99,7 @@ class InputQueueItem:
var _utils = load("res://addons/gut/utils.gd").get_instance()
var InputFactory = load("res://addons/gut/input_factory.gd")
const INPUT_WARN = "If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use .hold_for(...) to automatically release after some duration."
const INPUT_WARN = "If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use super.hold_for(...) to automatically release after some duration."
var _lgr = _utils.get_logger()
var _receivers = []
@ -197,7 +197,7 @@ func _on_queue_item_ready(item):
func _add_queue_item(item):
item.connect("event_ready", self, "_on_queue_item_ready", [item])
item.connect("event_ready",Callable(self,"_on_queue_item_ready").bind(item))
_next_queue_item = item
_input_queue.append(item)
Engine.get_main_loop().root.add_child(item)
@ -344,7 +344,7 @@ func release_all():
for key in _pressed_mouse_buttons:
var event = _pressed_mouse_buttons[key].duplicate()
if event.pressed:
event.pressed = false
event.button_pressed = false
_send_event(event)
_pressed_mouse_buttons.clear()
@ -352,7 +352,7 @@ func release_all():
func hold_for(duration):
if _last_event != null and _last_event.pressed:
var next_event = _last_event.duplicate()
next_event.pressed = false
next_event.button_pressed = false
wait(duration)
send_event(next_event)
return self

View file

@ -90,7 +90,7 @@ func _init():
_printers.console = _utils.Printers.ConsolePrinter.new()
# There were some problems in the timing of disabling this at the right
# time in gut_cmdln so it is disabled by default. This is enabled
# by plugin_control.gd based on settings.
# by plugin_control.gd based checked settings.
_printers.console.set_disabled(true)

View file

@ -2,13 +2,13 @@ class CallParameters:
var p_name = null
var default = null
func _init(n, d):
func _init(n,d):
p_name = n
default = d
# ------------------------------------------------------------------------------
# This class will generate method declaration lines based on method meta
# This class will generate method declaration lines based checked method meta
# data. It will create defaults that match the method data.
#
# --------------------
@ -43,7 +43,7 @@ const PARAM_PREFIX = "p_"
# TYPE_NIL = 0 — Variable is of type nil (only applied for null).
# TYPE_BOOL = 1 — Variable is of type bool.
# TYPE_INT = 2 — Variable is of type int.
# TYPE_REAL = 3 — Variable is of type float/real.
# TYPE_FLOAT = 3 — Variable is of type float/real.
# TYPE_STRING = 4 — Variable is of type String.
# TYPE_VECTOR2 = 5 — Variable is of type Vector2.
# TYPE_RECT2 = 6 — Variable is of type Rect2.
@ -52,22 +52,22 @@ const PARAM_PREFIX = "p_"
# TYPE_OBJECT = 17 — Variable is of type Object.
# TYPE_DICTIONARY = 18 — Variable is of type Dictionary.
# TYPE_ARRAY = 19 — Variable is of type Array.
# TYPE_VECTOR2_ARRAY = 24 — Variable is of type PoolVector2Array.
# TYPE_TRANSFORM = 13 — Variable is of type Transform.
# TYPE_PACKED_VECTOR2_ARRAY = 24 — Variable is of type PackedVector2Array.
# TYPE_TRANSFORM3D = 13 — Variable is of type Transform3D.
# TYPE_TRANSFORM2D = 8 — Variable is of type Transform2D.
# TYPE_RID = 16 — Variable is of type RID.
# TYPE_INT_ARRAY = 21 — Variable is of type PoolIntArray.
# TYPE_REAL_ARRAY = 22 — Variable is of type PoolRealArray.
# TYPE_PACKED_INT32_ARRAY = 21 — Variable is of type PackedInt32Array.
# TYPE_PACKED_FLOAT32_ARRAY = 22 — Variable is of type PackedFloat32Array.
# TYPE_PLANE = 9 — Variable is of type Plane.
# TYPE_QUAT = 10 — Variable is of type Quat.
# TYPE_QUATERNION = 10 — Variable is of type Quaternion.
# TYPE_AABB = 11 — Variable is of type AABB.
# TYPE_BASIS = 12 — Variable is of type Basis.
# TYPE_NODE_PATH = 15 — Variable is of type NodePath.
# TYPE_RAW_ARRAY = 20 — Variable is of type PoolByteArray.
# TYPE_STRING_ARRAY = 23 — Variable is of type PoolStringArray.
# TYPE_VECTOR3_ARRAY = 25 — Variable is of type PoolVector3Array.
# TYPE_COLOR_ARRAY = 26 — Variable is of type PoolColorArray.
# TYPE_PACKED_BYTE_ARRAY = 20 — Variable is of type PackedByteArray.
# TYPE_PACKED_STRING_ARRAY = 23 — Variable is of type PackedStringArray.
# TYPE_PACKED_VECTOR3_ARRAY = 25 — Variable is of type PackedVector3Array.
# TYPE_PACKED_COLOR_ARRAY = 26 — Variable is of type PackedColorArray.
# TYPE_MAX = 27 — Marker for end of type constants.
# ------------------------------------------------------
var _supported_defaults = []
@ -81,12 +81,12 @@ func _init():
_supported_defaults[TYPE_NIL] = ""
_supported_defaults[TYPE_BOOL] = ""
_supported_defaults[TYPE_INT] = ""
_supported_defaults[TYPE_REAL] = ""
_supported_defaults[TYPE_FLOAT] = ""
_supported_defaults[TYPE_OBJECT] = ""
_supported_defaults[TYPE_ARRAY] = ""
_supported_defaults[TYPE_STRING] = ""
_supported_defaults[TYPE_DICTIONARY] = ""
_supported_defaults[TYPE_VECTOR2_ARRAY] = ""
_supported_defaults[TYPE_PACKED_VECTOR2_ARRAY] = ""
_supported_defaults[TYPE_RID] = ""
# These require a prefix for whatever default is provided
@ -95,9 +95,9 @@ func _init():
_supported_defaults[TYPE_VECTOR3] = "Vector3"
_supported_defaults[TYPE_COLOR] = "Color"
_supported_defaults[TYPE_TRANSFORM2D] = "Transform2D"
_supported_defaults[TYPE_TRANSFORM] = "Transform"
_supported_defaults[TYPE_INT_ARRAY] = "PoolIntArray"
_supported_defaults[TYPE_REAL_ARRAY] = "PoolRealArray"
_supported_defaults[TYPE_TRANSFORM3D] = "Transform3D"
_supported_defaults[TYPE_PACKED_INT32_ARRAY] = "PackedInt32Array"
_supported_defaults[TYPE_PACKED_FLOAT32_ARRAY] = "PackedFloat32Array"
# ###############
@ -146,7 +146,7 @@ func _make_arg_array(method_meta, override_size):
_supported_defaults[t],
str(method_meta.default_args[dflt_idx]).to_lower()
)
elif t == TYPE_TRANSFORM:
elif t == TYPE_TRANSFORM3D:
#value will be 4 Vector3 and look like: 1, 0, 0, 0, 1, 0, 0, 0, 1 - 0, 0, 0
var sections = str(method_meta.default_args[dflt_idx]).split("-")
var vecs = sections[0].split(",")
@ -167,7 +167,7 @@ func _make_arg_array(method_meta, override_size):
dflt_text = str(_supported_defaults[t], "(", vectors, ")")
elif t == TYPE_RID:
dflt_text = str(_supported_defaults[t], "null")
elif t in [TYPE_REAL_ARRAY, TYPE_INT_ARRAY]:
elif t in [TYPE_PACKED_FLOAT32_ARRAY, TYPE_PACKED_INT32_ARRAY]:
dflt_text = str(_supported_defaults[t], "()")
# Everything else puts the prefix (if one is there) form _supported_defaults
@ -253,7 +253,7 @@ func _get_spy_call_parameters_text(args):
# ###############
# Creates a delceration for a function based off of function metadata. All
# Creates a delceration for a function based unchecked of function metadata. All
# types whose defaults are supported will have their values. If a datatype
# is not supported and the parameter has a default, a warning message will be
# printed and the declaration will return null.

View file

@ -40,7 +40,7 @@
#-------------------------------------------------------------------------------
# Parses the command line arguments supplied into an array that can then be
# examined and parsed based on how the gut options work.
# examined and parsed based checked how the gut options work.
#-------------------------------------------------------------------------------
class CmdLineParser:
var _used_options = []
@ -94,7 +94,7 @@ class CmdLineParser:
var opt_loc = find_option(option)
if opt_loc != -1:
to_return = _parse_array_value(_opts[opt_loc])
_opts.remove(opt_loc)
_opts.remove_at(opt_loc)
return to_return
@ -107,7 +107,7 @@ class CmdLineParser:
var opt_loc = find_option(option)
if opt_loc != -1:
to_return = _parse_option_value(_opts[opt_loc])
_opts.remove(opt_loc)
_opts.remove_at(opt_loc)
return to_return
@ -128,14 +128,14 @@ class CmdLineParser:
var script_option = to_return.find("-s")
if script_option != -1:
to_return.remove(script_option + 1)
to_return.remove(script_option)
to_return.remove_at(script_option + 1)
to_return.remove_at(script_option)
while _used_options.size() > 0:
var index = to_return.find(_used_options[0].split("=")[0])
if index != -1:
to_return.remove(index)
_used_options.remove(0)
to_return.remove_at(index)
_used_options.remove_at(0)
return to_return
@ -149,7 +149,7 @@ class Option:
var default = null
var description = ""
func _init(name, default_value, desc = ""):
func _init(name,default_value,desc = ""):
option_name = name
default = default_value
description = desc

View file

@ -30,84 +30,84 @@
# through the editor and delays the creation of the GUT instance until
# Engine.get_main_loop() works as expected.
# ##############################################################################
tool
@tool
extends Control
# ------------------------------------------------------------------------------
# GUT Settings
# ------------------------------------------------------------------------------
export(String, "AnonymousPro", "CourierPrime", "LobsterTwo", "Default") var _font_name = "AnonymousPro"
export(int) var _font_size = 20
export(Color) var _font_color = Color(.8, .8, .8, 1)
export(Color) var _background_color = Color(.15, .15, .15, 1)
@export var _font_name = "AnonymousPro" # (String, "AnonymousPro", "CourierPrime", "LobsterTwo", "Default")
@export var _font_size: int = 20
@export var _font_color: Color = Color(.8, .8, .8, 1)
@export var _background_color: Color = Color(.15, .15, .15, 1)
# Enable/Disable coloring of output.
export(bool) var _color_output = true
@export var _color_output: bool = true
# The full/partial name of a script to select upon startup
export(String) var _select_script = ""
@export var _select_script: String = ""
# The full/partial name of a test. All tests that contain the string will be
# run
export(String) var _tests_like = ""
@export var _tests_like: String = ""
# The full/partial name of an Inner Class to be run. All Inner Classes that
# contain the string will be run.
export(String) var _inner_class_name = ""
@export var _inner_class_name: String = ""
# Start running tests when the scene finishes loading
export var _run_on_load = false
# Maximize the GUT control on startup
export var _should_maximize = false
@export var _run_on_load = false
# Maximize the GUT control checked startup
@export var _should_maximize = false
# Print output to the consol as well
export var _should_print_to_console = true
@export var _should_print_to_console = true
# Display orphan counts at the end of tests/scripts.
export var _show_orphans = true
@export var _show_orphans = true
# The log level.
export(int, "Fail/Errors", "Errors/Warnings/Test Names", "Everything") var _log_level = 1
@export var _log_level = 1 # (int, "Fail/Errors", "Errors/Warnings/Test Names", "Everything")
# When enabled GUT will yield between tests to give the GUI time to paint.
# Disabling this can make the program appear to hang and can have some
# unwanted consequences with the timing of freeing objects
export var _yield_between_tests = true
@export var _yield_between_tests = true
# When GUT compares values it first checks the types to prevent runtime errors.
# This behavior can be disabled if desired. This flag was added early in
# development to prevent any breaking changes and will likely be removed in
# the future.
export var _disable_strict_datatype_checks = false
@export var _disable_strict_datatype_checks = false
# The prefix used to find test methods.
export var _test_prefix = "test_"
@export var _test_prefix = "test_"
# The prefix used to find test scripts.
export var _file_prefix = "test_"
@export var _file_prefix = "test_"
# The file extension for test scripts (I don't think you can change this and
# everythign work).
export var _file_extension = ".gd"
@export var _file_extension = ".gd"
# The prefix used to find Inner Test Classes.
export var _inner_class_prefix = "Test"
@export var _inner_class_prefix = "Test"
# The directory GUT will use to write any temporary files. This isn't used
# much anymore since there was a change to the double creation implementation.
# This will be removed in a later release.
export(String) var _temp_directory = "user://gut_temp_directory"
@export var _temp_directory: String = "user://gut_temp_directory"
# The path and filename for exported test information.
export(String) var _export_path = ""
@export var _export_path: String = ""
# When enabled, any directory added will also include its subdirectories when
# GUT looks for test scripts.
export var _include_subdirectories = false
@export var _include_subdirectories = false
# Allow user to add test directories via editor. This is done with strings
# instead of an array because the interface for editing arrays is really
# cumbersome and complicates testing because arrays set through the editor
# apply to ALL instances. This also allows the user to use the built in
# dialog to pick a directory.
export(String, DIR) var _directory1 = ""
export(String, DIR) var _directory2 = ""
export(String, DIR) var _directory3 = ""
export(String, DIR) var _directory4 = ""
export(String, DIR) var _directory5 = ""
export(String, DIR) var _directory6 = ""
@export var _directory1 = "" # (String, DIR)
@export var _directory2 = "" # (String, DIR)
@export var _directory3 = "" # (String, DIR)
@export var _directory4 = "" # (String, DIR)
@export var _directory5 = "" # (String, DIR)
@export var _directory6 = "" # (String, DIR)
# Must match the types in _utils for double strategy
export(int, "FULL", "PARTIAL") var _double_strategy = 1
# Path and filename to the script to run before all tests are run.
export(String, FILE) var _pre_run_script = ""
# Path and filename to the script to run after all tests are run.
export(String, FILE) var _post_run_script = ""
# Path to the file that gut will export results to in the junit xml format
export(String, FILE) var _junit_xml_file = ""
@export var _double_strategy = 1 # (int, "FULL", "PARTIAL")
# Path3D and filename to the script to run before all tests are run.
@export var _pre_run_script = "" # (String, FILE)
# Path3D and filename to the script to run after all tests are run.
@export var _post_run_script = "" # (String, FILE)
# Path3D to the file that gut will export results to in the junit xml format
@export var _junit_xml_file = "" # (String, FILE)
# Flag to include a timestamp in the filename of _junit_xml_file
export(bool) var _junit_xml_timestamp = false
@export var _junit_xml_timestamp: bool = false
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
@ -130,7 +130,7 @@ var _placeholder = null
func _init():
# This min size has to be what the min size of the GutScene's min size is
# but it has to be set here and not inferred i think.
rect_min_size = Vector2(740, 250)
minimum_size = Vector2(740, 250)
func _ready():
@ -138,18 +138,18 @@ func _ready():
# Engine.get_main_loop() is populated and the psuedo singleton utils.gd
# can be setup correctly.
if Engine.editor_hint:
_placeholder = load("res://addons/gut/GutScene.tscn").instance()
_placeholder = load("res://addons/gut/GutScene.tscn").instantiate()
call_deferred("add_child", _placeholder)
_placeholder.rect_size = rect_size
_placeholder.size = size
else:
call_deferred("_setup_gut")
connect("resized", self, "_on_resized")
connect("resized",Callable(self,"_on_resized"))
func _on_resized():
if _placeholder != null:
_placeholder.rect_size = rect_size
_placeholder.size = size
# Templates can be missing if tests are exported and the export config for the
@ -176,7 +176,7 @@ func _setup_gut():
_lgr = _utils.get_logger()
_gut = load("res://addons/gut/gut.gd").new()
_gut.connect("tests_finished", self, "_on_tests_finished")
_gut.connect("tests_finished",Callable(self,"_on_tests_finished"))
if !_check_for_templates():
return
@ -228,7 +228,7 @@ func _setup_gut():
_gut.get_gui().set_font(_font_name)
_gut.get_gui().set_default_font_color(_font_color)
_gut.get_gui().set_background_color(_background_color)
_gut.get_gui().rect_size = rect_size
_gut.get_gui().size = size
emit_signal("gut_ready")
if _run_on_load:
@ -244,7 +244,7 @@ func _is_ready_to_go(action):
str(
"GUT is not ready for ",
action,
" yet. Perform actions on GUT in/after the gut_ready signal."
" yet. Perform actions checked GUT in/after the gut_ready signal."
)
)
return _gut != null

View file

@ -49,7 +49,7 @@ class GutGuiPrinter:
extends Printer
var _gut = null
var _colors = {red = Color.red, yellow = Color.yellow, green = Color.green}
var _colors = {red = Color.RED, yellow = Color.YELLOW, green = Color.GREEN}
func _init():
_printer_name = "gui"
@ -122,7 +122,7 @@ class ConsolePrinter:
class TerminalPrinter:
extends Printer
var escape = PoolByteArray([0x1b]).get_string_from_ascii()
var escape = PackedByteArray([0x1b]).get_string_from_ascii()
var cmd_colors = {
red = escape + "[31m",
yellow = escape + "[33m",

View file

@ -94,7 +94,7 @@ func get_results_dictionary(gut, include_scripts = true):
func write_json_file(gut, path):
var dict = get_results_dictionary(gut)
var json = JSON.print(dict, " ")
var json = JSON.stringify(dict, " ")
var f_result = _utils.write_file(path, json)
if f_result != OK:
@ -106,7 +106,7 @@ func write_json_file(gut, path):
func write_summary_file(gut, path):
var dict = get_results_dictionary(gut, false)
var json = JSON.print(dict, " ")
var json = JSON.stringify(dict, " ")
var f_result = _utils.write_file(path, json)
if f_result != OK:

View file

@ -25,7 +25,7 @@
# ##############################################################################
# Some arbitrary string that should never show up by accident. If it does, then
# shame on you.
# shame checked you.
const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_"
# This hash holds the objects that are being watched, the signals that are being
@ -46,11 +46,11 @@ const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_"
# }
#
# In this sample:
# - signal1 on the ref1 object was emitted 3 times and each time, zero
# - signal1 checked the ref1 object was emitted 3 times and each time, zero
# parameters were passed.
# - signal3 on ref1 was emitted once and passed a single parameter
# - some_signal on ref2 was never emitted.
# - other_signal on ref2 was emitted 3 times, each time with 3 parameters.
# - signal3 checked ref1 was emitted once and passed a single parameter
# - some_signal checked ref2 was never emitted.
# - other_signal checked ref2 was emitted 3 times, each time with 3 parameters.
var _watched_signals = {}
var _utils = load("res://addons/gut/utils.gd").get_instance()
@ -64,7 +64,7 @@ func _add_watched_signal(obj, name):
_watched_signals[obj] = {name: []}
else:
_watched_signals[obj][name] = []
obj.connect(name, self, "_on_watched_signal", [obj, name])
obj.connect(name,Callable(self,"_on_watched_signal").bind(obj, name))
# This handles all the signals that are watched. It supports up to 9 parameters
@ -73,7 +73,7 @@ func _add_watched_signal(obj, name):
# parameters when dynamically calling a method via call (per the Godot
# documentation, i.e. some_object.call('some_method', 1, 2, 3...)).
#
# Based on the documentation of emit_signal, it appears you can only pass up
# Based checked the documentation of emit_signal, it appears you can only pass up
# to 4 parameters when firing a signal. I haven't verified this, but this should
# future proof this some if the value ever grows.
func _on_watched_signal(
@ -91,13 +91,13 @@ func _on_watched_signal(
):
var args = [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]
# strip off any unused vars.
# strip unchecked any unused vars.
var idx = args.size() - 1
while str(args[idx]) == ARG_NOT_SET:
args.remove(idx)
args.remove_at(idx)
idx -= 1
# retrieve object and signal name from the array and remove them. These
# retrieve object and signal name from the array and remove_at them. These
# will always be at the end since they are added when the connect happens.
var signal_name = args[args.size() - 1]
args.pop_back()
@ -172,7 +172,7 @@ func clear():
for obj in _watched_signals:
if _utils.is_not_freed(obj):
for signal_name in _watched_signals[obj]:
obj.disconnect(signal_name, self, "_on_watched_signal")
obj.disconnect(signal_name,Callable(self,"_on_watched_signal"))
_watched_signals.clear()

View file

@ -10,37 +10,37 @@ func _init_types_dictionary():
types[TYPE_NIL] = "TYPE_NIL"
types[TYPE_BOOL] = "Bool"
types[TYPE_INT] = "Int"
types[TYPE_REAL] = "Float/Real"
types[TYPE_FLOAT] = "Float/Real"
types[TYPE_STRING] = "String"
types[TYPE_VECTOR2] = "Vector2"
types[TYPE_RECT2] = "Rect2"
types[TYPE_VECTOR3] = "Vector3"
#types[8] = 'Matrix32'
types[TYPE_PLANE] = "Plane"
types[TYPE_QUAT] = "QUAT"
types[TYPE_QUATERNION] = "QUAT"
types[TYPE_AABB] = "AABB"
#types[12] = 'Matrix3'
types[TYPE_TRANSFORM] = "Transform"
types[TYPE_TRANSFORM3D] = "Transform3D"
types[TYPE_COLOR] = "Color"
#types[15] = 'Image'
types[TYPE_NODE_PATH] = "Node Path"
types[TYPE_NODE_PATH] = "Node Path3D"
types[TYPE_RID] = "RID"
types[TYPE_OBJECT] = "TYPE_OBJECT"
#types[19] = 'TYPE_INPUT_EVENT'
types[TYPE_DICTIONARY] = "Dictionary"
types[TYPE_ARRAY] = "Array"
types[TYPE_RAW_ARRAY] = "TYPE_RAW_ARRAY"
types[TYPE_INT_ARRAY] = "TYPE_INT_ARRAY"
types[TYPE_REAL_ARRAY] = "TYPE_REAL_ARRAY"
types[TYPE_STRING_ARRAY] = "TYPE_STRING_ARRAY"
types[TYPE_VECTOR2_ARRAY] = "TYPE_VECTOR2_ARRAY"
types[TYPE_VECTOR3_ARRAY] = "TYPE_VECTOR3_ARRAY"
types[TYPE_COLOR_ARRAY] = "TYPE_COLOR_ARRAY"
types[TYPE_PACKED_BYTE_ARRAY] = "TYPE_PACKED_BYTE_ARRAY"
types[TYPE_PACKED_INT32_ARRAY] = "TYPE_PACKED_INT32_ARRAY"
types[TYPE_PACKED_FLOAT32_ARRAY] = "TYPE_PACKED_FLOAT32_ARRAY"
types[TYPE_PACKED_STRING_ARRAY] = "TYPE_PACKED_STRING_ARRAY"
types[TYPE_PACKED_VECTOR2_ARRAY] = "TYPE_PACKED_VECTOR2_ARRAY"
types[TYPE_PACKED_VECTOR3_ARRAY] = "TYPE_PACKED_VECTOR3_ARRAY"
types[TYPE_PACKED_COLOR_ARRAY] = "TYPE_PACKED_COLOR_ARRAY"
types[TYPE_MAX] = "TYPE_MAX"
# Types to not be formatted when using _str
var _str_ignore_types = [TYPE_INT, TYPE_REAL, TYPE_STRING, TYPE_NIL, TYPE_BOOL]
var _str_ignore_types = [TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_NIL, TYPE_BOOL]
func _init():
@ -82,10 +82,10 @@ func _get_obj_filename(thing):
pass
elif NativeScriptClass != null and thing.get_script() is NativeScriptClass:
# Work with GDNative scripts:
# inst2dict fails with "Not a script with an instance" on GDNative script instances
# inst_to_dict fails with "Not a script with an instance" checked GDNative script instances
filename = _get_filename(thing.get_script().resource_path)
elif !_utils.is_native_class(thing):
var dict = inst2dict(thing)
var dict = inst_to_dict(thing)
filename = _get_filename(dict["@path"])
if dict["@subpath"] != "":
filename += str("/", dict["@subpath"])
@ -108,7 +108,7 @@ func type2str(thing):
# will pass typeof(thing) == TYPE_OBJECT check so this has to be
# before that.
str_thing = str(null)
elif typeof(thing) == TYPE_REAL:
elif typeof(thing) == TYPE_FLOAT:
if !"." in str_thing:
str_thing += ".0"
elif typeof(thing) == TYPE_STRING:

View file

@ -1,7 +1,7 @@
var return_val = null
var stub_target = null
var target_subpath = null
# the parameter values to match method call on.
# the parameter values to match method call checked.
var parameters = null
var stub_method = null
var call_super = false
@ -25,7 +25,7 @@ var _parameter_override_only = true
const NOT_SET = "|_1_this_is_not_set_1_|"
func _init(target = null, method = null, subpath = null):
func _init(target = null,method = null,subpath = null):
stub_target = target
stub_method = method
target_subpath = subpath
@ -64,7 +64,7 @@ func when_passed(
var idx = 0
while idx < parameters.size():
if str(parameters[idx]) == NOT_SET:
parameters.remove(idx)
parameters.remove_at(idx)
else:
idx += 1
return self

View file

@ -28,7 +28,7 @@ func _make_key_from_metadata(doubled):
return to_return
# Creates they key for the returns hash based on the type of object passed in
# Creates they key for the returns hash based checked the type of object passed in
# obj could be a string of a path to a script with an optional subpath or
# it could be an instance of a doubled object.
func _make_key_from_variant(obj, subpath = null):

View file

@ -62,7 +62,7 @@ class DoubleInfo:
# (object_to_double, subpath)
# (object_to_double, strategy)
# (object_to_double, subpath, strategy)
func _init(thing, p2 = null, p3 = null):
func _init(thing,p2 = null,p3 = null):
strategy = p2
# short-circuit and ensure that is_valid
@ -218,7 +218,7 @@ func _do_datatypes_match__fail_if_not(got, expected, text):
# ------------------------------------------------------------------------------
# Create a string that lists all the methods that were called on an spied
# Create a string that lists all the methods that were called checked an spied
# instance.
# ------------------------------------------------------------------------------
func _get_desc_of_calls_to_instance(inst):
@ -226,9 +226,9 @@ func _get_desc_of_calls_to_instance(inst):
var calls = gut.get_spy().get_call_list_as_string(inst)
# indent all the calls
calls = BULLET + calls.replace("\n", "\n" + BULLET)
# remove trailing newline and bullet
# remove_at trailing newline and bullet
calls = calls.substr(0, calls.length() - BULLET.length() - 1)
return "Calls made on " + str(inst) + "\n" + calls
return "Calls made checked " + str(inst) + "\n" + calls
# ------------------------------------------------------------------------------
@ -282,7 +282,7 @@ func _fail_if_parameters_not_array(parameters):
func _create_obj_from_type(type):
var obj = null
if type.is_class("PackedScene"):
obj = type.instance()
obj = type.instantiate()
add_child(obj)
else:
obj = type.new()
@ -678,8 +678,8 @@ func assert_get_set_methods(obj, property, default, set_to):
# ------------------------------------------------------------------------------
func assert_accessors(obj, property, default, set_to):
var fail_count = _summary.failed
var get_func = "get_" + property
var set_func = "set_" + property
var get()_func = "get_" + property
var set()_func = "set_" + property
if obj.has_method("is_" + property):
get_func = "is_" + property
@ -699,7 +699,7 @@ func assert_accessors(obj, property, default, set_to):
# from passed object. Returns null if not found.
# If provided, property_usage constrains the type of property returned by
# passing either:
# EDITOR_PROPERTY for properties defined as: export(int) var some_value
# EDITOR_PROPERTY for properties defined as: export var some_value: int
# VARIABLE_PROPERTY for properties defined as: var another_value
# ---------------------------------------------------------------------------
func _find_object_property(obj, property_name, property_usage = null):
@ -707,7 +707,7 @@ func _find_object_property(obj, property_name, property_usage = null):
var found = false
var properties = obj.get_property_list()
while !found and !properties.empty():
while !found and !properties.is_empty():
var property = properties.pop_back()
if property["name"] == property_name:
if property_usage == null or property["usage"] == property_usage:
@ -747,12 +747,12 @@ func _can_make_signal_assertions(object, signal_name):
# ------------------------------------------------------------------------------
# Check if an object is connected to a signal on another object. Returns True
# Check if an object is connected to a signal checked another object. Returns True
# if it is and false otherwise
# ------------------------------------------------------------------------------
func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""):
if method_name != "":
return signaler_obj.is_connected(signal_name, connect_to_obj, method_name)
return signaler_obj.is_connected(signal_name,Callable(connect_to_obj,method_name))
else:
var connections = signaler_obj.get_signal_connection_list(signal_name)
for conn in connections:
@ -770,10 +770,10 @@ func watch_signals(object):
# ------------------------------------------------------------------------------
# Asserts that an object is connected to a signal on another object
# Asserts that an object is connected to a signal checked another object
#
# This will fail with specific messages if the target object is not connected
# to the specified signal on the source object.
# to the specified signal checked the source object.
# ------------------------------------------------------------------------------
func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""):
pass
@ -785,7 +785,7 @@ func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = "
_str(signaler_obj),
" to be connected to signal: [",
signal_name,
"] on ",
"] checked ",
_str(connect_to_obj),
method_disp
)
@ -796,10 +796,10 @@ func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = "
# ------------------------------------------------------------------------------
# Asserts that an object is not connected to a signal on another object
# Asserts that an object is not connected to a signal checked another object
#
# This will fail with specific messages if the target object is connected
# to the specified signal on the source object.
# to the specified signal checked the source object.
# ------------------------------------------------------------------------------
func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""):
var method_disp = ""
@ -810,7 +810,7 @@ func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name
_str(signaler_obj),
" to not be connected to signal: [",
signal_name,
"] on ",
"] checked ",
_str(connect_to_obj),
method_disp
)
@ -1116,21 +1116,21 @@ func assert_string_ends_with(text, search, match_case = true):
# ------------------------------------------------------------------------------
# Assert that a method was called on an instance of a doubled class. If
# Assert that a method was called checked an instance of a doubled class. If
# parameters are supplied then the params passed in when called must match.
# TODO make 3rd parameter "param_or_text" and add fourth parameter of "text" and
# then work some magic so this can have a "text" parameter without being
# annoying.
# ------------------------------------------------------------------------------
func assert_called(inst, method_name, parameters = null):
var disp = str("Expected [", method_name, "] to have been called on ", _str(inst))
var disp = str("Expected [", method_name, "] to have been called checked ", _str(inst))
if _fail_if_parameters_not_array(parameters):
return
if !_utils.is_double(inst):
_fail(
"You must pass a doubled instance to assert_called. Check the wiki for info on using double."
"You must pass a doubled instance to assert_called. Check the wiki for info checked using double."
)
else:
if gut.get_spy().was_called(inst, method_name, parameters):
@ -1142,19 +1142,19 @@ func assert_called(inst, method_name, parameters = null):
# ------------------------------------------------------------------------------
# Assert that a method was not called on an instance of a doubled class. If
# Assert that a method was not called checked an instance of a doubled class. If
# parameters are specified then this will only fail if it finds a call that was
# sent matching parameters.
# ------------------------------------------------------------------------------
func assert_not_called(inst, method_name, parameters = null):
var disp = str("Expected [", method_name, "] to NOT have been called on ", _str(inst))
var disp = str("Expected [", method_name, "] to NOT have been called checked ", _str(inst))
if _fail_if_parameters_not_array(parameters):
return
if !_utils.is_double(inst):
_fail(
"You must pass a doubled instance to assert_not_called. Check the wiki for info on using double."
"You must pass a doubled instance to assert_not_called. Check the wiki for info checked using double."
)
else:
if gut.get_spy().was_called(inst, method_name, parameters):
@ -1166,7 +1166,7 @@ func assert_not_called(inst, method_name, parameters = null):
# ------------------------------------------------------------------------------
# Assert that a method on an instance of a doubled class was called a number
# Assert that a method checked an instance of a doubled class was called a number
# of times. If parameters are specified then only calls with matching
# parameter values will be counted.
# ------------------------------------------------------------------------------
@ -1179,12 +1179,12 @@ func assert_call_count(inst, method_name, expected_count, parameters = null):
var param_text = ""
if parameters:
param_text = " with parameters " + str(parameters)
var disp = "Expected [%s] on %s to be called [%s] times%s. It was called [%s] times."
var disp = "Expected [%s] checked %s to be called [%s] times%s. It was called [%s] times."
disp = disp % [method_name, _str(inst), expected_count, param_text, count]
if !_utils.is_double(inst):
_fail(
"You must pass a doubled instance to assert_call_count. Check the wiki for info on using double."
"You must pass a doubled instance to assert_call_count. Check the wiki for info checked using double."
)
else:
if count == expected_count:
@ -1498,7 +1498,7 @@ func yield_frames(frames, msg = ""):
# not make assertions after a yield.
# ------------------------------------------------------------------------------
func end_test():
_lgr.deprecated("end_test is no longer necessary, you can remove it.")
_lgr.deprecated("end_test is no longer necessary, you can remove_at it.")
#gut.end_yielded_test()
@ -1678,7 +1678,7 @@ func ignore_method_when_doubling(thing, method_name):
var path = double_info.path
if double_info.is_scene():
var inst = thing.instance()
var inst = thing.instantiate()
if inst.get_script():
path = inst.get_script().get_path()
@ -1698,7 +1698,7 @@ func ignore_method_when_doubling(thing, method_name):
# ------------------------------------------------------------------------------
func stub(thing, p2, p3 = null):
if _utils.is_instance(thing) and !_utils.is_double(thing):
_lgr.error(str("You cannot use stub on ", _str(thing), " because it is not a double."))
_lgr.error(str("You cannot use stub checked ", _str(thing), " because it is not a double."))
return _utils.StubParams.new()
var method_name = p2
@ -1791,7 +1791,7 @@ func autofree(thing):
# ------------------------------------------------------------------------------
# Works the same as autofree except queue_free will be called on the object
# Works the same as autofree except queue_free will be called checked the object
# instead. This also imparts a brief pause after the test finishes so that
# the queued object has time to free.
# ------------------------------------------------------------------------------
@ -1807,7 +1807,7 @@ func add_child_autofree(node, legible_unique_name = false):
gut.get_autofree().add_free(node)
# Explicitly calling super here b/c add_child MIGHT change and I don't want
# a bug sneaking its way in here.
.add_child(node, legible_unique_name)
super.add_child(node, legible_unique_name)
return node
@ -1818,7 +1818,7 @@ func add_child_autoqfree(node, legible_unique_name = false):
gut.get_autofree().add_queue_free(node)
# Explicitly calling super here b/c add_child MIGHT change and I don't want
# a bug sneaking its way in here.
.add_child(node, legible_unique_name)
super.add_child(node, legible_unique_name)
return node
@ -1869,7 +1869,7 @@ func fail_test(text):
# ------------------------------------------------------------------------------
# Peforms a deep compare on both values, a CompareResult instnace is returned.
# Peforms a deep compare checked both values, a CompareResult instnace is returned.
# The optional max_differences paramter sets the max_differences to be displayed.
# ------------------------------------------------------------------------------
func compare_deep(v1, v2, max_differences = null):
@ -1880,7 +1880,7 @@ func compare_deep(v1, v2, max_differences = null):
# ------------------------------------------------------------------------------
# Peforms a shallow compare on both values, a CompareResult instnace is returned.
# Peforms a shallow compare checked both values, a CompareResult instnace is returned.
# The optional max_differences paramter sets the max_differences to be displayed.
# ------------------------------------------------------------------------------
func compare_shallow(v1, v2, max_differences = null):

View file

@ -31,7 +31,7 @@ class TestScript:
var _utils = null
var _lgr = null
func _init(utils = null, logger = null):
func _init(utils = null,logger = null):
_utils = utils
_lgr = logger
@ -60,7 +60,7 @@ class TestScript:
return to_return
func get_filename_and_inner():
var to_return = get_filename()
var to_return = get_scene_file_path()
if inner_class_name != null:
to_return += "." + inner_class_name
return to_return
@ -71,7 +71,7 @@ class TestScript:
to_return += "." + inner_class_name
return to_return
func get_filename():
func get_scene_file_path():
return path.get_file()
func has_inner_class():

View file

@ -108,7 +108,7 @@ var req_godot = [3, 2, 0]
# Used for doing file manipulation stuff so as to not keep making File instances.
# could be a bit of overkill but who cares.
var _file_checker = File.new()
# Online fetch of the latest version available on github
# Online fetch of the latest version available checked github
var latest_version = null
var should_display_latest_version = false
@ -135,7 +135,7 @@ func _http_request_latest_version() -> void:
var http_request = HTTPRequest.new()
http_request.name = "http_request"
add_child(http_request)
http_request.connect("request_completed", self, "_on_http_request_latest_version_completed")
http_request.connect("request_completed",Callable(self,"_on_http_request_latest_version_completed"))
# Perform a GET request. The URL below returns JSON as of writing.
var error = http_request.request("https://api.github.com/repos/bitwes/Gut/releases/latest")
@ -144,7 +144,9 @@ func _on_http_request_latest_version_completed(result, response_code, headers, b
if not result == HTTPRequest.RESULT_SUCCESS:
return
var response = parse_json(body.get_string_from_utf8())
var test_json_conv = JSON.new()
test_json_conv.parse(body.get_string_from_utf8())
var response = test_json_conv.get_data()
# Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
if response:
if response.get("html_url"):
@ -176,7 +178,7 @@ func get_version_text():
# Returns a nice string for erroring out when we have a bad Godot version.
# ------------------------------------------------------------------------------
func get_bad_version_text():
var ver = PoolStringArray(req_godot).join(".")
var ver = ".".join(PackedStringArray(req_godot))
var info = Engine.get_version_info()
var gd_version = str(info.major, ".", info.minor, ".", info.patch)
return (
@ -278,7 +280,7 @@ func is_gdscript(obj):
# ------------------------------------------------------------------------------
# Returns an array of values by calling get(property) on each element in source
# Returns an array of values by calling get(property) checked each element in source
# ------------------------------------------------------------------------------
func extract_property_from_array(source, property):
var to_return = []
@ -323,7 +325,7 @@ func get_native_class_name(thing):
if is_native_class(thing):
var newone = thing.new()
to_return = newone.get_class()
if !newone is Reference:
if !newone is RefCounted:
newone.free()
return to_return
@ -352,7 +354,7 @@ func get_file_as_text(path):
# ------------------------------------------------------------------------------
# Loops through an array of things and calls a method or checks a property on
# Loops through an array of things and calls a method or checks a property checked
# each element until it finds the returned value. The item in the array is
# returned or null if it is not found.
# ------------------------------------------------------------------------------
@ -383,7 +385,7 @@ func are_datatypes_same(got, expected):
func pretty_print(dict):
print(str(JSON.print(dict, " ")))
print(str(JSON.stringify(dict, " ")))
func get_script_text(obj):

View file

@ -1,6 +1,6 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
[sub_resource type="Sky" id=1]
[resource]
background_mode = 2

View file

@ -1,4 +1,4 @@
tool
@tool
extends Control
# This scene demonstrates how we can control the Terminal node directly by
# sending and receiving strings and ANSI escape sequences to the terminal
@ -38,15 +38,15 @@ var row: int
var menu_start_row: int
var offset: int
onready var tput = TPut.new($Terminal)
@onready var tput = TPut.new($Terminal)
func _ready():
if not $Terminal.is_connected("key_pressed", self, "_on_Terminal_key_pressed"):
if not $Terminal.is_connected("key_pressed",Callable(self,"_on_Terminal_key_pressed")):
# warning-ignore:return_value_discarded
$Terminal.connect("key_pressed", self, "_on_Terminal_key_pressed")
$Terminal.connect("key_pressed",Callable(self,"_on_Terminal_key_pressed"))
# warning-ignore:return_value_discarded
$Terminal.connect("size_changed", self, "draw_all")
$Terminal.connect("size_changed",Callable(self,"draw_all"))
$Terminal.grab_focus()
draw_all()
@ -132,12 +132,12 @@ func _on_Terminal_key_pressed(data: String, event: InputEventKey) -> void:
match item.name:
"Asciicast":
var scene = item.scene.instance()
var scene = item.scene.instantiate()
var animation_player: AnimationPlayer = scene.get_node("AnimationPlayer")
scene.connect("key_pressed", self, "_on_Asciicast_key_pressed", [animation_player])
scene.connect("key_pressed",Callable(self,"_on_Asciicast_key_pressed").bind(animation_player))
add_child(scene)
scene.grab_focus()
yield(animation_player, "animation_finished")
await animation_player.animation_finished
remove_child(scene)
$Terminal.grab_focus()
scene.queue_free()
@ -148,15 +148,15 @@ func _on_Terminal_key_pressed(data: String, event: InputEventKey) -> void:
(
"Psuedoterminal node currently"
+ " uses pty.h but needs to use either winpty or conpty"
+ " to work on Windows."
+ " to work checked Windows."
),
"Terminal not Supported on Windows"
"Terminal not Supported checked Windows"
)
var scene = item.scene.instance()
var scene = item.scene.instantiate()
var pty = scene if OS.has_feature("JavaScript") else scene.get_node("PTY")
add_child(scene)
scene.grab_focus()
yield(pty, "exited")
await pty.exited
$Terminal.grab_focus()
scene.queue_free()
"Exit":

View file

@ -20,14 +20,14 @@ shader_type canvas_item;
// - If you are using this shader as an overlay, and want the shader to affect the nodes below in the Scene hierarchy,
// set 'overlay' to true (checked in the inspector).
// On Mac there is potentially a bug causing this to not work properly. If that is the case and you want to use the shader as an overlay
// change all \"overlay ? SCREEN_TEXTURE : TEXTURE\" to only \"SCREEN_TEXTURE\" on lines 129-140, and \"vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV);\"
// to \"vec2 uv = warp(SCREEN_UV);\" on line 98.
// change all \"overlay ? SCREEN_TEXTURE : TEXTURE\" to only \"SCREEN_TEXTURE\" checked lines 129-140, and \"vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV);\"
// to \"vec2 uv = warp(SCREEN_UV);\" checked line 98.
uniform bool overlay = false;
uniform float scanlines_opacity : hint_range(0.0, 1.0) = 0.4;
uniform float scanlines_width : hint_range(0.0, 0.5) = 0.25;
uniform float grille_opacity : hint_range(0.0, 1.0) = 0.3;
uniform vec2 resolution = vec2(640.0, 480.0); // Set the number of rows and columns the texture will be divided in. Scanlines and grille will make a square based on these values
uniform vec2 resolution = vec2(640.0, 480.0); // Set the number of rows and columns the texture will be divided in. Scanlines and grille will make a square based checked these values
uniform bool pixelate = true; // Fill each square (\"pixel\") with a sampled color, creating a pixel look and a more accurate representation of how a CRT monitor would work.
@ -42,7 +42,7 @@ uniform float noise_speed = 5.0; // There is a movement in the noise pattern tha
uniform float static_noise_intensity : hint_range(0.0, 1.0) = 0.06;
uniform float aberration : hint_range(-1.0, 1.0) = 0.03; // Chromatic aberration, a distortion on each color channel.
uniform float aberration : hint_range(-1.0, 1.0) = 0.03; // Chromatic aberration, a distortion checked each color channel.
uniform float brightness = 1.4; // When adding scanline gaps and grille the image can get very dark. Brightness tries to compensate for that.
uniform bool discolor = true; // Add a discolor effect simulating a VHS
@ -107,7 +107,7 @@ void fragment()
float time = roll ? TIME : 0.0;
// Pixelate the texture based on the given resolution.
// Pixelate the texture based checked the given resolution.
if (pixelate)
{
text_uv = ceil(uv * resolution) / resolution;
@ -174,7 +174,7 @@ void fragment()
text.g = clamp(g * brightness, 0.0, 1.0);
text.b = clamp(b * brightness, 0.0, 1.0);
// Scanlines are the horizontal lines that make up the image on a CRT monitor.
// Scanlines are the horizontal lines that make up the image checked a CRT monitor.
// Here we are actual setting the black gap between each line, which I guess is not the right definition of the word, but you get the idea
float scanlines = 0.5;
if (scanlines_opacity > 0.0)
@ -190,13 +190,13 @@ void fragment()
// Generate a noise pattern that is very stretched horizontally, and animate it with noise_speed
float noise = smoothstep(0.4, 0.5, noise(uv * vec2(2.0, 200.0) + vec2(10.0, (TIME * (noise_speed))) ) );
// We use roll_line (set above) to define how big the noise should be vertically (multiplying cuts off all black parts).
// We use roll_line (set above) to define how big the noise should be vertically (multiplying cuts unchecked all black parts).
// We also add in some basic noise with random() to break up the noise pattern above. The noise is sized according to
// the resolution value set in the inspector. If you don't like this look you can
// change \"ceil(uv * resolution) / resolution\" to only \"uv\" to make it less pixelated. Or multiply resolution with som value
// greater than 1.0 to make them smaller.
roll_line *= noise * scanlines * clamp(random((ceil(uv * resolution) / resolution) + vec2(TIME * 0.8, 0.0)).x + 0.8, 0.0, 1.0);
// Add it to the texture based on noise_opacity
// Add it to the texture based checked noise_opacity
text.rgb = clamp(mix(text.rgb, text.rgb + roll_line, noise_opacity), vec3(0.0), vec3(1.0));
}
@ -210,7 +210,7 @@ void fragment()
// Also apply the vignette
text.rgb *= border(uv);
text.rgb *= vignette(uv);
// Hides the black border and make that area transparent. Good if you want to add the the texture on top an image of a TV or monitor.
// Hides the black border and make that area transparent. Good if you want to add the the texture checked top an image of a TV or monitor.
if (clip_warp)
{
text.a = border(uv);
@ -283,8 +283,8 @@ __meta__ = {
}
[node name="Menu" parent="." instance=ExtResource( 1 )]
margin_left = 30.0
margin_top = 30.0
offset_left = 30.0
offset_top = 30.0
[node name="CanvasLayer" type="CanvasLayer" parent="."]

View file

@ -1,9 +1,9 @@
extends "res://addons/godot_xterm/terminal.gd"
export(String) var exec_path := "bash"
export(String) var socat_path := "socat" # E.g. /usr/bin/socat
export(int) var port := 2023
export(bool) var verbose := false
@export var exec_path: String := "bash"
@export var socat_path: String := "socat" # E.g. /usr/bin/socat
@export var port: int := 2023
@export var verbose: bool := false
var _timeout = 30
var _pid: int
@ -31,7 +31,7 @@ func _process(delta):
StreamPeerTCP.STATUS_CONNECTED:
var avail = _stream.get_available_bytes()
var data = PoolByteArray()
var data = PackedByteArray()
for i in range(avail):
data.append(_stream.get_u8())
call_deferred("write", data)

View file

@ -1,6 +1,6 @@
extends "res://addons/godot_xterm/terminal.gd"
onready var pty = $PTY
@onready var pty = $PTY
func _ready():

View file

@ -7,8 +7,8 @@ signal exited(status)
var line := ""
var _tput
onready var terminal = $Terminal
onready var _has_js: bool = OS.has_feature("JavaScript")
@onready var terminal = $Terminal
@onready var _has_js: bool = OS.has_feature("JavaScript")
func prompt(prompt: String):
@ -42,7 +42,7 @@ func _on_Terminal_key_pressed(_data, event: InputEventKey):
if not event:
return
# For some reason, data String is malformed on HTML5, so only use event.unicode.
# For some reason, data String is malformed checked HTML5, so only use event.unicode.
var data = char(event.unicode)
match event.scancode:

View file

@ -1,14 +1,6 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ {
; Project was converted by built-in tool to Godot 4.0
config_version=5
_global_script_classes=[{
"base": "Reference",
"class": "GutHookScript",
"language": "GDScript",
@ -18,7 +10,7 @@ _global_script_classes=[ {
"class": "GutTest",
"language": "GDScript",
"path": "res://addons/gut/test.gd"
} ]
}]
_global_script_class_icons={
"GutHookScript": "",
"GutTest": ""
@ -36,7 +28,7 @@ window/vsync/use_vsync=false
[editor_plugins]
enabled=PoolStringArray( "res://addons/godot_xterm/plugin.cfg" )
enabled=PackedStringArray("res://addons/godot_xterm/plugin.cfg")
[rendering]

View file

@ -7,7 +7,7 @@ var terminal: Terminal
func before_each():
terminal = Terminal.new()
terminal.rect_size = Vector2(400, 200)
terminal.size = Vector2(400, 200)
add_child_autofree(terminal)
@ -18,7 +18,7 @@ func test_bell() -> void:
terminal.write("\a")
terminal.write("\u0007")
terminal.write("'Ask not for whom the \a tolls; it tolls for thee' - John Donne")
yield(yield_to(terminal, "bell", 5), YIELD)
await yield_to(terminal, "bell", 5).YIELD
assert_signal_emit_count(terminal, "bell", 5)
@ -27,15 +27,15 @@ func test_bell_cooldown() -> void:
terminal.bell_cooldown = 0.5
terminal.write("\a")
terminal.write("\a")
yield(yield_for(1), YIELD)
await yield_for(1).YIELD
terminal.write("\a")
yield(yield_to(terminal, "bell", 5), YIELD)
await yield_to(terminal, "bell", 5).YIELD
assert_signal_emit_count(terminal, "bell", 2)
func test_writing_random_data_to_terminal_does_not_crash_application():
add_child_autofree(preload("res://test/scenes/write_random.tscn").instance())
yield(yield_frames(5, "Writing random data to terminal"), YIELD)
add_child_autofree(preload("res://test/scenes/write_random.tscn").instantiate())
await yield_frames(5, "Writing random data to terminal").YIELD
assert_true(true, "Expected no crash when writing random data to terminal.")
@ -71,16 +71,16 @@ class TestTheme:
func _get_pixelv(src: Vector2) -> Color:
var screen := get_tree().root.get_texture().get_data()
screen.lock()
false # screen.lock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed
screen.flip_y()
var pixel := screen.get_pixelv(src)
screen.unlock()
false # screen.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed
return pixel
func _check_colors(theme: Theme):
var cell_size := Vector2(
int(terminal.rect_size.x / terminal.get_cols()),
int(terminal.rect_size.y / terminal.get_rows())
int(terminal.size.x / terminal.get_cols()),
int(terminal.size.y / terminal.get_rows())
)
var src := cell_size / 2
@ -96,61 +96,61 @@ class TestTheme:
src += Vector2(cell_size.x, 0)
func before_each():
terminal = autofree(TestScene.instance())
yield(yield_frames(1), YIELD)
terminal = autofree(TestScene.instantiate())
await yield_frames(1).YIELD
func test_terminal_display_colors_from_default_theme():
terminal.theme = null
add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(default_theme)
func test_terminal_displays_colors_from_theme():
terminal.theme = alt_theme
add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(alt_theme)
func test_visible_characters_still_displayed_after_resize_with_default_theme():
terminal.theme = null
add_child(terminal)
yield(yield_frames(1), YIELD)
await yield_frames(1).YIELD
OS.window_size += Vector2(1, 0)
yield(yield_to(terminal, "size_changed", 5), YIELD)
await yield_to(terminal, "size_changed", 5).YIELD
_check_colors(default_theme)
func test_visible_characters_still_displayed_after_resize_with_custom_theme():
# Issue 57: https://github.com/lihop/godot-xterm/issues/57
terminal.theme = alt_theme
add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
OS.window_size += Vector2(1, 0)
yield(yield_to(terminal, "size_changed", 5), YIELD)
await yield_to(terminal, "size_changed", 5).YIELD
_check_colors(alt_theme)
func test_updates_colors_after_theme_set():
# Issue 58: https://github.com/lihop/godot-xterm/issues/58
terminal.theme = null
add_child(terminal)
yield(yield_frames(1), YIELD)
await yield_frames(1).YIELD
terminal.theme = alt_theme
yield(yield_to(terminal, "theme_changed", 50), YIELD)
await yield_to(terminal, "theme_changed", 50).YIELD
_check_colors(alt_theme)
func test_updates_colors_after_theme_unset():
# Issue 58: https://github.com/lihop/godot-xterm/issues/58
terminal.theme = alt_theme
add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
terminal.theme = null
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(default_theme)
func test_updates_colors_after_theme_changed():
# Issue 58: https://github.com/lihop/godot-xterm/issues/58
terminal.theme = alt_theme
add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
terminal.theme = default_theme
yield(yield_to(terminal, "theme_changed", 5), YIELD)
await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(default_theme)

View file

@ -26,8 +26,8 @@ func test_fork_succeeds():
func test_fork_has_output():
pty.call_deferred("fork", "exit")
yield(yield_to(pty, "data_received", 1), YIELD)
var expected := PoolByteArray(
await yield_to(pty, "data_received", 1).YIELD
var expected := PackedByteArray(
[
101,
120,
@ -124,20 +124,20 @@ func test_closes_pty_on_exit():
pty.fork("sleep", ["1000"])
remove_child(pty)
pty.free()
yield(yield_for(1), YIELD)
await yield_for(1).YIELD
var new_num_pts = helper._get_pts().size()
assert_eq(new_num_pts, num_pts)
func test_emits_exited_signal_when_child_process_exits():
pty.call_deferred("fork", "exit")
yield(yield_to(pty, "exited", 1), YIELD)
await yield_to(pty, "exited", 1).YIELD
assert_signal_emitted(pty, "exited")
class Helper:
static func _get_pts() -> Array:
assert(false, "Abstract method")
assert(false) #,"Abstract method")
return []
static func _get_winsize(fd: int) -> Dictionary:
@ -161,9 +161,9 @@ class Helper:
true,
output
)
assert(exit_code == 0, "Failed to run python command for this test.")
assert(exit_code == 0) #,"Failed to run python command for this test.")
var size = str2var("Vector2" + output[0].strip_edges())
var size = str_to_var("Vector2" + output[0].strip_edges())
return {rows = int(size.x), cols = int(size.y)}
@ -186,7 +186,7 @@ class TestPTYSize:
regex.compile(".*rows (?<rows>[0-9]+).*columns (?<columns>[0-9]+).*")
func before_each():
scene = add_child_autofree(preload("res://test/scenes/pty_and_terminal.tscn").instance())
scene = add_child_autofree(preload("res://test/scenes/pty_and_terminal.tscn").instantiate())
func test_correct_stty_reports_correct_size():
for s in [
@ -198,14 +198,14 @@ class TestPTYSize:
"PTYCousinAbove2",
"PTYCousinBelow2"
]:
pty = scene.get_node(s).find_node("PTY")
terminal = scene.get_node(s).find_node("Terminal")
pty = scene.get_node(s).find_child("PTY")
terminal = scene.get_node(s).find_child("Terminal")
pty.call_deferred("fork", OS.get_environment("SHELL"))
pty.call_deferred("write", "stty -a | head -n1\n")
var output := ""
while not "rows" in output and not "columns" in output:
output = (yield(pty, "data_received")).get_string_from_utf8()
output = (await pty.data_received).get_string_from_utf8()
var regex_match = regex.search(output)
var stty_rows = int(regex_match.get_string("rows"))
var stty_cols = int(regex_match.get_string("columns"))
@ -228,14 +228,14 @@ class LinuxHelper:
static func _get_pts() -> Array:
var dir := Directory.new()
if dir.open("/dev/pts") != OK or dir.list_dir_begin(true, true) != OK:
assert(false, "Could not open /dev/pts.")
if dir.open("/dev/pts") != OK or dir.list_dir_begin() != OK:# TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
assert(false) #,"Could not open /dev/pts.")
var pts := []
var file_name: String = dir.get_next()
while file_name != "":
if file_name.is_valid_integer():
if file_name.is_valid_int():
pts.append("/dev/pts/%s" % file_name)
file_name = dir.get_next()
@ -249,5 +249,5 @@ class MacOSHelper:
# TODO: Implement for macOS.
# On macOS there is no /dev/pts directory, rather new ptys are created
# under /dev/ttysXYZ.
assert(false, "Not implemented")
assert(false) #,"Not implemented")
return []

View file

@ -1,10 +1,10 @@
extends Control
onready var terminal = $Terminal
@onready var terminal = $Terminal
func _ready():
print("terminal size; rows %d; cols %d;" % [terminal.get_rows(), terminal.get_cols()])
terminal.write("h")
yield(get_tree().create_timer(1), "timeout")
await get_tree().create_timer(1).timeout
terminal.write(" i")

View file

@ -4,16 +4,16 @@
[ext_resource path="res://test/scenes/basic.gd" type="Script" id=3]
[node name="BasicNewTerm" type="Control"]
margin_right = 43.0
margin_bottom = 43.0
offset_right = 43.0
offset_bottom = 43.0
script = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ColorRect" type="ColorRect" parent="."]
margin_right = 40.0
margin_bottom = 40.0
offset_right = 40.0
offset_bottom = 40.0
color = Color( 0, 1, 0, 1 )
__meta__ = {
"_edit_use_anchors_": false

View file

@ -7,44 +7,44 @@ anchor_right = 1.0
anchor_bottom = 1.0
[node name="HBoxContainer" type="HBoxContainer" parent="."]
margin_right = 1024.0
margin_bottom = 600.0
offset_right = 1024.0
offset_bottom = 600.0
size_flags_horizontal = 3
[node name="TextEdit" type="TextEdit" parent="HBoxContainer"]
margin_right = 338.0
margin_bottom = 600.0
offset_right = 338.0
offset_bottom = 600.0
size_flags_horizontal = 3
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"]
margin_left = 342.0
margin_right = 681.0
margin_bottom = 600.0
offset_left = 342.0
offset_right = 681.0
offset_bottom = 600.0
size_flags_horizontal = 3
[node name="TextEdit3" type="TextEdit" parent="HBoxContainer/VBoxContainer"]
margin_right = 339.0
margin_bottom = 197.0
offset_right = 339.0
offset_bottom = 197.0
size_flags_vertical = 3
[node name="Terminal" type="Control" parent="HBoxContainer/VBoxContainer"]
margin_top = 201.0
margin_right = 339.0
margin_bottom = 398.0
offset_top = 201.0
offset_right = 339.0
offset_bottom = 398.0
focus_mode = 2
size_flags_vertical = 3
script = ExtResource( 1 )
[node name="TextEdit2" type="TextEdit" parent="HBoxContainer/VBoxContainer"]
margin_top = 402.0
margin_right = 339.0
margin_bottom = 600.0
offset_top = 402.0
offset_right = 339.0
offset_bottom = 600.0
size_flags_vertical = 3
[node name="TextEdit2" type="TextEdit" parent="HBoxContainer"]
margin_left = 685.0
margin_right = 1024.0
margin_bottom = 600.0
offset_left = 685.0
offset_right = 1024.0
offset_bottom = 600.0
size_flags_horizontal = 3
[connection signal="data_sent" from="HBoxContainer/VBoxContainer/Terminal" to="HBoxContainer/VBoxContainer/Terminal" method="write"]

View file

@ -1,4 +1,4 @@
tool
@tool
extends "res://addons/godot_xterm/terminal.gd"
signal theme_changed
@ -27,7 +27,7 @@ func _ready():
func _notification(what):
._notification(what)
super._notification(what)
match what:
NOTIFICATION_THEME_CHANGED:
call_deferred("emit_signal", "theme_changed")

View file

@ -12,7 +12,7 @@ func _ready():
func _process(_delta):
for _i in range(4096):
write(PoolByteArray([rng.randi() % 256]))
write(PackedByteArray([rng.randi() % 256]))
"
[node name="Terminal" type="Control"]

View file

@ -21,18 +21,18 @@ class TestMultipleInputs:
func press_key(scancode: int, unicode := 0) -> void:
var key_down = InputEventKey.new()
key_down.scancode = scancode
key_down.pressed = true
key_down.button_pressed = true
Input.parse_input_event(key_down)
yield(get_tree().create_timer(0.1), "timeout")
await get_tree().create_timer(0.1).timeout
var key_up = InputEventKey.new()
key_up.scancode = scancode
key_up.pressed = false
key_up.button_pressed = false
Input.parse_input_event(key_up)
func before_each():
var scene := preload("../scenes/multiple_inputs.tscn").instance()
var scene := preload("../scenes/multiple_inputs.tscn").instantiate()
add_child_autofree(scene)
terminal = scene.find_node("Terminal")
terminal = scene.find_child("Terminal")
terminal.grab_focus()
func test_terminal_keeps_focus_when_certain_keys_pressed():

View file

@ -1,9 +1,9 @@
[gd_resource type="Theme" load_steps=5 format=2]
[ext_resource path="res://themes/fonts/bold_italic.tres" type="DynamicFont" id=2]
[ext_resource path="res://themes/fonts/italic.tres" type="DynamicFont" id=3]
[ext_resource path="res://themes/fonts/bold.tres" type="DynamicFont" id=4]
[ext_resource path="res://themes/fonts/regular.tres" type="DynamicFont" id=5]
[ext_resource path="res://themes/fonts/bold_italic.tres" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/italic.tres" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/bold.tres" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/regular.tres" type="FontFile" id=5]
[resource]
Terminal/colors/background = Color( 0.12549, 0.145098, 0.192157, 1 )

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2]
[gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/hack/hack_bold-3.003.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5]
[ext_resource path="res://themes/fonts/hack/hack_bold-3.003.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=5]
[resource]
size = 14

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2]
[gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://themes/fonts/hack/hack_bold_italic-3.003.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/hack/hack_bold_italic-3.003.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=5]
[resource]
size = 14

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2]
[gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=3]
[ext_resource path="res://themes/fonts/hack/hack_italic-3.003.ttf" type="DynamicFontData" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/hack/hack_italic-3.003.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=5]
[resource]
size = 14

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2]
[gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=4]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=5]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=3]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=5]
[resource]
size = 14

View file

@ -1,9 +1,9 @@
[gd_resource type="Theme" load_steps=4 format=2]
[ext_resource path="res://addons/godot_xterm/resources/xrdb_theme.gd" type="Script" id=1]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="FontFile" id=2]
[sub_resource type="DynamicFont" id=1]
[sub_resource type="FontFile" id=1]
size = 39
extra_spacing_bottom = 1
font_data = ExtResource( 2 )