Skip to content

Commit 8d7d7a6

Browse files
committed
Update GDUnit
1 parent d3339b1 commit 8d7d7a6

27 files changed

+609
-257
lines changed

addons/gdUnit4/bin/GdUnitCmdTool.gd

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class CLIRunner extends Node:
2727
var _runner_config := GdUnitRunnerConfig.new()
2828
var _console := CmdConsole.new()
2929
var _cs_executor
30-
var _rtf :RichTextLabel
3130
var _cmd_options: = CmdOptions.new([
3231
CmdOption.new("-a, --add", "-a <directory|path of testsuite>", "Adds the given test suite or directory to the execution pipeline.", TYPE_STRING),
3332
CmdOption.new("-i, --ignore", "-i <testsuite_name|testsuite_name:test-name>", "Adds the given test suite or test case to the ignore list.", TYPE_STRING),
@@ -62,8 +61,6 @@ class CLIRunner extends Node:
6261
push_error("Error checked startup, can't connect executor for 'send_event'")
6362
quit(RETURN_ERROR)
6463
add_child(_executor)
65-
_rtf = RichTextLabel.new()
66-
add_child(_rtf)
6764

6865

6966
func _process(_delta):
@@ -93,14 +90,8 @@ class CLIRunner extends Node:
9390
func quit(code :int) -> void:
9491
if is_instance_valid(_executor):
9592
_executor.free()
96-
if is_instance_valid(_rtf):
97-
_rtf.free()
9893
GdUnitTools.dispose_all()
9994
await get_tree().physics_frame
100-
prints("-Orphan nodes report-----------------------")
101-
Window.print_orphan_nodes()
102-
prints("-SceneTree report-----------------------")
103-
get_tree().root.print_tree_pretty()
10495
get_tree().quit(code)
10596

10697

@@ -308,25 +299,35 @@ class CLIRunner extends Node:
308299
GdUnitEvent.STOP:
309300
var report_path := _report.write()
310301
_report.delete_history(_report_max)
311-
JUnitXmlReport.new(_report._report_path, _report.iteration(), _rtf).write(_report)
302+
JUnitXmlReport.new(_report._report_path, _report.iteration()).write(_report)
312303
_console.prints_color("Total test suites: %s" % _report.suite_count(), Color.DARK_SALMON)
313304
_console.prints_color("Total test cases: %s" % _report.test_count(), Color.DARK_SALMON)
314305
_console.prints_color("Total time: %s" % LocalTime.elapsed(_report.duration()), Color.DARK_SALMON)
315306
_console.prints_color("Open Report at: file://%s" % report_path, Color.CORNFLOWER_BLUE)
316307
GdUnitEvent.TESTSUITE_BEFORE:
317308
_report.add_testsuite_report(GdUnitTestSuiteReport.new(event.resource_path(), event.suite_name()))
318309
GdUnitEvent.TESTSUITE_AFTER:
319-
_report.update_test_suite_report(event.resource_path(), event.elapsed_time())
310+
_report.update_test_suite_report(
311+
event.resource_path(),
312+
event.elapsed_time(),
313+
event.is_error(),
314+
event.is_failed(),
315+
event.is_warning(),
316+
event.is_skipped(),
317+
event.skipped_count(),
318+
event.failed_count(),
319+
event.orphan_nodes(),
320+
event.reports())
320321
GdUnitEvent.TESTCASE_BEFORE:
321-
_report.add_testcase_report(event.resource_path(), GdUnitTestCaseReport.new(_rtf, event.resource_path(), event.suite_name(), event.test_name()))
322+
_report.add_testcase_report(event.resource_path(), GdUnitTestCaseReport.new(event.resource_path(), event.suite_name(), event.test_name()))
322323
GdUnitEvent.TESTCASE_AFTER:
323324
var test_report := GdUnitTestCaseReport.new(
324-
_rtf,
325325
event.resource_path(),
326326
event.suite_name(),
327327
event.test_name(),
328328
event.is_error(),
329329
event.is_failed(),
330+
event.failed_count(),
330331
event.orphan_nodes(),
331332
event.is_skipped(),
332333
event.reports(),
@@ -358,17 +359,17 @@ class CLIRunner extends Node:
358359
_print_status(event)
359360
_print_failure_report(event.reports())
360361
GdUnitEvent.TESTSUITE_AFTER:
362+
_print_failure_report(event.reports())
361363
_print_status(event)
362364
_console.prints_color(" | %d total | %d error | %d failed | %d skipped | %d orphans |\n" % [_report.test_count(), _report.error_count(), _report.failure_count(), _report.skipped_count(), _report.orphan_count()], Color.ANTIQUE_WHITE)
363365

364366

365367
func _print_failure_report(reports :Array) -> void:
366368
for report in reports:
367-
_rtf.clear()
368-
_rtf.parse_bbcode(report._to_string())
369369
if report.is_failure() or report.is_error() or report.is_warning() or report.is_skipped():
370370
_console.prints_color(" Report:", Color.DARK_TURQUOISE, CmdConsole.BOLD|CmdConsole.UNDERLINE)
371-
for line in _rtf.get_parsed_text().split("\n"):
371+
var text = GdUnitTools.richtext_normalize(report._to_string())
372+
for line in text.split("\n"):
372373
_console.prints_color(" %s" % line, Color.DARK_TURQUOISE)
373374
_console.new_line()
374375

@@ -397,3 +398,8 @@ func _initialize():
397398
func _finalize():
398399
prints("Finallize ..")
399400
_cli_runner.free()
401+
prints("-Orphan nodes report-----------------------")
402+
Window.print_orphan_nodes()
403+
prints("-SceneTree report-----------------------")
404+
root.print_tree_pretty()
405+
prints("Finallize .. done")

addons/gdUnit4/plugin.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
name="gdUnit4"
44
description="Unit Testing Framework for Godot Scripts"
55
author="Mike Schulze"
6-
version="4.1.3"
6+
version="4.1.4"
77
script="plugin.gd"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## An assertion tool to verify for Godot runtime errors like assert() and push notifications like push_error().
2+
class_name GdUnitGodotErrorAssert
3+
extends GdUnitAssert
4+
5+
6+
## Verifies if the executed code runs without any runtime errors
7+
## Usage:
8+
## [codeblock]
9+
## await assert_error(<callable>).is_success()
10+
## [/codeblock]
11+
func is_success() -> GdUnitGodotErrorAssert:
12+
await Engine.get_main_loop().process_frame
13+
return self
14+
15+
16+
## Verifies if the executed code runs into a runtime error
17+
## Usage:
18+
## [codeblock]
19+
## await assert_error(<callable>).is_runtime_error(<expected error message>)
20+
## [/codeblock]
21+
@warning_ignore("unused_parameter")
22+
func is_runtime_error(expected_error :String) -> GdUnitGodotErrorAssert:
23+
await Engine.get_main_loop().process_frame
24+
return self
25+
26+
27+
## Verifies if the executed code has a push_warning() used
28+
## Usage:
29+
## [codeblock]
30+
## await assert_error(<callable>).is_push_warning(<expected push warning message>)
31+
## [/codeblock]
32+
@warning_ignore("unused_parameter")
33+
func is_push_warning(expected_warning :String) -> GdUnitGodotErrorAssert:
34+
await Engine.get_main_loop().process_frame
35+
return self
36+
37+
38+
## Verifies if the executed code has a push_error() used
39+
## Usage:
40+
## [codeblock]
41+
## await assert_error(<callable>).is_push_error(<expected push error message>)
42+
## [/codeblock]
43+
@warning_ignore("unused_parameter")
44+
func is_push_error(expected_error :String) -> GdUnitGodotErrorAssert:
45+
await Engine.get_main_loop().process_frame
46+
return self

addons/gdUnit4/src/GdUnitTestSuite.gd

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ extends Node
1717

1818
const NO_ARG = GdUnitConstants.NO_ARG
1919

20+
### internal runtime variables that must not be overwritten!!!
21+
var __is_skipped := false
22+
var __skip_reason :String = "Unknow."
23+
24+
2025
## This function is called before a test suite starts[br]
2126
## You can overwrite to prepare test data or initalizize necessary variables
2227
func before() -> void:
@@ -41,19 +46,10 @@ func after_test() -> void:
4146
pass
4247

4348

44-
## Skip the test-suite from execution, it will be ignored
45-
func skip(skipped :bool) -> void:
46-
set_meta("gd_skipped", skipped)
47-
48-
4949
func is_failure(_expected_failure :String = NO_ARG) -> bool:
5050
return Engine.get_meta("GD_TEST_FAILURE") if Engine.has_meta("GD_TEST_FAILURE") else false
5151

5252

53-
func is_skipped() -> bool:
54-
return get_meta("gd_skipped") if has_meta("gd_skipped") else false
55-
56-
5753
var __active_test_case :String
5854
func set_active_test_case(test_case :String) -> void:
5955
__active_test_case = test_case
@@ -525,15 +521,42 @@ func assert_signal(instance :Object) -> GdUnitSignalAssert:
525521
return GdUnitSignalAssertImpl.new(instance)
526522

527523

528-
## Verifiys an assertion is failing as expected
529-
## This assert is only designed for internal use to verify failing asserts working as expected
524+
## An assertion tool to test for failing assertions.[br]
525+
## This assert is only designed for internal use to verify failing asserts working as expected.[br]
530526
## Usage:
531527
## [codeblock]
532528
## assert_failure(func(): assert_bool(true).is_not_equal(true)) \
533-
## .has_message("Expecting:\n 'true'\n not equal to\n 'true'")
529+
## .has_message("Expecting:\n 'true'\n not equal to\n 'true'")
534530
## [/codeblock]
535531
func assert_failure(assertion :Callable) -> GdUnitFailureAssert:
536-
return GdUnitFailureAssertImpl.new(assertion)
532+
return GdUnitFailureAssertImpl.new().execute(assertion)
533+
534+
535+
## An assertion tool to test for failing assertions.[br]
536+
## This assert is only designed for internal use to verify failing asserts working as expected.[br]
537+
## Usage:
538+
## [codeblock]
539+
## await assert_failure_await(func(): assert_bool(true).is_not_equal(true)) \
540+
## .has_message("Expecting:\n 'true'\n not equal to\n 'true'")
541+
## [/codeblock]
542+
func assert_failure_await(assertion :Callable) -> GdUnitFailureAssert:
543+
return await GdUnitFailureAssertImpl.new().execute_and_await(assertion)
544+
545+
546+
## An assertion tool to verify for Godot errors.[br]
547+
## You can use to verify for certain Godot erros like failing assertions, push_error, push_warn.[br]
548+
## Usage:
549+
## [codeblock]
550+
## # tests no error was occured during execution the code
551+
## await assert_error(func (): return 0 )\
552+
## .is_success()
553+
##
554+
## # tests an push_error('test error') was occured during execution the code
555+
## await assert_error(func (): push_error('test error') )\
556+
## .is_push_error('test error')
557+
## [/codeblock]
558+
func assert_error(current :Callable) -> GdUnitGodotErrorAssert:
559+
return GdUnitGodotErrorAssertImpl.new(current)
537560

538561

539562
## Utility to check if a test has failed in a particular line and if there is an error message

addons/gdUnit4/src/asserts/GdAssertMessages.gd

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,21 @@ static func test_timeout(timeout :int) -> String:
156156
return "%s\n %s" % [_error("Timeout !"), _colored_value("Test timed out after %s" % LocalTime.elapsed(timeout))]
157157

158158

159+
static func test_suite_skipped(hint :String, skip_count) -> String:
160+
return """
161+
%s
162+
Tests skipped: %s
163+
Reason: %s
164+
""".dedent().trim_prefix("\n")\
165+
% [_error("Entire test-suite is skipped!"), _colored_value(skip_count), _colored_value(hint)]
166+
167+
159168
static func test_skipped(hint :String) -> String:
160-
return "%s\n %s" % [_error("This test is skipped!"), "Reason: %s" % _colored_value(hint)]
169+
return """
170+
%s
171+
Reason: %s
172+
""".dedent().trim_prefix("\n")\
173+
% [_error("This test is skipped!"), _colored_value(hint)]
161174

162175

163176
static func error_not_implemented() -> String:

addons/gdUnit4/src/asserts/GdAssertReports.gd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ const LAST_ERROR = "last_assert_error_message"
55
const LAST_ERROR_LINE = "last_assert_error_line"
66

77

8-
static func report_success(_line_number :int) -> void:
8+
static func report_success() -> void:
99
GdUnitSignals.instance().gdunit_set_test_failed.emit(false)
10+
GdAssertReports.set_last_error_line_number(-1)
1011
Engine.remove_meta(LAST_ERROR)
1112

1213

@@ -17,6 +18,7 @@ static func report_warning(message :String, line_number :int) -> void:
1718

1819
static func report_error(message:String, line_number :int) -> void:
1920
GdUnitSignals.instance().gdunit_set_test_failed.emit(true)
21+
GdAssertReports.set_last_error_line_number(line_number)
2022
Engine.set_meta(LAST_ERROR, message)
2123
# if we expect to fail we handle as success test
2224
if is_expect_fail():

addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func __validate_value_type(value, type :Variant.Type) -> bool:
5050

5151

5252
func report_success() -> GdUnitAssert:
53-
GdAssertReports.report_success(GdUnitAssertImpl._get_line_number())
53+
GdAssertReports.report_success()
5454
return self
5555

5656

@@ -67,12 +67,7 @@ func test_fail():
6767

6868

6969
static func _normalize_bbcode(message :String) -> String:
70-
var rtl := RichTextLabel.new()
71-
rtl.bbcode_enabled = true
72-
rtl.append_text(message if message else "")
73-
var normalized = rtl.get_parsed_text()
74-
rtl.free()
75-
return normalized.replace("\r", "")
70+
return GdUnitTools.richtext_normalize(message).replace("\r", "")
7671

7772

7873
func override_failure_message(message :String):

addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
class_name GdUnitFailureAssertImpl
22
extends GdUnitFailureAssert
33

4-
var _gdunit_signals := GdUnitSignals.instance()
5-
var _current :GdUnitAssert
64
var _is_failed := false
75
var _failure_message :String
86

97

10-
func _init(assertion :Callable):
8+
func execute_and_await(assertion :Callable, do_await := true) -> GdUnitFailureAssert:
119
# do not report any failure from the original assertion we want to test
1210
GdAssertReports.expect_fail(true)
1311
var thread_context := GdUnitThreadManager.get_current_context()
1412
thread_context.set_assert(null)
1513
GdUnitSignals.instance().gdunit_set_test_failed.connect(_on_test_failed)
16-
1714
# execute the given assertion as callable
18-
assertion.call()
15+
if do_await:
16+
await assertion.call()
17+
else:
18+
assertion.call()
1919
GdAssertReports.expect_fail(false)
2020
# get the assert instance from current tread context
21-
_current = thread_context.get_assert()
22-
if not is_instance_of(_current, GdUnitAssert):
21+
var current_assert := thread_context.get_assert()
22+
if not is_instance_of(current_assert, GdUnitAssert):
2323
_is_failed = true
2424
_failure_message = "Invalid Callable! It must be a callable of 'GdUnitAssert'"
2525
return
26-
_failure_message = _current._failure_message()
26+
_failure_message = current_assert._failure_message()
27+
return self
28+
29+
30+
func execute(assertion :Callable) -> GdUnitFailureAssert:
31+
execute_and_await(assertion, false)
32+
return self
2733

2834

2935
func _on_test_failed(value :bool) -> void:
@@ -89,17 +95,10 @@ func starts_with_message(expected :String) -> GdUnitFailureAssert:
8995

9096
func _report_error(error_message :String, failure_line_number: int = -1) -> GdUnitAssert:
9197
var line_number := failure_line_number if failure_line_number != -1 else GdUnitAssertImpl._get_line_number()
92-
GdAssertReports.set_last_error_line_number(line_number)
93-
GdUnitSignals.instance().gdunit_set_test_failed.emit(true)
94-
_send_report(GdUnitReport.new().create(GdUnitReport.FAILURE, line_number, error_message))
98+
GdAssertReports.report_error(error_message, line_number)
9599
return self
96100

97101

98102
func _report_success() -> GdUnitFailureAssert:
99-
GdAssertReports.set_last_error_line_number(-1)
100-
GdUnitSignals.instance().gdunit_set_test_failed.emit(false)
103+
GdAssertReports.report_success()
101104
return self
102-
103-
104-
func _send_report(report :GdUnitReport)-> void:
105-
_gdunit_signals.gdunit_report.emit(report)

addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func _notification(_what):
3333

3434

3535
func report_success() -> GdUnitAssert:
36-
GdAssertReports.report_success(_line_number)
36+
GdAssertReports.report_success()
3737
return self
3838

3939

0 commit comments

Comments
 (0)