trying to fix Export
All checks were successful
Create tag and build when new code gets to main / Export (push) Successful in 6m53s
All checks were successful
Create tag and build when new code gets to main / Export (push) Successful in 6m53s
This commit is contained in:
@@ -1,227 +0,0 @@
|
||||
@tool
|
||||
class_name GdUnitCSIMessageWriter
|
||||
extends GdUnitMessageWriter
|
||||
## A message writer implementation using ANSI/CSI escape codes for console output.[br]
|
||||
## [br]
|
||||
## This writer provides formatted message output using CSI (Control Sequence Introducer) codes.[br]
|
||||
## It supports:[br]
|
||||
## - Color using RGB values[br]
|
||||
## - Text styles (bold, italic, underline)[br]
|
||||
## - Cursor positioning and text alignment[br]
|
||||
## [br]
|
||||
## Used primarily for console-based test execution and CI/CD environments.
|
||||
|
||||
|
||||
enum {
|
||||
COLOR_TABLE,
|
||||
COLOR_RGB
|
||||
}
|
||||
|
||||
const CSI_BOLD = "[1m"
|
||||
const CSI_ITALIC = "[3m"
|
||||
const CSI_UNDERLINE = "[4m"
|
||||
const CSI_RESET = "[0m"
|
||||
|
||||
# Control Sequence Introducer
|
||||
var _debug_show_color_codes := false
|
||||
var _color_mode := COLOR_TABLE
|
||||
|
||||
## Current cursor position in the line
|
||||
var _current_pos := 0
|
||||
|
||||
# Pre-compiled regex patterns for tag matching
|
||||
var _tag_regex: RegEx
|
||||
|
||||
|
||||
## Constructs CSI style codes based on flags.[br]
|
||||
## [br]
|
||||
## [param flags] The style flags to apply (BOLD, ITALIC, UNDERLINE).[br]
|
||||
## Returns the corresponding CSI codes.
|
||||
func _apply_style_flags(flags: int) -> String:
|
||||
var _style := ""
|
||||
if flags & BOLD:
|
||||
_style += CSI_BOLD
|
||||
if flags & ITALIC:
|
||||
_style += CSI_ITALIC
|
||||
if flags & UNDERLINE:
|
||||
_style += CSI_UNDERLINE
|
||||
return _style
|
||||
|
||||
|
||||
## Converts a color string (named or hex) to a Color object
|
||||
func _parse_color(color_str: String) -> Color:
|
||||
return Color.from_string(color_str.strip_edges().to_lower(), Color.WHITE)
|
||||
|
||||
|
||||
## Generates CSI color code for foreground color
|
||||
func _color_to_csi_fg(c: Color) -> String:
|
||||
return "[38;2;%d;%d;%dm" % [c.r8 * c.a, c.g8 * c.a, c.b8 * c.a]
|
||||
|
||||
|
||||
## Generates CSI color code for background color
|
||||
func _color_to_csi_bg(c: Color) -> String:
|
||||
return "[48;2;%d;%d;%dm" % [c.r8 * c.a, c.g8 * c.a, c.b8 * c.a]
|
||||
|
||||
|
||||
func _init_regex_patterns() -> void:
|
||||
if not _tag_regex:
|
||||
_tag_regex = RegEx.new()
|
||||
# Match all richtext tags: [tag], [tag=value], [/tag]
|
||||
_tag_regex.compile(r"\[/?(?:color|bgcolor|b|i|u)(?:=[^\]]+)?\]")
|
||||
|
||||
|
||||
func _extract_color_from_tag(tag: String, tag_assign: String) -> Color:
|
||||
var tag_assign_length := tag_assign.length()
|
||||
var color_value := tag.substr(tag_assign_length, tag.length() - tag_assign_length - 1)
|
||||
return _parse_color(color_value)
|
||||
|
||||
|
||||
## Optimized richtext to CSI conversion using regex and lookup processing
|
||||
func _bbcode_tags_to_csi_codes(message: String) -> String:
|
||||
_init_regex_patterns()
|
||||
|
||||
var result := ""
|
||||
var last_pos := 0
|
||||
var color_stack: Array[Color] = []
|
||||
var bgcolor_stack: Array[Color] = []
|
||||
|
||||
# Find all richtext tags
|
||||
var matches := _tag_regex.search_all(message)
|
||||
|
||||
for match in matches:
|
||||
var start_pos := match.get_start()
|
||||
var end_pos := match.get_end()
|
||||
var tag := match.get_string(0)
|
||||
|
||||
# Add text before this tag
|
||||
result += message.substr(last_pos, start_pos - last_pos)
|
||||
|
||||
# Process the tag
|
||||
if tag.begins_with("[color="):
|
||||
var fg_color := _extract_color_from_tag(tag, "[color=")
|
||||
color_stack.push_back(fg_color)
|
||||
result += _color_to_csi_fg(fg_color)
|
||||
elif tag.begins_with("[bgcolor="):
|
||||
var bg_color := _extract_color_from_tag(tag, "[bgcolor=")
|
||||
bgcolor_stack.push_back(bg_color)
|
||||
result += _color_to_csi_bg(bg_color)
|
||||
elif tag == "[b]":
|
||||
result += CSI_BOLD
|
||||
elif tag == "[i]":
|
||||
result += CSI_ITALIC
|
||||
elif tag == "[u]":
|
||||
result += CSI_UNDERLINE
|
||||
elif tag == "[/color]":
|
||||
result += CSI_RESET
|
||||
if color_stack.size() > 0:
|
||||
color_stack.pop_back()
|
||||
# Restore remaining styles and colors
|
||||
if color_stack.size() > 0:
|
||||
result += _color_to_csi_fg(color_stack[-1])
|
||||
if bgcolor_stack.size() > 0:
|
||||
result += _color_to_csi_bg(bgcolor_stack[-1])
|
||||
elif tag == "[/bgcolor]":
|
||||
result += CSI_RESET
|
||||
if bgcolor_stack.size() > 0:
|
||||
bgcolor_stack.pop_back()
|
||||
# Restore remaining styles and colors
|
||||
if color_stack.size() > 0:
|
||||
result += _color_to_csi_fg(color_stack[-1])
|
||||
if bgcolor_stack.size() > 0:
|
||||
result += _color_to_csi_bg(bgcolor_stack[-1])
|
||||
elif tag in ["[/b]", "[/i]", "[/u]"]:
|
||||
result += CSI_RESET
|
||||
# Restore remaining colors after style reset
|
||||
if color_stack.size() > 0:
|
||||
result += _color_to_csi_fg(color_stack[-1])
|
||||
if bgcolor_stack.size() > 0:
|
||||
result += _color_to_csi_bg(bgcolor_stack[-1])
|
||||
|
||||
last_pos = end_pos
|
||||
|
||||
# Add remaining text after last tag
|
||||
result += message.substr(last_pos)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
## Implementation of basic message output with formatting.
|
||||
func _print_message(_message: String, _color: Color, _indent: int, _flags: int) -> void:
|
||||
var text := _bbcode_tags_to_csi_codes(_message)
|
||||
var indent_text := "".lpad(_indent * 2)
|
||||
var _style := _apply_style_flags(_flags)
|
||||
printraw("%s[38;2;%d;%d;%dm%s%s[0m" % [indent_text, _color.r8, _color.g8, _color.b8, _style, text])
|
||||
_current_pos += _indent * 2 + text.length()
|
||||
|
||||
|
||||
## Implementation of line-ending message output with formatting.
|
||||
func _println_message(_message: String, _color: Color, _indent: int, _flags: int) -> void:
|
||||
_print_message(_message, _color, _indent, _flags)
|
||||
prints()
|
||||
_current_pos = 0
|
||||
|
||||
|
||||
## Implementation of positioned message output with formatting.
|
||||
func _print_at(_message: String, cursor_pos: int, _color: Color, _effect: Effect, _align: Align, _flags: int) -> void:
|
||||
if _align == Align.RIGHT:
|
||||
cursor_pos = cursor_pos - _message.length()
|
||||
|
||||
if cursor_pos > _current_pos:
|
||||
printraw("[%dG" % cursor_pos) # Move cursor to absolute position
|
||||
else:
|
||||
_message = " " + _message
|
||||
|
||||
var _style := _apply_style_flags(_flags)
|
||||
printraw("[38;2;%d;%d;%dm%s%s[0m" % [_color.r8, _color.g8, _color.b8, _style, _message])
|
||||
_current_pos = cursor_pos + _message.length()
|
||||
|
||||
|
||||
## Writes a line break and returns self for chaining.
|
||||
func new_line() -> GdUnitCSIMessageWriter:
|
||||
prints()
|
||||
return self
|
||||
|
||||
|
||||
## Saves the current cursor position.[br]
|
||||
## Returns self for chaining.
|
||||
func save_cursor() -> GdUnitCSIMessageWriter:
|
||||
printraw("[s")
|
||||
return self
|
||||
|
||||
|
||||
## Restores previously saved cursor position.[br]
|
||||
## Returns self for chaining.
|
||||
func restore_cursor() -> GdUnitCSIMessageWriter:
|
||||
printraw("[u")
|
||||
return self
|
||||
|
||||
|
||||
## Clears screen content and resets cursor position.
|
||||
func clear() -> void:
|
||||
printraw("[2J[H") # Clear screen and move cursor to home
|
||||
_current_pos = 0
|
||||
|
||||
|
||||
## Debug method to display the available color table.[br]
|
||||
## Shows both 6x6x6 color cube and RGB color modes.
|
||||
@warning_ignore("return_value_discarded")
|
||||
func _print_color_table() -> void:
|
||||
color(Color.ANTIQUE_WHITE).println_message("Color Table 6x6x6")
|
||||
_debug_show_color_codes = true
|
||||
for green in range(0, 6):
|
||||
for red in range(0, 6):
|
||||
for blue in range(0, 6):
|
||||
color(Color8(red * 42, green * 42, blue * 42)).println_message("████████ ")
|
||||
new_line()
|
||||
new_line()
|
||||
|
||||
color(Color.ANTIQUE_WHITE).println_message("Color Table RGB")
|
||||
_color_mode = COLOR_RGB
|
||||
for green in range(0, 6):
|
||||
for red in range(0, 6):
|
||||
for blue in range(0, 6):
|
||||
color(Color8(red * 42, green * 42, blue * 42)).println_message("████████ ")
|
||||
new_line()
|
||||
new_line()
|
||||
_color_mode = COLOR_TABLE
|
||||
_debug_show_color_codes = false
|
||||
@@ -1 +0,0 @@
|
||||
uid://bgk5ubygmpous
|
||||
@@ -1,214 +0,0 @@
|
||||
@tool
|
||||
class_name GdUnitMessageWriter
|
||||
extends RefCounted
|
||||
## Base interface class for writing formatted messages to different outputs.[br]
|
||||
## [br]
|
||||
## This class defines the interface and common functionality for writing formatted messages.[br]
|
||||
## It provides a fluent API for message formatting and supports different output targets.[br]
|
||||
## [br]
|
||||
## The class provides formatting options for:[br]
|
||||
## - Text colors[br]
|
||||
## - Text styles (bold, italic, underline)[br]
|
||||
## - Text effects (e.g., wave)[br]
|
||||
## - Text alignment[br]
|
||||
## - Indentation[br]
|
||||
## [br]
|
||||
## Two concrete implementations are available:[br]
|
||||
## - [GdUnitRichTextMessageWriter] writing to a [RichTextLabel][br]
|
||||
## - [GdUnitCSIMessageWriter] writing to console using CSI codes[br]
|
||||
## [br]
|
||||
## Example usage:[br]
|
||||
## [codeblock]
|
||||
## writer.color(Color.RED).style(BOLD).println_message("Test failed!")
|
||||
## writer.color(Color.GREEN).align(Align.RIGHT).print_at("Success", 80)
|
||||
## [/codeblock]
|
||||
|
||||
|
||||
## Text style flag for bold formatting
|
||||
const BOLD = 0x1
|
||||
## Text style flag for italic formatting
|
||||
const ITALIC = 0x2
|
||||
## Text style flag for underline formatting
|
||||
const UNDERLINE = 0x4
|
||||
|
||||
|
||||
## Represents special text effects that can be applied to the output
|
||||
enum Effect {
|
||||
## No special effect applied
|
||||
NONE,
|
||||
## Applies a wave animation to the text
|
||||
WAVE
|
||||
}
|
||||
|
||||
|
||||
## Controls text alignment at the specified cursor position
|
||||
enum Align {
|
||||
## Aligns text to the left of the cursor position
|
||||
LEFT,
|
||||
## Aligns text to the right of the cursor position, accounting for text length
|
||||
RIGHT
|
||||
}
|
||||
|
||||
|
||||
## The current text color to be used for the next output operation
|
||||
var _current_color := Color.WHITE
|
||||
|
||||
## The current indentation level to be used for the next output operation.[br]
|
||||
## Each level represents two spaces of indentation.
|
||||
var _current_indent := 0
|
||||
|
||||
## The current text style flags (BOLD, ITALIC, UNDERLINE) to be used for the next output operation
|
||||
var _current_flags := 0
|
||||
|
||||
## The current text alignment to be used for the next output operation
|
||||
var _current_align := Align.LEFT
|
||||
|
||||
## The current text effect to be used for the next output operation
|
||||
var _current_effect := Effect.NONE
|
||||
|
||||
|
||||
## Sets the text color for the next output operation.[br]
|
||||
## [br]
|
||||
## [param value] The color to be used for the text.
|
||||
## Returns self for method chaining.
|
||||
func color(value: Color) -> GdUnitMessageWriter:
|
||||
_current_color = value
|
||||
return self
|
||||
|
||||
|
||||
## Sets the indentation level for the next output operation.[br]
|
||||
## [br]
|
||||
## [param value] The number of indentation levels, where each level equals two spaces.
|
||||
## Returns self for method chaining.
|
||||
func indent(value: int) -> GdUnitMessageWriter:
|
||||
_current_indent = value
|
||||
return self
|
||||
|
||||
|
||||
## Sets text style flags for the next output operation.[br]
|
||||
## [br]
|
||||
## [param value] A combination of style flags (BOLD, ITALIC, UNDERLINE).
|
||||
## Returns self for method chaining.
|
||||
func style(value: int) -> GdUnitMessageWriter:
|
||||
_current_flags = value
|
||||
return self
|
||||
|
||||
|
||||
## Sets text effect for the next output operation.[br]
|
||||
## [br]
|
||||
## [param value] The effect to apply to the text (NONE, WAVE).
|
||||
## Returns self for method chaining.
|
||||
func effect(value: Effect) -> GdUnitMessageWriter:
|
||||
_current_effect = value
|
||||
return self
|
||||
|
||||
|
||||
## Sets text alignment for the next output operation.[br]
|
||||
## [br]
|
||||
## [param value] The alignment to use (LEFT, RIGHT).
|
||||
## Returns self for method chaining.
|
||||
func align(value: Align) -> GdUnitMessageWriter:
|
||||
_current_align = value
|
||||
return self
|
||||
|
||||
|
||||
## Resets all formatting options to their default values.[br]
|
||||
## [br]
|
||||
## Defaults:[br]
|
||||
## - color: Color.WHITE[br]
|
||||
## - indent: 0[br]
|
||||
## - flags: 0[br]
|
||||
## - align: LEFT[br]
|
||||
## - effect: NONE[br]
|
||||
## Returns self for method chaining.
|
||||
func reset() -> GdUnitMessageWriter:
|
||||
_current_color = Color.WHITE
|
||||
_current_indent = 0
|
||||
_current_flags = 0
|
||||
_current_align = Align.LEFT
|
||||
_current_effect = Effect.NONE
|
||||
return self
|
||||
|
||||
|
||||
## Prints a warning message in golden color.[br]
|
||||
## [br]
|
||||
## [param message] The warning message to print.
|
||||
func prints_warning(message: String) -> void:
|
||||
color(Color.GOLDENROD).println_message(message)
|
||||
|
||||
|
||||
## Prints an error message in crimson color.[br]
|
||||
## [br]
|
||||
## [param message] The error message to print.
|
||||
func prints_error(message: String) -> void:
|
||||
color(Color.CRIMSON).println_message(message)
|
||||
|
||||
|
||||
## Prints a message with current formatting settings.[br]
|
||||
## [br]
|
||||
## [param message] The text to print.
|
||||
func print_message(message: String) -> void:
|
||||
_print_message(message, _current_color, _current_indent, _current_flags)
|
||||
reset()
|
||||
|
||||
|
||||
## Prints a message with current formatting settings followed by a newline.[br]
|
||||
## [br]
|
||||
## [param message] The text to print.
|
||||
func println_message(message: String) -> void:
|
||||
_println_message(message, _current_color, _current_indent, _current_flags)
|
||||
reset()
|
||||
|
||||
|
||||
## Prints a message at a specific column position with current formatting settings.[br]
|
||||
## [br]
|
||||
## [param message] The text to print.[br]
|
||||
## [param cursor_pos] The column position where the text should start.
|
||||
func print_at(message: String, cursor_pos: int) -> void:
|
||||
_print_at(message, cursor_pos, _current_color, _current_effect, _current_align, _current_flags)
|
||||
reset()
|
||||
|
||||
|
||||
## Internal implementation of print_message.[br]
|
||||
## [br]
|
||||
## To be overridden by concrete formatters.[br]
|
||||
## [br]
|
||||
## [param message] The text to print.[br]
|
||||
## [param color] The color to use.[br]
|
||||
## [param indent] The indentation level.[br]
|
||||
## [param flags] The style flags to apply.
|
||||
func _print_message(_message: String, _color: Color, _indent: int, _flags: int) -> void:
|
||||
pass
|
||||
|
||||
|
||||
## Internal implementation of println_message.[br]
|
||||
## [br]
|
||||
## To be overridden by concrete formatters.[br]
|
||||
## [br]
|
||||
## [param message] The text to print.[br]
|
||||
## [param color] The color to use.[br]
|
||||
## [param indent] The indentation level.[br]
|
||||
## [param flags] The style flags to apply.
|
||||
func _println_message(_message: String, _color: Color, _indent: int, _flags: int) -> void:
|
||||
pass
|
||||
|
||||
|
||||
## Internal implementation of print_at.[br]
|
||||
## [br]
|
||||
## To be overridden by concrete formatters.[br]
|
||||
## [br]
|
||||
## [param message] The text to print.[br]
|
||||
## [param cursor_pos] The column position.[br]
|
||||
## [param color] The color to use.[br]
|
||||
## [param effect] The effect to apply.[br]
|
||||
## [param align] The text alignment.[br]
|
||||
## [param flags] The style flags to apply.
|
||||
func _print_at(_message: String, _cursor_pos: int, _color: Color, _effect: Effect, _align: Align, _flags: int) -> void:
|
||||
pass
|
||||
|
||||
|
||||
## Clears all output content.[br]
|
||||
## [br]
|
||||
## To be overridden by concrete formatters.
|
||||
func clear() -> void:
|
||||
pass
|
||||
@@ -1 +0,0 @@
|
||||
uid://dlf6gid7myugk
|
||||
@@ -1,115 +0,0 @@
|
||||
@tool
|
||||
class_name GdUnitRichTextMessageWriter
|
||||
extends GdUnitMessageWriter
|
||||
## A message writer implementation using [RichTextLabel] for the test report UI.[br]
|
||||
## [br]
|
||||
## This writer implementation writes formatted messages to a [RichTextLabel] using BBCode.[br]
|
||||
## It supports:[br]
|
||||
## - Text formatting using BBCode (bold, italic, underline)[br]
|
||||
## - Text coloring using push colors[br]
|
||||
## - Text indentation using push indent[br]
|
||||
## - Text effects like wave[br]
|
||||
## - Basic cursor positioning[br]
|
||||
## [br]
|
||||
## Used to format test reports in the editor UI.
|
||||
|
||||
|
||||
## The [RichTextLabel] instance to write formatted messages
|
||||
var _output: RichTextLabel
|
||||
|
||||
## Tracks current position in characters from line start
|
||||
var _current_pos := 0
|
||||
|
||||
|
||||
## Creates a new message writer for the given [RichTextLabel].[br]
|
||||
## [br]
|
||||
## [param output] The [RichTextLabel] used for output.
|
||||
func _init(output: RichTextLabel) -> void:
|
||||
_output = output
|
||||
|
||||
|
||||
## Applies text style flags by wrapping text in BBCode tags.[br]
|
||||
## [br]
|
||||
## Available styles:[br]
|
||||
## - BOLD: [b]text[/b][br]
|
||||
## - ITALIC: [i]text[/i][br]
|
||||
## - UNDERLINE: [u]text[/u][br]
|
||||
## [br]
|
||||
## [param message] The text to format.[br]
|
||||
## [param flags] The text style flags to apply.
|
||||
func _apply_flags(message: String, flags: int) -> String:
|
||||
if flags & BOLD:
|
||||
message = "[b]%s[/b]" % message
|
||||
if flags & ITALIC:
|
||||
message = "[i]%s[/i]" % message
|
||||
if flags & UNDERLINE:
|
||||
message = "[u]%s[/u]" % message
|
||||
return message
|
||||
|
||||
|
||||
## Writes a message with formatting.[br]
|
||||
## [br]
|
||||
## [param message] The text to write.[br]
|
||||
## [param _color] The color to use.[br]
|
||||
## [param _indent] The indentation level.[br]
|
||||
## [param flags] The text style flags to apply.
|
||||
func _print_message(message: String, _color: Color, _indent: int, flags: int) -> void:
|
||||
for i in _indent:
|
||||
_output.push_indent(1)
|
||||
_output.push_color(_color)
|
||||
message = _apply_flags(message, flags)
|
||||
_output.append_text(message)
|
||||
_output.pop()
|
||||
for i in _indent:
|
||||
_output.pop()
|
||||
_current_pos += _indent * 2 + message.length()
|
||||
|
||||
|
||||
## Writes a message with formatting followed by a line break.[br]
|
||||
## [br]
|
||||
## [param message] The text to write.[br]
|
||||
## [param _color] The color to use.[br]
|
||||
## [param _indent] The indentation level.[br]
|
||||
## [param flags] The text style flags to apply.
|
||||
func _println_message(message: String, _color: Color, _indent: int, flags: int) -> void:
|
||||
_print_message(message, _color, _indent, flags)
|
||||
_output.newline()
|
||||
_current_pos = 0
|
||||
|
||||
|
||||
## Writes a message at a specific column position.[br]
|
||||
## [br]
|
||||
## [param message] The text to write.[br]
|
||||
## [param cursor_pos] The column position from line start.[br]
|
||||
## [param _color] The color to use.[br]
|
||||
## [param _effect] The text effect to apply (e.g. wave).[br]
|
||||
## [param _align] The text alignment (left or right).[br]
|
||||
## [param flags] The text style flags to apply.
|
||||
func _print_at(message: String, cursor_pos: int, _color: Color, _effect: Effect, _align: Align, flags: int) -> void:
|
||||
if _align == Align.RIGHT:
|
||||
cursor_pos = cursor_pos - message.length()
|
||||
|
||||
var spaces := cursor_pos - _current_pos
|
||||
if spaces > 0:
|
||||
_output.append_text("".lpad(spaces))
|
||||
_current_pos += spaces
|
||||
else:
|
||||
_output.append_text(" ")
|
||||
_current_pos += 1
|
||||
|
||||
_output.push_color(_color)
|
||||
message = _apply_flags(message, flags)
|
||||
match _effect:
|
||||
Effect.NONE:
|
||||
pass
|
||||
Effect.WAVE:
|
||||
message = "[wave]%s[/wave]" % message
|
||||
_output.append_text(message)
|
||||
_output.pop()
|
||||
_current_pos += message.length()
|
||||
|
||||
|
||||
## Clears all written content from the [RichTextLabel].
|
||||
func clear() -> void:
|
||||
_output.clear()
|
||||
_current_pos = 0
|
||||
@@ -1 +0,0 @@
|
||||
uid://dasu47qjmnlks
|
||||
Reference in New Issue
Block a user