Adding log.gd
This commit is contained in:
parent
eb32d6614e
commit
4522259397
547 changed files with 46844 additions and 0 deletions
25
addons/gdUnit4/src/asserts/CallBackValueProvider.gd
Normal file
25
addons/gdUnit4/src/asserts/CallBackValueProvider.gd
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# a value provider unsing a callback to get `next` value from a certain function
|
||||
class_name CallBackValueProvider
|
||||
extends ValueProvider
|
||||
|
||||
var _cb :Callable
|
||||
var _args :Array
|
||||
|
||||
|
||||
func _init(instance :Object, func_name :String, args :Array = Array(), force_error := true):
|
||||
_cb = Callable(instance, func_name);
|
||||
_args = args
|
||||
if force_error and not _cb.is_valid():
|
||||
push_error("Can't find function '%s' checked instance %s" % [func_name, instance])
|
||||
|
||||
|
||||
func get_value() -> Variant:
|
||||
if not _cb.is_valid():
|
||||
return null
|
||||
if _args.is_empty():
|
||||
return await _cb.call()
|
||||
return await _cb.callv(_args)
|
||||
|
||||
|
||||
func dispose():
|
||||
_cb = Callable()
|
||||
12
addons/gdUnit4/src/asserts/DefaultValueProvider.gd
Normal file
12
addons/gdUnit4/src/asserts/DefaultValueProvider.gd
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# default value provider, simple returns the initial value
|
||||
class_name DefaultValueProvider
|
||||
extends ValueProvider
|
||||
|
||||
var _value
|
||||
|
||||
func _init(value):
|
||||
_value = value
|
||||
|
||||
|
||||
func get_value():
|
||||
return _value
|
||||
608
addons/gdUnit4/src/asserts/GdAssertMessages.gd
Normal file
608
addons/gdUnit4/src/asserts/GdAssertMessages.gd
Normal file
|
|
@ -0,0 +1,608 @@
|
|||
class_name GdAssertMessages
|
||||
extends Resource
|
||||
|
||||
const WARN_COLOR = "#EFF883"
|
||||
const ERROR_COLOR = "#CD5C5C"
|
||||
const VALUE_COLOR = "#1E90FF"
|
||||
const SUB_COLOR := Color(1, 0, 0, .3)
|
||||
const ADD_COLOR := Color(0, 1, 0, .3)
|
||||
|
||||
|
||||
static func format_dict(value :Dictionary) -> String:
|
||||
if value.is_empty():
|
||||
return "{ }"
|
||||
var as_rows := var_to_str(value).split("\n")
|
||||
for index in range( 1, as_rows.size()-1):
|
||||
as_rows[index] = " " + as_rows[index]
|
||||
as_rows[-1] = " " + as_rows[-1]
|
||||
return "\n".join(as_rows)
|
||||
|
||||
|
||||
# improved version of InputEvent as text
|
||||
static func input_event_as_text(event :InputEvent) -> String:
|
||||
var text := ""
|
||||
if event is InputEventKey:
|
||||
text += "InputEventKey : key='%s', pressed=%s, keycode=%d, physical_keycode=%s" % [
|
||||
event.as_text(), event.pressed, event.keycode, event.physical_keycode]
|
||||
else:
|
||||
text += event.as_text()
|
||||
if event is InputEventMouse:
|
||||
text += ", global_position %s" % event.global_position
|
||||
if event is InputEventWithModifiers:
|
||||
text += ", shift=%s, alt=%s, control=%s, meta=%s, command=%s" % [
|
||||
event.shift_pressed, event.alt_pressed, event.ctrl_pressed, event.meta_pressed, event.command_or_control_autoremap]
|
||||
return text
|
||||
|
||||
|
||||
static func _colored_string_div(characters :String) -> String:
|
||||
return colored_array_div(characters.to_ascii_buffer())
|
||||
|
||||
|
||||
static func colored_array_div(characters :PackedByteArray) -> String:
|
||||
if characters.is_empty():
|
||||
return "<empty>"
|
||||
var result = PackedByteArray()
|
||||
var index = 0
|
||||
var missing_chars := PackedByteArray()
|
||||
var additional_chars := PackedByteArray()
|
||||
|
||||
while index < characters.size():
|
||||
var character := characters[index]
|
||||
match character:
|
||||
GdDiffTool.DIV_ADD:
|
||||
index += 1
|
||||
additional_chars.append(characters[index])
|
||||
GdDiffTool.DIV_SUB:
|
||||
index += 1
|
||||
missing_chars.append(characters[index])
|
||||
_:
|
||||
if not missing_chars.is_empty():
|
||||
result.append_array(format_chars(missing_chars, SUB_COLOR))
|
||||
missing_chars = PackedByteArray()
|
||||
if not additional_chars.is_empty():
|
||||
result.append_array(format_chars(additional_chars, ADD_COLOR))
|
||||
additional_chars = PackedByteArray()
|
||||
result.append(character)
|
||||
index += 1
|
||||
|
||||
result.append_array(format_chars(missing_chars, SUB_COLOR))
|
||||
result.append_array(format_chars(additional_chars, ADD_COLOR))
|
||||
return result.get_string_from_utf8()
|
||||
|
||||
|
||||
static func _typed_value(value) -> String:
|
||||
return GdDefaultValueDecoder.decode(value)
|
||||
|
||||
|
||||
static func _warning(error :String) -> String:
|
||||
return "[color=%s]%s[/color]" % [WARN_COLOR, error]
|
||||
|
||||
|
||||
static func _error(error :String) -> String:
|
||||
return "[color=%s]%s[/color]" % [ERROR_COLOR, error]
|
||||
|
||||
|
||||
static func _nerror(number) -> String:
|
||||
match typeof(number):
|
||||
TYPE_INT:
|
||||
return "[color=%s]%d[/color]" % [ERROR_COLOR, number]
|
||||
TYPE_FLOAT:
|
||||
return "[color=%s]%f[/color]" % [ERROR_COLOR, number]
|
||||
_:
|
||||
return "[color=%s]%s[/color]" % [ERROR_COLOR, str(number)]
|
||||
|
||||
|
||||
static func _colored_value(value, _delimiter ="\n") -> String:
|
||||
match typeof(value):
|
||||
TYPE_STRING, TYPE_STRING_NAME:
|
||||
return "'[color=%s]%s[/color]'" % [VALUE_COLOR, _colored_string_div(value)]
|
||||
TYPE_INT:
|
||||
return "'[color=%s]%d[/color]'" % [VALUE_COLOR, value]
|
||||
TYPE_FLOAT:
|
||||
return "'[color=%s]%s[/color]'" % [VALUE_COLOR, _typed_value(value)]
|
||||
TYPE_COLOR:
|
||||
return "'[color=%s]%s[/color]'" % [VALUE_COLOR, _typed_value(value)]
|
||||
TYPE_OBJECT:
|
||||
if value == null:
|
||||
return "'[color=%s]<null>[/color]'" % [VALUE_COLOR]
|
||||
if value is InputEvent:
|
||||
return "[color=%s]<%s>[/color]" % [VALUE_COLOR, input_event_as_text(value)]
|
||||
if value.has_method("_to_string"):
|
||||
return "[color=%s]<%s>[/color]" % [VALUE_COLOR, str(value)]
|
||||
return "[color=%s]<%s>[/color]" % [VALUE_COLOR, value.get_class()]
|
||||
TYPE_DICTIONARY:
|
||||
return "'[color=%s]%s[/color]'" % [VALUE_COLOR, format_dict(value)]
|
||||
_:
|
||||
if GdArrayTools.is_array_type(value):
|
||||
return "'[color=%s]%s[/color]'" % [VALUE_COLOR, _typed_value(value)]
|
||||
return "'[color=%s]%s[/color]'" % [VALUE_COLOR, value]
|
||||
|
||||
|
||||
static func _index_report_as_table(index_reports :Array) -> String:
|
||||
var table := "[table=3]$cells[/table]"
|
||||
var header := "[cell][right][b]$text[/b][/right]\t[/cell]"
|
||||
var cell := "[cell][right]$text[/right]\t[/cell]"
|
||||
var cells := header.replace("$text", "Index") + header.replace("$text", "Current") + header.replace("$text", "Expected")
|
||||
for report in index_reports:
|
||||
var index :String = str(report["index"])
|
||||
var current :String = str(report["current"])
|
||||
var expected :String = str(report["expected"])
|
||||
cells += cell.replace("$text", index) + cell.replace("$text", current) + cell.replace("$text", expected)
|
||||
return table.replace("$cells", cells)
|
||||
|
||||
|
||||
static func orphan_detected_on_suite_setup(count :int):
|
||||
return "%s\n Detected <%d> orphan nodes during test suite setup stage! [b]Check before() and after()![/b]" % [
|
||||
_warning("WARNING:"), count]
|
||||
|
||||
|
||||
static func orphan_detected_on_test_setup(count :int):
|
||||
return "%s\n Detected <%d> orphan nodes during test setup! [b]Check before_test() and after_test()![/b]" % [
|
||||
_warning("WARNING:"), count]
|
||||
|
||||
|
||||
static func orphan_detected_on_test(count :int):
|
||||
return "%s\n Detected <%d> orphan nodes during test execution!" % [
|
||||
_warning("WARNING:"), count]
|
||||
|
||||
|
||||
static func fuzzer_interuped(iterations: int, error: String) -> String:
|
||||
return "%s %s %s\n %s" % [
|
||||
_error("Found an error after"),
|
||||
_colored_value(iterations + 1),
|
||||
_error("test iterations"),
|
||||
error]
|
||||
|
||||
|
||||
static func test_timeout(timeout :int) -> String:
|
||||
return "%s\n %s" % [_error("Timeout !"), _colored_value("Test timed out after %s" % LocalTime.elapsed(timeout))]
|
||||
|
||||
|
||||
# gdlint:disable = mixed-tabs-and-spaces
|
||||
static func test_suite_skipped(hint :String, skip_count) -> String:
|
||||
return """
|
||||
%s
|
||||
Tests skipped: %s
|
||||
Reason: %s
|
||||
""".dedent().trim_prefix("\n")\
|
||||
% [_error("Entire test-suite is skipped!"), _colored_value(skip_count), _colored_value(hint)]
|
||||
|
||||
|
||||
static func test_skipped(hint :String) -> String:
|
||||
return """
|
||||
%s
|
||||
Reason: %s
|
||||
""".dedent().trim_prefix("\n")\
|
||||
% [_error("This test is skipped!"), _colored_value(hint)]
|
||||
|
||||
|
||||
static func error_not_implemented() -> String:
|
||||
return _error("Test not implemented!")
|
||||
|
||||
|
||||
static func error_is_null(current) -> String:
|
||||
return "%s %s but was %s" % [_error("Expecting:"), _colored_value(null), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_not_null() -> String:
|
||||
return "%s %s" % [_error("Expecting: not to be"), _colored_value(null)]
|
||||
|
||||
|
||||
static func error_equal(current, expected, index_reports :Array = []) -> String:
|
||||
var report = """
|
||||
%s
|
||||
%s
|
||||
but was
|
||||
%s""".dedent().trim_prefix("\n") % [_error("Expecting:"), _colored_value(expected, true), _colored_value(current, true)]
|
||||
if not index_reports.is_empty():
|
||||
report += "\n\n%s\n%s" % [_error("Differences found:"), _index_report_as_table(index_reports)]
|
||||
return report
|
||||
|
||||
|
||||
static func error_not_equal(current, expected) -> String:
|
||||
return "%s\n %s\n not equal to\n %s" % [_error("Expecting:"), _colored_value(expected, true), _colored_value(current, true)]
|
||||
|
||||
|
||||
static func error_not_equal_case_insensetiv(current, expected) -> String:
|
||||
return "%s\n %s\n not equal to (case insensitiv)\n %s" % [
|
||||
_error("Expecting:"), _colored_value(expected, true), _colored_value(current, true)]
|
||||
|
||||
|
||||
static func error_is_empty(current) -> String:
|
||||
return "%s\n must be empty but was\n %s" % [_error("Expecting:"), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_not_empty() -> String:
|
||||
return "%s\n must not be empty" % [_error("Expecting:")]
|
||||
|
||||
|
||||
static func error_is_same(current, expected) -> String:
|
||||
return "%s\n %s\n to refer to the same object\n %s" % [_error("Expecting:"), _colored_value(expected), _colored_value(current)]
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter")
|
||||
static func error_not_same(_current, expected) -> String:
|
||||
return "%s\n %s" % [_error("Expecting not same:"), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_not_same_error(current, expected) -> String:
|
||||
return "%s\n %s\n but was\n %s" % [_error("Expecting error message:"), _colored_value(expected), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_instanceof(current: GdUnitResult, expected :GdUnitResult) -> String:
|
||||
return "%s\n %s\n But it was %s" % [_error("Expected instance of:"),\
|
||||
_colored_value(expected.or_else(null)), _colored_value(current.or_else(null))]
|
||||
|
||||
|
||||
# -- Boolean Assert specific messages -----------------------------------------------------
|
||||
static func error_is_true(current) -> String:
|
||||
return "%s %s but is %s" % [_error("Expecting:"), _colored_value(true), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_false(current) -> String:
|
||||
return "%s %s but is %s" % [_error("Expecting:"), _colored_value(false), _colored_value(current)]
|
||||
|
||||
|
||||
# - Integer/Float Assert specific messages -----------------------------------------------------
|
||||
|
||||
static func error_is_even(current) -> String:
|
||||
return "%s\n %s must be even" % [_error("Expecting:"), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_odd(current) -> String:
|
||||
return "%s\n %s must be odd" % [_error("Expecting:"), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_negative(current) -> String:
|
||||
return "%s\n %s be negative" % [_error("Expecting:"), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_not_negative(current) -> String:
|
||||
return "%s\n %s be not negative" % [_error("Expecting:"), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_zero(current) -> String:
|
||||
return "%s\n equal to 0 but is %s" % [_error("Expecting:"), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_is_not_zero() -> String:
|
||||
return "%s\n not equal to 0" % [_error("Expecting:")]
|
||||
|
||||
|
||||
static func error_is_wrong_type(current_type :Variant.Type, expected_type :Variant.Type) -> String:
|
||||
return "%s\n Expecting type %s but is %s" % [
|
||||
_error("Unexpected type comparison:"),
|
||||
_colored_value(GdObjects.type_as_string(current_type)),
|
||||
_colored_value(GdObjects.type_as_string(expected_type))]
|
||||
|
||||
|
||||
static func error_is_value(operation, current, expected, expected2=null) -> String:
|
||||
match operation:
|
||||
Comparator.EQUAL:
|
||||
return "%s\n %s but was '%s'" % [_error("Expecting:"), _colored_value(expected), _nerror(current)]
|
||||
Comparator.LESS_THAN:
|
||||
return "%s\n %s but was '%s'" % [_error("Expecting to be less than:"), _colored_value(expected), _nerror(current)]
|
||||
Comparator.LESS_EQUAL:
|
||||
return "%s\n %s but was '%s'" % [_error("Expecting to be less than or equal:"), _colored_value(expected), _nerror(current)]
|
||||
Comparator.GREATER_THAN:
|
||||
return "%s\n %s but was '%s'" % [_error("Expecting to be greater than:"), _colored_value(expected), _nerror(current)]
|
||||
Comparator.GREATER_EQUAL:
|
||||
return "%s\n %s but was '%s'" % [_error("Expecting to be greater than or equal:"), _colored_value(expected), _nerror(current)]
|
||||
Comparator.BETWEEN_EQUAL:
|
||||
return "%s\n %s\n in range between\n %s <> %s" % [
|
||||
_error("Expecting:"), _colored_value(current), _colored_value(expected), _colored_value(expected2)]
|
||||
Comparator.NOT_BETWEEN_EQUAL:
|
||||
return "%s\n %s\n not in range between\n %s <> %s" % [
|
||||
_error("Expecting:"), _colored_value(current), _colored_value(expected), _colored_value(expected2)]
|
||||
return "TODO create expected message"
|
||||
|
||||
|
||||
static func error_is_in(current, expected :Array) -> String:
|
||||
return "%s\n %s\n is in\n %s" % [_error("Expecting:"), _colored_value(current), _colored_value(str(expected))]
|
||||
|
||||
|
||||
static func error_is_not_in(current, expected :Array) -> String:
|
||||
return "%s\n %s\n is not in\n %s" % [_error("Expecting:"), _colored_value(current), _colored_value(str(expected))]
|
||||
|
||||
|
||||
# - StringAssert ---------------------------------------------------------------------------------
|
||||
static func error_equal_ignoring_case(current, expected) -> String:
|
||||
return "%s\n %s\n but was\n %s (ignoring case)" % [_error("Expecting:"), _colored_value(expected), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_contains(current, expected) -> String:
|
||||
return "%s\n %s\n do contains\n %s" % [_error("Expecting:"), _colored_value(current), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_not_contains(current, expected) -> String:
|
||||
return "%s\n %s\n not do contain\n %s" % [_error("Expecting:"), _colored_value(current), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_contains_ignoring_case(current, expected) -> String:
|
||||
return "%s\n %s\n contains\n %s\n (ignoring case)" % [_error("Expecting:"), _colored_value(current), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_not_contains_ignoring_case(current, expected) -> String:
|
||||
return "%s\n %s\n not do contains\n %s\n (ignoring case)" % [_error("Expecting:"), _colored_value(current), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_starts_with(current, expected) -> String:
|
||||
return "%s\n %s\n to start with\n %s" % [_error("Expecting:"), _colored_value(current), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_ends_with(current, expected) -> String:
|
||||
return "%s\n %s\n to end with\n %s" % [_error("Expecting:"), _colored_value(current), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_has_length(current, expected: int, compare_operator) -> String:
|
||||
var current_length = current.length() if current != null else null
|
||||
match compare_operator:
|
||||
Comparator.EQUAL:
|
||||
return "%s\n %s but was '%s' in\n %s" % [
|
||||
_error("Expecting size:"), _colored_value(expected), _nerror(current_length), _colored_value(current)]
|
||||
Comparator.LESS_THAN:
|
||||
return "%s\n %s but was '%s' in\n %s" % [
|
||||
_error("Expecting size to be less than:"), _colored_value(expected), _nerror(current_length), _colored_value(current)]
|
||||
Comparator.LESS_EQUAL:
|
||||
return "%s\n %s but was '%s' in\n %s" % [
|
||||
_error("Expecting size to be less than or equal:"), _colored_value(expected),
|
||||
_nerror(current_length), _colored_value(current)]
|
||||
Comparator.GREATER_THAN:
|
||||
return "%s\n %s but was '%s' in\n %s" % [
|
||||
_error("Expecting size to be greater than:"), _colored_value(expected),
|
||||
_nerror(current_length), _colored_value(current)]
|
||||
Comparator.GREATER_EQUAL:
|
||||
return "%s\n %s but was '%s' in\n %s" % [
|
||||
_error("Expecting size to be greater than or equal:"), _colored_value(expected),
|
||||
_nerror(current_length), _colored_value(current)]
|
||||
return "TODO create expected message"
|
||||
|
||||
|
||||
# - ArrayAssert specific messgaes ---------------------------------------------------
|
||||
|
||||
static func error_arr_contains(current, expected :Array, not_expect :Array, not_found :Array, by_reference :bool) -> String:
|
||||
var failure_message = "Expecting contains SAME elements:" if by_reference else "Expecting contains elements:"
|
||||
var error := "%s\n %s\n do contains (in any order)\n %s" % [
|
||||
_error(failure_message), _colored_value(current, ", "), _colored_value(expected, ", ")]
|
||||
if not not_expect.is_empty():
|
||||
error += "\nbut some elements where not expected:\n %s" % _colored_value(not_expect, ", ")
|
||||
if not not_found.is_empty():
|
||||
var prefix = "but" if not_expect.is_empty() else "and"
|
||||
error += "\n%s could not find elements:\n %s" % [prefix, _colored_value(not_found, ", ")]
|
||||
return error
|
||||
|
||||
|
||||
static func error_arr_contains_exactly(current, expected, not_expect, not_found, compare_mode :GdObjects.COMPARE_MODE) -> String:
|
||||
var failure_message = (
|
||||
"Expecting contains exactly elements:" if compare_mode == GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST
|
||||
else "Expecting contains SAME exactly elements:"
|
||||
)
|
||||
if not_expect.is_empty() and not_found.is_empty():
|
||||
var diff := _find_first_diff(current, expected)
|
||||
return "%s\n %s\n do contains (in same order)\n %s\n but has different order %s" % [
|
||||
_error(failure_message), _colored_value(current, ", "), _colored_value(expected, ", "), diff]
|
||||
|
||||
var error := "%s\n %s\n do contains (in same order)\n %s" % [
|
||||
_error(failure_message), _colored_value(current, ", "), _colored_value(expected, ", ")]
|
||||
if not not_expect.is_empty():
|
||||
error += "\nbut some elements where not expected:\n %s" % _colored_value(not_expect, ", ")
|
||||
if not not_found.is_empty():
|
||||
var prefix = "but" if not_expect.is_empty() else "and"
|
||||
error += "\n%s could not find elements:\n %s" % [prefix, _colored_value(not_found, ", ")]
|
||||
return error
|
||||
|
||||
|
||||
static func error_arr_contains_exactly_in_any_order(
|
||||
current,
|
||||
expected :Array,
|
||||
not_expect :Array,
|
||||
not_found :Array,
|
||||
compare_mode :GdObjects.COMPARE_MODE) -> String:
|
||||
|
||||
var failure_message = (
|
||||
"Expecting contains exactly elements:" if compare_mode == GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST
|
||||
else "Expecting contains SAME exactly elements:"
|
||||
)
|
||||
var error := "%s\n %s\n do contains exactly (in any order)\n %s" % [
|
||||
_error(failure_message), _colored_value(current, ", "), _colored_value(expected, ", ")]
|
||||
if not not_expect.is_empty():
|
||||
error += "\nbut some elements where not expected:\n %s" % _colored_value(not_expect, ", ")
|
||||
if not not_found.is_empty():
|
||||
var prefix = "but" if not_expect.is_empty() else "and"
|
||||
error += "\n%s could not find elements:\n %s" % [prefix, _colored_value(not_found, ", ")]
|
||||
return error
|
||||
|
||||
|
||||
static func error_arr_not_contains(current :Array, expected :Array, found :Array, compare_mode :GdObjects.COMPARE_MODE) -> String:
|
||||
var failure_message = "Expecting:" if compare_mode == GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST else "Expecting SAME:"
|
||||
var error := "%s\n %s\n do not contains\n %s" % [
|
||||
_error(failure_message), _colored_value(current, ", "), _colored_value(expected, ", ")]
|
||||
if not found.is_empty():
|
||||
error += "\n but found elements:\n %s" % _colored_value(found, ", ")
|
||||
return error
|
||||
|
||||
|
||||
# - DictionaryAssert specific messages ----------------------------------------------
|
||||
static func error_contains_keys(current :Array, expected :Array, keys_not_found :Array, compare_mode :GdObjects.COMPARE_MODE) -> String:
|
||||
var failure := (
|
||||
"Expecting contains keys:" if compare_mode == GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST
|
||||
else "Expecting contains SAME keys:"
|
||||
)
|
||||
return "%s\n %s\n to contains:\n %s\n but can't find key's:\n %s" % [
|
||||
_error(failure), _colored_value(current, ", "), _colored_value(expected, ", "), _colored_value(keys_not_found, ", ")]
|
||||
|
||||
|
||||
static func error_not_contains_keys(current :Array, expected :Array, keys_not_found :Array, compare_mode :GdObjects.COMPARE_MODE) -> String:
|
||||
var failure := (
|
||||
"Expecting NOT contains keys:" if compare_mode == GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST
|
||||
else "Expecting NOT contains SAME keys"
|
||||
)
|
||||
return "%s\n %s\n do not contains:\n %s\n but contains key's:\n %s" % [
|
||||
_error(failure), _colored_value(current, ", "), _colored_value(expected, ", "), _colored_value(keys_not_found, ", ")]
|
||||
|
||||
|
||||
static func error_contains_key_value(key, value, current_value, compare_mode :GdObjects.COMPARE_MODE) -> String:
|
||||
var failure := (
|
||||
"Expecting contains key and value:" if compare_mode == GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST
|
||||
else "Expecting contains SAME key and value:"
|
||||
)
|
||||
return "%s\n %s : %s\n but contains\n %s : %s" % [
|
||||
_error(failure), _colored_value(key), _colored_value(value), _colored_value(key), _colored_value(current_value)]
|
||||
|
||||
|
||||
# - ResultAssert specific errors ----------------------------------------------------
|
||||
static func error_result_is_empty(current :GdUnitResult) -> String:
|
||||
return _result_error_message(current, GdUnitResult.EMPTY)
|
||||
|
||||
|
||||
static func error_result_is_success(current :GdUnitResult) -> String:
|
||||
return _result_error_message(current, GdUnitResult.SUCCESS)
|
||||
|
||||
|
||||
static func error_result_is_warning(current :GdUnitResult) -> String:
|
||||
return _result_error_message(current, GdUnitResult.WARN)
|
||||
|
||||
|
||||
static func error_result_is_error(current :GdUnitResult) -> String:
|
||||
return _result_error_message(current, GdUnitResult.ERROR)
|
||||
|
||||
|
||||
static func error_result_has_message(current :String, expected :String) -> String:
|
||||
return "%s\n %s\n but was\n %s." % [_error("Expecting:"), _colored_value(expected), _colored_value(current)]
|
||||
|
||||
|
||||
static func error_result_has_message_on_success(expected :String) -> String:
|
||||
return "%s\n %s\n but the GdUnitResult is a success." % [_error("Expecting:"), _colored_value(expected)]
|
||||
|
||||
|
||||
static func error_result_is_value(current, expected) -> String:
|
||||
return "%s\n %s\n but was\n %s." % [_error("Expecting to contain same value:"), _colored_value(expected), _colored_value(current)]
|
||||
|
||||
|
||||
static func _result_error_message(current :GdUnitResult, expected_type :int) -> String:
|
||||
if current == null:
|
||||
return _error("Expecting the result must be a %s but was <null>." % result_type(expected_type))
|
||||
if current.is_success():
|
||||
return _error("Expecting the result must be a %s but was SUCCESS." % result_type(expected_type))
|
||||
var error = "Expecting the result must be a %s but was %s:" % [result_type(expected_type), result_type(current._state)]
|
||||
return "%s\n %s" % [_error(error), _colored_value(result_message(current))]
|
||||
|
||||
|
||||
static func error_interrupted(func_name :String, expected, elapsed :String) -> String:
|
||||
func_name = humanized(func_name)
|
||||
if expected == null:
|
||||
return "%s %s but timed out after %s" % [_error("Expected:"), func_name, elapsed]
|
||||
return "%s %s %s but timed out after %s" % [_error("Expected:"), func_name, _colored_value(expected), elapsed]
|
||||
|
||||
|
||||
static func error_wait_signal(signal_name :String, args :Array, elapsed :String) -> String:
|
||||
if args.is_empty():
|
||||
return "%s %s but timed out after %s" % [
|
||||
_error("Expecting emit signal:"), _colored_value(signal_name + "()"), elapsed]
|
||||
return "%s %s but timed out after %s" % [
|
||||
_error("Expecting emit signal:"), _colored_value(signal_name + "(" + str(args) + ")"), elapsed]
|
||||
|
||||
|
||||
static func error_signal_emitted(signal_name :String, args :Array, elapsed :String) -> String:
|
||||
if args.is_empty():
|
||||
return "%s %s but is emitted after %s" % [
|
||||
_error("Expecting do not emit signal:"), _colored_value(signal_name + "()"), elapsed]
|
||||
return "%s %s but is emitted after %s" % [
|
||||
_error("Expecting do not emit signal:"), _colored_value(signal_name + "(" + str(args) + ")"), elapsed]
|
||||
|
||||
static func error_await_signal_on_invalid_instance(source, signal_name :String, args :Array) -> String:
|
||||
return "%s\n await_signal_on(%s, %s, %s)" % [
|
||||
_error("Invalid source! Can't await on signal:"), _colored_value(source), signal_name, args]
|
||||
|
||||
static func result_type(type :int) -> String:
|
||||
match type:
|
||||
GdUnitResult.SUCCESS: return "SUCCESS"
|
||||
GdUnitResult.WARN: return "WARNING"
|
||||
GdUnitResult.ERROR: return "ERROR"
|
||||
GdUnitResult.EMPTY: return "EMPTY"
|
||||
return "UNKNOWN"
|
||||
|
||||
|
||||
static func result_message(result :GdUnitResult) -> String:
|
||||
match result._state:
|
||||
GdUnitResult.SUCCESS: return ""
|
||||
GdUnitResult.WARN: return result.warn_message()
|
||||
GdUnitResult.ERROR: return result.error_message()
|
||||
GdUnitResult.EMPTY: return ""
|
||||
return "UNKNOWN"
|
||||
# -----------------------------------------------------------------------------------
|
||||
|
||||
# - Spy|Mock specific errors ----------------------------------------------------
|
||||
static func error_no_more_interactions(summary :Dictionary) -> String:
|
||||
var interactions := PackedStringArray()
|
||||
for args in summary.keys():
|
||||
var times :int = summary[args]
|
||||
interactions.append(_format_arguments(args, times))
|
||||
return "%s\n%s\n%s" % [_error("Expecting no more interactions!"), _error("But found interactions on:"), "\n".join(interactions)]
|
||||
|
||||
|
||||
static func error_validate_interactions(current_interactions :Dictionary, expected_interactions :Dictionary) -> String:
|
||||
var interactions := PackedStringArray()
|
||||
for args in current_interactions.keys():
|
||||
var times :int = current_interactions[args]
|
||||
interactions.append(_format_arguments(args, times))
|
||||
var expected_interaction := _format_arguments(expected_interactions.keys()[0], expected_interactions.values()[0])
|
||||
return "%s\n%s\n%s\n%s" % [
|
||||
_error("Expecting interaction on:"), expected_interaction, _error("But found interactions on:"), "\n".join(interactions)]
|
||||
|
||||
|
||||
static func _format_arguments(args :Array, times :int) -> String:
|
||||
var fname :String = args[0]
|
||||
var fargs := args.slice(1) as Array
|
||||
var typed_args := _to_typed_args(fargs)
|
||||
var fsignature := _colored_value("%s(%s)" % [fname, ", ".join(typed_args)])
|
||||
return " %s %d time's" % [fsignature, times]
|
||||
|
||||
|
||||
static func _to_typed_args(args :Array) -> PackedStringArray:
|
||||
var typed := PackedStringArray()
|
||||
for arg in args:
|
||||
typed.append(_format_arg(arg) + " :" + GdObjects.type_as_string(typeof(arg)))
|
||||
return typed
|
||||
|
||||
|
||||
static func _format_arg(arg) -> String:
|
||||
if arg is InputEvent:
|
||||
return input_event_as_text(arg)
|
||||
return str(arg)
|
||||
|
||||
|
||||
static func _find_first_diff( left :Array, right :Array) -> String:
|
||||
for index in left.size():
|
||||
var l = left[index]
|
||||
var r = "<no entry>" if index >= right.size() else right[index]
|
||||
if not GdObjects.equals(l, r):
|
||||
return "at position %s\n '%s' vs '%s'" % [_colored_value(index), _typed_value(l), _typed_value(r)]
|
||||
return ""
|
||||
|
||||
|
||||
static func error_has_size(current, expected: int) -> String:
|
||||
var current_size = null if current == null else current.size()
|
||||
return "%s\n %s\n but was\n %s" % [_error("Expecting size:"), _colored_value(expected), _colored_value(current_size)]
|
||||
|
||||
|
||||
static func error_contains_exactly(current: Array, expected: Array) -> String:
|
||||
return "%s\n %s\n but was\n %s" % [_error("Expecting exactly equal:"), _colored_value(expected), _colored_value(current)]
|
||||
|
||||
|
||||
static func format_chars(characters :PackedByteArray, type :Color) -> PackedByteArray:
|
||||
if characters.size() == 0:# or characters[0] == 10:
|
||||
return characters
|
||||
var result := PackedByteArray()
|
||||
var message := "[bgcolor=#%s][color=with]%s[/color][/bgcolor]" % [
|
||||
type.to_html(), characters.get_string_from_utf8().replace("\n", "<LF>")]
|
||||
result.append_array(message.to_utf8_buffer())
|
||||
return result
|
||||
|
||||
|
||||
static func format_invalid(value :String) -> String:
|
||||
return "[bgcolor=#%s][color=with]%s[/color][/bgcolor]" % [SUB_COLOR.to_html(), value]
|
||||
|
||||
|
||||
static func humanized(value :String) -> String:
|
||||
return value.replace("_", " ")
|
||||
55
addons/gdUnit4/src/asserts/GdAssertReports.gd
Normal file
55
addons/gdUnit4/src/asserts/GdAssertReports.gd
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class_name GdAssertReports
|
||||
extends RefCounted
|
||||
|
||||
const LAST_ERROR = "last_assert_error_message"
|
||||
const LAST_ERROR_LINE = "last_assert_error_line"
|
||||
|
||||
|
||||
static func report_success() -> void:
|
||||
GdUnitSignals.instance().gdunit_set_test_failed.emit(false)
|
||||
GdAssertReports.set_last_error_line_number(-1)
|
||||
Engine.remove_meta(LAST_ERROR)
|
||||
|
||||
|
||||
static func report_warning(message :String, line_number :int) -> void:
|
||||
GdUnitSignals.instance().gdunit_set_test_failed.emit(false)
|
||||
send_report(GdUnitReport.new().create(GdUnitReport.WARN, line_number, message))
|
||||
|
||||
|
||||
static func report_error(message:String, line_number :int) -> void:
|
||||
GdUnitSignals.instance().gdunit_set_test_failed.emit(true)
|
||||
GdAssertReports.set_last_error_line_number(line_number)
|
||||
Engine.set_meta(LAST_ERROR, message)
|
||||
# if we expect to fail we handle as success test
|
||||
if _do_expect_assert_failing():
|
||||
return
|
||||
send_report(GdUnitReport.new().create(GdUnitReport.FAILURE, line_number, message))
|
||||
|
||||
|
||||
static func reset_last_error_line_number() -> void:
|
||||
Engine.remove_meta(LAST_ERROR_LINE)
|
||||
|
||||
|
||||
static func set_last_error_line_number(line_number :int) -> void:
|
||||
Engine.set_meta(LAST_ERROR_LINE, line_number)
|
||||
|
||||
|
||||
static func get_last_error_line_number() -> int:
|
||||
if Engine.has_meta(LAST_ERROR_LINE):
|
||||
return Engine.get_meta(LAST_ERROR_LINE)
|
||||
return -1
|
||||
|
||||
|
||||
static func _do_expect_assert_failing() -> bool:
|
||||
if Engine.has_meta(GdUnitConstants.EXPECT_ASSERT_REPORT_FAILURES):
|
||||
return Engine.get_meta(GdUnitConstants.EXPECT_ASSERT_REPORT_FAILURES)
|
||||
return false
|
||||
|
||||
|
||||
static func current_failure() -> String:
|
||||
return Engine.get_meta(LAST_ERROR)
|
||||
|
||||
|
||||
static func send_report(report :GdUnitReport) -> void:
|
||||
var execution_context_id := GdUnitThreadManager.get_current_context().get_execution_context_id()
|
||||
GdUnitSignals.instance().gdunit_report.emit(execution_context_id, report)
|
||||
349
addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd
Normal file
349
addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
extends GdUnitArrayAssert
|
||||
|
||||
|
||||
var _base :GdUnitAssert
|
||||
var _current_value_provider :ValueProvider
|
||||
|
||||
|
||||
func _init(current):
|
||||
_current_value_provider = DefaultValueProvider.new(current)
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not _validate_value_type(current):
|
||||
report_error("GdUnitArrayAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func report_success() -> GdUnitArrayAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitArrayAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitArrayAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func _validate_value_type(value) -> bool:
|
||||
return value == null or GdArrayTools.is_array_type(value)
|
||||
|
||||
|
||||
func current_value() -> Variant:
|
||||
return _current_value_provider.get_value()
|
||||
|
||||
|
||||
func max_length(left, right) -> int:
|
||||
var ls = str(left).length()
|
||||
var rs = str(right).length()
|
||||
return rs if ls < rs else ls
|
||||
|
||||
|
||||
func _array_equals_div(current, expected, case_sensitive :bool = false) -> Array:
|
||||
var current_value := PackedStringArray(Array(current))
|
||||
var expected_value := PackedStringArray(Array(expected))
|
||||
var index_report := Array()
|
||||
for index in current_value.size():
|
||||
var c := current_value[index]
|
||||
if index < expected_value.size():
|
||||
var e := expected_value[index]
|
||||
if not GdObjects.equals(c, e, case_sensitive):
|
||||
var length := max_length(c, e)
|
||||
current_value[index] = GdAssertMessages.format_invalid(c.lpad(length))
|
||||
expected_value[index] = e.lpad(length)
|
||||
index_report.push_back({"index" : index, "current" :c, "expected": e})
|
||||
else:
|
||||
current_value[index] = GdAssertMessages.format_invalid(c)
|
||||
index_report.push_back({"index" : index, "current" :c, "expected": "<N/A>"})
|
||||
|
||||
for index in range(current.size(), expected_value.size()):
|
||||
var value := expected_value[index]
|
||||
expected_value[index] = GdAssertMessages.format_invalid(value)
|
||||
index_report.push_back({"index" : index, "current" : "<N/A>", "expected": value})
|
||||
return [current_value, expected_value, index_report]
|
||||
|
||||
|
||||
func _array_div(compare_mode :GdObjects.COMPARE_MODE, left :Array[Variant], right :Array[Variant], _same_order := false) -> Array[Variant]:
|
||||
var not_expect := left.duplicate(true)
|
||||
var not_found := right.duplicate(true)
|
||||
for index_c in left.size():
|
||||
var c = left[index_c]
|
||||
for index_e in right.size():
|
||||
var e = right[index_e]
|
||||
if GdObjects.equals(c, e, false, compare_mode):
|
||||
GdArrayTools.erase_value(not_expect, e)
|
||||
GdArrayTools.erase_value(not_found, c)
|
||||
break
|
||||
return [not_expect, not_found]
|
||||
|
||||
|
||||
func _contains(expected, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var by_reference := compare_mode == GdObjects.COMPARE_MODE.OBJECT_REFERENCE
|
||||
var current_value = current_value()
|
||||
if current_value == null:
|
||||
return report_error(GdAssertMessages.error_arr_contains(current_value, expected, [], expected, by_reference))
|
||||
var diffs := _array_div(compare_mode, current_value, expected)
|
||||
#var not_expect := diffs[0] as Array
|
||||
var not_found := diffs[1] as Array
|
||||
if not not_found.is_empty():
|
||||
return report_error(GdAssertMessages.error_arr_contains(current_value, expected, [], not_found, by_reference))
|
||||
return report_success()
|
||||
|
||||
|
||||
func _contains_exactly(expected, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if current_value == null:
|
||||
return report_error(GdAssertMessages.error_arr_contains_exactly(current_value, expected, [], expected, compare_mode))
|
||||
# has same content in same order
|
||||
if GdObjects.equals(Array(current_value), Array(expected), false, compare_mode):
|
||||
return report_success()
|
||||
# check has same elements but in different order
|
||||
if GdObjects.equals_sorted(Array(current_value), Array(expected), false, compare_mode):
|
||||
return report_error(GdAssertMessages.error_arr_contains_exactly(current_value, expected, [], [], compare_mode))
|
||||
# find the difference
|
||||
var diffs := _array_div(compare_mode, current_value, expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
var not_expect := diffs[0] as Array[Variant]
|
||||
var not_found := diffs[1] as Array[Variant]
|
||||
return report_error(GdAssertMessages.error_arr_contains_exactly(current_value, expected, not_expect, not_found, compare_mode))
|
||||
|
||||
|
||||
func _contains_exactly_in_any_order(expected, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if current_value == null:
|
||||
return report_error(GdAssertMessages.error_arr_contains_exactly_in_any_order(current_value, expected, [], expected, compare_mode))
|
||||
# find the difference
|
||||
var diffs := _array_div(compare_mode, current_value, expected, false)
|
||||
var not_expect := diffs[0] as Array
|
||||
var not_found := diffs[1] as Array
|
||||
if not_expect.is_empty() and not_found.is_empty():
|
||||
return report_success()
|
||||
return report_error(GdAssertMessages.error_arr_contains_exactly_in_any_order(current_value, expected, not_expect, not_found, compare_mode))
|
||||
|
||||
|
||||
func _not_contains(expected, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if current_value == null:
|
||||
return report_error(GdAssertMessages.error_arr_contains_exactly_in_any_order(current_value, expected, [], expected, compare_mode))
|
||||
var diffs := _array_div(compare_mode, current_value, expected)
|
||||
var found := diffs[0] as Array
|
||||
if found.size() == current_value.size():
|
||||
return report_success()
|
||||
var diffs2 := _array_div(compare_mode, expected, diffs[1])
|
||||
return report_error(GdAssertMessages.error_arr_not_contains(current_value, expected, diffs2[0], compare_mode))
|
||||
|
||||
|
||||
func is_null() -> GdUnitArrayAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitArrayAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
# Verifies that the current String is equal to the given one.
|
||||
func is_equal(expected) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if current_value == null and expected != null:
|
||||
return report_error(GdAssertMessages.error_equal(null, expected))
|
||||
if not GdObjects.equals(current_value, expected):
|
||||
var diff := _array_equals_div(current_value, expected)
|
||||
var expected_as_list = GdArrayTools.as_string(diff[0], false)
|
||||
var current_as_list = GdArrayTools.as_string(diff[1], false)
|
||||
var index_report = diff[2]
|
||||
return report_error(GdAssertMessages.error_equal(expected_as_list, current_as_list, index_report))
|
||||
return report_success()
|
||||
|
||||
|
||||
# Verifies that the current Array is equal to the given one, ignoring case considerations.
|
||||
func is_equal_ignoring_case(expected) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if current_value == null and expected != null:
|
||||
return report_error(GdAssertMessages.error_equal(null, GdArrayTools.as_string(expected)))
|
||||
if not GdObjects.equals(current_value, expected, true):
|
||||
var diff := _array_equals_div(current_value, expected, true)
|
||||
var expected_as_list := GdArrayTools.as_string(diff[0])
|
||||
var current_as_list := GdArrayTools.as_string(diff[1])
|
||||
var index_report = diff[2]
|
||||
return report_error(GdAssertMessages.error_equal(expected_as_list, current_as_list, index_report))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if GdObjects.equals(current_value, expected):
|
||||
return report_error(GdAssertMessages.error_not_equal(current_value, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_equal_ignoring_case(expected) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current_value = current_value()
|
||||
if GdObjects.equals(current_value, expected, true):
|
||||
var c := GdArrayTools.as_string(current_value)
|
||||
var e := GdArrayTools.as_string(expected)
|
||||
return report_error(GdAssertMessages.error_not_equal_case_insensetiv(c, e))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_empty() -> GdUnitArrayAssert:
|
||||
var current_value = current_value()
|
||||
if current_value == null or current_value.size() > 0:
|
||||
return report_error(GdAssertMessages.error_is_empty(current_value))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_empty() -> GdUnitArrayAssert:
|
||||
var current_value = current_value()
|
||||
if current_value != null and current_value.size() == 0:
|
||||
return report_error(GdAssertMessages.error_is_not_empty())
|
||||
return report_success()
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter", "shadowed_global_identifier")
|
||||
func is_same(expected) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current = current_value()
|
||||
if not is_same(current, expected):
|
||||
report_error(GdAssertMessages.error_is_same(current, expected))
|
||||
return self
|
||||
|
||||
|
||||
func is_not_same(expected) -> GdUnitArrayAssert:
|
||||
if not _validate_value_type(expected):
|
||||
return report_error("ERROR: expected value: <%s>\n is not a Array Type!" % GdObjects.typeof_as_string(expected))
|
||||
var current = current_value()
|
||||
if is_same(current, expected):
|
||||
report_error(GdAssertMessages.error_not_same(current, expected))
|
||||
return self
|
||||
|
||||
|
||||
func has_size(expected: int) -> GdUnitArrayAssert:
|
||||
var current_value = current_value()
|
||||
if current_value == null or current_value.size() != expected:
|
||||
return report_error(GdAssertMessages.error_has_size(current_value, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func contains(expected) -> GdUnitArrayAssert:
|
||||
return _contains(expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func contains_exactly(expected) -> GdUnitArrayAssert:
|
||||
return _contains_exactly(expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func contains_exactly_in_any_order(expected) -> GdUnitArrayAssert:
|
||||
return _contains_exactly_in_any_order(expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func contains_same(expected) -> GdUnitArrayAssert:
|
||||
return _contains(expected, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func contains_same_exactly(expected) -> GdUnitArrayAssert:
|
||||
return _contains_exactly(expected, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func contains_same_exactly_in_any_order(expected) -> GdUnitArrayAssert:
|
||||
return _contains_exactly_in_any_order(expected, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func not_contains(expected) -> GdUnitArrayAssert:
|
||||
return _not_contains(expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func not_contains_same(expected) -> GdUnitArrayAssert:
|
||||
return _not_contains(expected, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func is_instanceof(expected) -> GdUnitAssert:
|
||||
_base.is_instanceof(expected)
|
||||
return self
|
||||
|
||||
|
||||
func extract(func_name :String, args := Array()) -> GdUnitArrayAssert:
|
||||
var extracted_elements := Array()
|
||||
var extractor :GdUnitValueExtractor = ResourceLoader.load("res://addons/gdUnit4/src/extractors/GdUnitFuncValueExtractor.gd",
|
||||
"GDScript", ResourceLoader.CACHE_MODE_REUSE).new(func_name, args)
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
_current_value_provider = DefaultValueProvider.new(null)
|
||||
else:
|
||||
for element in current:
|
||||
extracted_elements.append(extractor.extract_value(element))
|
||||
_current_value_provider = DefaultValueProvider.new(extracted_elements)
|
||||
return self
|
||||
|
||||
|
||||
func extractv(
|
||||
extr0 :GdUnitValueExtractor,
|
||||
extr1 :GdUnitValueExtractor = null,
|
||||
extr2 :GdUnitValueExtractor = null,
|
||||
extr3 :GdUnitValueExtractor = null,
|
||||
extr4 :GdUnitValueExtractor = null,
|
||||
extr5 :GdUnitValueExtractor = null,
|
||||
extr6 :GdUnitValueExtractor = null,
|
||||
extr7 :GdUnitValueExtractor = null,
|
||||
extr8 :GdUnitValueExtractor = null,
|
||||
extr9 :GdUnitValueExtractor = null) -> GdUnitArrayAssert:
|
||||
var extractors :Variant = GdArrayTools.filter_value([extr0, extr1, extr2, extr3, extr4, extr5, extr6, extr7, extr8, extr9], null)
|
||||
var extracted_elements := Array()
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
_current_value_provider = DefaultValueProvider.new(null)
|
||||
else:
|
||||
for element in current_value():
|
||||
var ev :Array[Variant] = [
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG
|
||||
]
|
||||
for index in extractors.size():
|
||||
var extractor :GdUnitValueExtractor = extractors[index]
|
||||
ev[index] = extractor.extract_value(element)
|
||||
if extractors.size() > 1:
|
||||
extracted_elements.append(GdUnitTuple.new(ev[0], ev[1], ev[2], ev[3], ev[4], ev[5], ev[6], ev[7], ev[8], ev[9]))
|
||||
else:
|
||||
extracted_elements.append(ev[0])
|
||||
_current_value_provider = DefaultValueProvider.new(extracted_elements)
|
||||
return self
|
||||
71
addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd
Normal file
71
addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
extends GdUnitAssert
|
||||
|
||||
|
||||
var _current :Variant
|
||||
var _current_error_message :String = ""
|
||||
var _custom_failure_message :String = ""
|
||||
|
||||
|
||||
func _init(current :Variant) -> void:
|
||||
_current = current
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
GdAssertReports.reset_last_error_line_number()
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _current_error_message
|
||||
|
||||
|
||||
func current_value() -> Variant:
|
||||
return _current
|
||||
|
||||
|
||||
func report_success() -> GdUnitAssert:
|
||||
GdAssertReports.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error_message :String, failure_line_number: int = -1) -> GdUnitAssert:
|
||||
var line_number := failure_line_number if failure_line_number != -1 else GdUnitAssertions.get_line_number()
|
||||
GdAssertReports.set_last_error_line_number(line_number)
|
||||
_current_error_message = error_message if _custom_failure_message.is_empty() else _custom_failure_message
|
||||
GdAssertReports.report_error(_current_error_message, line_number)
|
||||
return self
|
||||
|
||||
|
||||
func test_fail():
|
||||
return report_error(GdAssertMessages.error_not_implemented())
|
||||
|
||||
|
||||
func override_failure_message(message :String):
|
||||
_custom_failure_message = message
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitAssert:
|
||||
var current = current_value()
|
||||
if not GdObjects.equals(current, expected):
|
||||
return report_error(GdAssertMessages.error_equal(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitAssert:
|
||||
var current = current_value()
|
||||
if GdObjects.equals(current, expected):
|
||||
return report_error(GdAssertMessages.error_not_equal(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_null() -> GdUnitAssert:
|
||||
var current = current_value()
|
||||
if current != null:
|
||||
return report_error(GdAssertMessages.error_is_null(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_is_not_null())
|
||||
return report_success()
|
||||
63
addons/gdUnit4/src/asserts/GdUnitAssertions.gd
Normal file
63
addons/gdUnit4/src/asserts/GdUnitAssertions.gd
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Preloads all GdUnit assertions
|
||||
class_name GdUnitAssertions
|
||||
extends RefCounted
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
# preload all gdunit assertions to speedup testsuite loading time
|
||||
# gdlint:disable=private-method-call
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd")
|
||||
GdUnitAssertions.__lazy_load("res://addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd")
|
||||
|
||||
|
||||
### We now load all used asserts and tool scripts into the cache according to the principle of "lazy loading"
|
||||
### in order to noticeably reduce the loading time of the test suite.
|
||||
# We go this hard way to increase the loading performance to avoid reparsing all the used scripts
|
||||
# for more detailed info -> https://github.com/godotengine/godot/issues/67400
|
||||
# gdlint:disable=function-name
|
||||
static func __lazy_load(script_path :String) -> GDScript:
|
||||
return ResourceLoader.load(script_path, "GDScript", ResourceLoader.CACHE_MODE_REUSE)
|
||||
|
||||
|
||||
static func validate_value_type(value, type :Variant.Type) -> bool:
|
||||
return value == null or typeof(value) == type
|
||||
|
||||
# Scans the current stack trace for the root cause to extract the line number
|
||||
static func get_line_number() -> int:
|
||||
var stack_trace := get_stack()
|
||||
if stack_trace == null or stack_trace.is_empty():
|
||||
return -1
|
||||
for index in stack_trace.size():
|
||||
var stack_info :Dictionary = stack_trace[index]
|
||||
var function :String = stack_info.get("function")
|
||||
# we catch helper asserts to skip over to return the correct line number
|
||||
if function.begins_with("assert_"):
|
||||
continue
|
||||
if function.begins_with("test_"):
|
||||
return stack_info.get("line")
|
||||
var source :String = stack_info.get("source")
|
||||
if source.is_empty() \
|
||||
or source.begins_with("user://") \
|
||||
or source.ends_with("GdUnitAssert.gd") \
|
||||
or source.ends_with("GdUnitAssertions.gd") \
|
||||
or source.ends_with("AssertImpl.gd") \
|
||||
or source.ends_with("GdUnitTestSuite.gd") \
|
||||
or source.ends_with("GdUnitSceneRunnerImpl.gd") \
|
||||
or source.ends_with("GdUnitObjectInteractions.gd") \
|
||||
or source.ends_with("GdUnitAwaiter.gd"):
|
||||
continue
|
||||
return stack_info.get("line")
|
||||
return -1
|
||||
76
addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd
Normal file
76
addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
extends GdUnitBoolAssert
|
||||
|
||||
var _base: GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not GdUnitAssertions.validate_value_type(current, TYPE_BOOL):
|
||||
report_error("GdUnitBoolAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func current_value():
|
||||
return _base.current_value()
|
||||
|
||||
|
||||
func report_success() -> GdUnitBoolAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitBoolAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitBoolAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
# Verifies that the current value is null.
|
||||
func is_null() -> GdUnitBoolAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
# Verifies that the current value is not null.
|
||||
func is_not_null() -> GdUnitBoolAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitBoolAssert:
|
||||
_base.is_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitBoolAssert:
|
||||
_base.is_not_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_true() -> GdUnitBoolAssert:
|
||||
if current_value() != true:
|
||||
return report_error(GdAssertMessages.error_is_true(current_value()))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_false() -> GdUnitBoolAssert:
|
||||
if current_value() == true || current_value() == null:
|
||||
return report_error(GdAssertMessages.error_is_false(current_value()))
|
||||
return report_success()
|
||||
182
addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd
Normal file
182
addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
extends GdUnitDictionaryAssert
|
||||
|
||||
var _base :GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not GdUnitAssertions.validate_value_type(current, TYPE_DICTIONARY):
|
||||
report_error("GdUnitDictionaryAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func report_success() -> GdUnitDictionaryAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitDictionaryAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitDictionaryAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func current_value() -> Variant:
|
||||
return _base.current_value()
|
||||
|
||||
|
||||
func is_null() -> GdUnitDictionaryAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitDictionaryAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_equal(null, GdAssertMessages.format_dict(expected)))
|
||||
if not GdObjects.equals(current, expected):
|
||||
var c := GdAssertMessages.format_dict(current)
|
||||
var e := GdAssertMessages.format_dict(expected)
|
||||
var diff := GdDiffTool.string_diff(c, e)
|
||||
var curent_diff := GdAssertMessages.colored_array_div(diff[1])
|
||||
return report_error(GdAssertMessages.error_equal(curent_diff, e))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if GdObjects.equals(current, expected):
|
||||
return report_error(GdAssertMessages.error_not_equal(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter", "shadowed_global_identifier")
|
||||
func is_same(expected) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_equal(null, GdAssertMessages.format_dict(expected)))
|
||||
if not is_same(current, expected):
|
||||
var c := GdAssertMessages.format_dict(current)
|
||||
var e := GdAssertMessages.format_dict(expected)
|
||||
var diff := GdDiffTool.string_diff(c, e)
|
||||
var curent_diff := GdAssertMessages.colored_array_div(diff[1])
|
||||
return report_error(GdAssertMessages.error_is_same(curent_diff, e))
|
||||
return report_success()
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter", "shadowed_global_identifier")
|
||||
func is_not_same(expected) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if is_same(current, expected):
|
||||
return report_error(GdAssertMessages.error_not_same(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_empty() -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null or not current.is_empty():
|
||||
return report_error(GdAssertMessages.error_is_empty(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_empty() -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null or current.is_empty():
|
||||
return report_error(GdAssertMessages.error_is_not_empty())
|
||||
return report_success()
|
||||
|
||||
|
||||
func has_size(expected: int) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_is_not_null())
|
||||
if current.size() != expected:
|
||||
return report_error(GdAssertMessages.error_has_size(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func _contains_keys(expected :Array, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_is_not_null())
|
||||
# find expected keys
|
||||
var keys_not_found :Array = expected.filter(_filter_by_key.bind(current.keys(), compare_mode))
|
||||
if not keys_not_found.is_empty():
|
||||
return report_error(GdAssertMessages.error_contains_keys(current.keys(), expected, keys_not_found, compare_mode))
|
||||
return report_success()
|
||||
|
||||
|
||||
func _contains_key_value(key, value, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
var expected := [key]
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_is_not_null())
|
||||
var keys_not_found :Array = expected.filter(_filter_by_key.bind(current.keys(), compare_mode))
|
||||
if not keys_not_found.is_empty():
|
||||
return report_error(GdAssertMessages.error_contains_key_value(key, value, current.keys(), compare_mode))
|
||||
if not GdObjects.equals(current[key], value, false, compare_mode):
|
||||
return report_error(GdAssertMessages.error_contains_key_value(key, value, current[key], compare_mode))
|
||||
return report_success()
|
||||
|
||||
|
||||
func _not_contains_keys(expected :Array, compare_mode :GdObjects.COMPARE_MODE) -> GdUnitDictionaryAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_is_not_null())
|
||||
var keys_found :Array = current.keys().filter(_filter_by_key.bind(expected, compare_mode, true))
|
||||
if not keys_found.is_empty():
|
||||
return report_error(GdAssertMessages.error_not_contains_keys(current.keys(), expected, keys_found, compare_mode))
|
||||
return report_success()
|
||||
|
||||
|
||||
func contains_keys(expected :Array) -> GdUnitDictionaryAssert:
|
||||
return _contains_keys(expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func contains_key_value(key, value) -> GdUnitDictionaryAssert:
|
||||
return _contains_key_value(key, value, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func not_contains_keys(expected :Array) -> GdUnitDictionaryAssert:
|
||||
return _not_contains_keys(expected, GdObjects.COMPARE_MODE.PARAMETER_DEEP_TEST)
|
||||
|
||||
|
||||
func contains_same_keys(expected :Array) -> GdUnitDictionaryAssert:
|
||||
return _contains_keys(expected, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func contains_same_key_value(key, value) -> GdUnitDictionaryAssert:
|
||||
return _contains_key_value(key, value, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func not_contains_same_keys(expected :Array) -> GdUnitDictionaryAssert:
|
||||
return _not_contains_keys(expected, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)
|
||||
|
||||
|
||||
func _filter_by_key(element :Variant, values :Array, compare_mode :GdObjects.COMPARE_MODE, is_not :bool = false) -> bool:
|
||||
for key in values:
|
||||
if GdObjects.equals(key, element, false, compare_mode):
|
||||
return is_not
|
||||
return !is_not
|
||||
110
addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd
Normal file
110
addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
extends GdUnitFailureAssert
|
||||
|
||||
const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd")
|
||||
|
||||
var _is_failed := false
|
||||
var _failure_message :String
|
||||
|
||||
|
||||
static func _set_do_expect_fail(enabled :bool = true):
|
||||
Engine.set_meta(GdUnitConstants.EXPECT_ASSERT_REPORT_FAILURES, enabled)
|
||||
|
||||
|
||||
func execute_and_await(assertion :Callable, do_await := true) -> GdUnitFailureAssert:
|
||||
# do not report any failure from the original assertion we want to test
|
||||
_set_do_expect_fail(true)
|
||||
var thread_context := GdUnitThreadManager.get_current_context()
|
||||
thread_context.set_assert(null)
|
||||
GdUnitSignals.instance().gdunit_set_test_failed.connect(_on_test_failed)
|
||||
# execute the given assertion as callable
|
||||
if do_await:
|
||||
await assertion.call()
|
||||
else:
|
||||
assertion.call()
|
||||
_set_do_expect_fail(false)
|
||||
# get the assert instance from current tread context
|
||||
var current_assert := thread_context.get_assert()
|
||||
if not is_instance_of(current_assert, GdUnitAssert):
|
||||
_is_failed = true
|
||||
_failure_message = "Invalid Callable! It must be a callable of 'GdUnitAssert'"
|
||||
return self
|
||||
_failure_message = current_assert.failure_message()
|
||||
return self
|
||||
|
||||
|
||||
func execute(assertion :Callable) -> GdUnitFailureAssert:
|
||||
execute_and_await(assertion, false)
|
||||
return self
|
||||
|
||||
|
||||
func _on_test_failed(value :bool) -> void:
|
||||
_is_failed = value
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter")
|
||||
func is_equal(_expected :GdUnitAssert) -> GdUnitFailureAssert:
|
||||
return _report_error("Not implemented")
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter")
|
||||
func is_not_equal(_expected :GdUnitAssert) -> GdUnitFailureAssert:
|
||||
return _report_error("Not implemented")
|
||||
|
||||
|
||||
func is_null() -> GdUnitFailureAssert:
|
||||
return _report_error("Not implemented")
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitFailureAssert:
|
||||
return _report_error("Not implemented")
|
||||
|
||||
|
||||
func is_success() -> GdUnitFailureAssert:
|
||||
if _is_failed:
|
||||
return _report_error("Expect: assertion ends successfully.")
|
||||
return self
|
||||
|
||||
|
||||
func is_failed() -> GdUnitFailureAssert:
|
||||
if not _is_failed:
|
||||
return _report_error("Expect: assertion fails.")
|
||||
return self
|
||||
|
||||
|
||||
func has_line(expected :int) -> GdUnitFailureAssert:
|
||||
var current := GdAssertReports.get_last_error_line_number()
|
||||
if current != expected:
|
||||
return _report_error("Expect: to failed on line '%d'\n but was '%d'." % [expected, current])
|
||||
return self
|
||||
|
||||
|
||||
func has_message(expected :String) -> GdUnitFailureAssert:
|
||||
is_failed()
|
||||
var expected_error := GdUnitTools.normalize_text(GdUnitTools.richtext_normalize(expected))
|
||||
var current_error := GdUnitTools.normalize_text(GdUnitTools.richtext_normalize(_failure_message))
|
||||
if current_error != expected_error:
|
||||
var diffs := GdDiffTool.string_diff(current_error, expected_error)
|
||||
var current := GdAssertMessages.colored_array_div(diffs[1])
|
||||
_report_error(GdAssertMessages.error_not_same_error(current, expected_error))
|
||||
return self
|
||||
|
||||
|
||||
func starts_with_message(expected :String) -> GdUnitFailureAssert:
|
||||
var expected_error := GdUnitTools.normalize_text(expected)
|
||||
var current_error := GdUnitTools.normalize_text(GdUnitTools.richtext_normalize(_failure_message))
|
||||
if current_error.find(expected_error) != 0:
|
||||
var diffs := GdDiffTool.string_diff(current_error, expected_error)
|
||||
var current := GdAssertMessages.colored_array_div(diffs[1])
|
||||
_report_error(GdAssertMessages.error_not_same_error(current, expected_error))
|
||||
return self
|
||||
|
||||
|
||||
func _report_error(error_message :String, failure_line_number: int = -1) -> GdUnitAssert:
|
||||
var line_number := failure_line_number if failure_line_number != -1 else GdUnitAssertions.get_line_number()
|
||||
GdAssertReports.report_error(error_message, line_number)
|
||||
return self
|
||||
|
||||
|
||||
func _report_success() -> GdUnitFailureAssert:
|
||||
GdAssertReports.report_success()
|
||||
return self
|
||||
95
addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd
Normal file
95
addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
extends GdUnitFileAssert
|
||||
|
||||
const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd")
|
||||
|
||||
var _base: GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not GdUnitAssertions.validate_value_type(current, TYPE_STRING):
|
||||
report_error("GdUnitFileAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func current_value() -> String:
|
||||
return _base.current_value() as String
|
||||
|
||||
|
||||
func report_success() -> GdUnitFileAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitFileAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitFileAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitFileAssert:
|
||||
_base.is_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitFileAssert:
|
||||
_base.is_not_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_file() -> GdUnitFileAssert:
|
||||
var current := current_value()
|
||||
if FileAccess.open(current, FileAccess.READ) == null:
|
||||
return report_error("Is not a file '%s', error code %s" % [current, FileAccess.get_open_error()])
|
||||
return report_success()
|
||||
|
||||
|
||||
func exists() -> GdUnitFileAssert:
|
||||
var current := current_value()
|
||||
if not FileAccess.file_exists(current):
|
||||
return report_error("The file '%s' not exists" %current)
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_script() -> GdUnitFileAssert:
|
||||
var current := current_value()
|
||||
if FileAccess.open(current, FileAccess.READ) == null:
|
||||
return report_error("Can't acces the file '%s'! Error code %s" % [current, FileAccess.get_open_error()])
|
||||
|
||||
var script = load(current)
|
||||
if not script is GDScript:
|
||||
return report_error("The file '%s' is not a GdScript" % current)
|
||||
return report_success()
|
||||
|
||||
|
||||
func contains_exactly(expected_rows :Array) -> GdUnitFileAssert:
|
||||
var current := current_value()
|
||||
if FileAccess.open(current, FileAccess.READ) == null:
|
||||
return report_error("Can't acces the file '%s'! Error code %s" % [current, FileAccess.get_open_error()])
|
||||
|
||||
var script = load(current)
|
||||
if script is GDScript:
|
||||
var instance = script.new()
|
||||
var source_code = GdScriptParser.to_unix_format(instance.get_script().source_code)
|
||||
GdUnitTools.free_instance(instance)
|
||||
var rows := Array(source_code.split("\n"))
|
||||
ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(rows).contains_exactly(expected_rows)
|
||||
return self
|
||||
144
addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd
Normal file
144
addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
extends GdUnitFloatAssert
|
||||
|
||||
var _base: GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not GdUnitAssertions.validate_value_type(current, TYPE_FLOAT):
|
||||
report_error("GdUnitFloatAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func current_value():
|
||||
return _base.current_value()
|
||||
|
||||
|
||||
func report_success() -> GdUnitFloatAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitFloatAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitFloatAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitFloatAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitFloatAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected :float) -> GdUnitFloatAssert:
|
||||
_base.is_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected :float) -> GdUnitFloatAssert:
|
||||
_base.is_not_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
@warning_ignore("shadowed_global_identifier")
|
||||
func is_equal_approx(expected :float, approx :float) -> GdUnitFloatAssert:
|
||||
return is_between(expected-approx, expected+approx)
|
||||
|
||||
|
||||
func is_less(expected :float) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current >= expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.LESS_THAN, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_less_equal(expected :float) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current > expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.LESS_EQUAL, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_greater(expected :float) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current <= expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.GREATER_THAN, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_greater_equal(expected :float) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current < expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.GREATER_EQUAL, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_negative() -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current >= 0.0:
|
||||
return report_error(GdAssertMessages.error_is_negative(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_negative() -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current < 0.0:
|
||||
return report_error(GdAssertMessages.error_is_not_negative(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_zero() -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or not is_equal_approx(0.00000000, current):
|
||||
return report_error(GdAssertMessages.error_is_zero(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_zero() -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or is_equal_approx(0.00000000, current):
|
||||
return report_error(GdAssertMessages.error_is_not_zero())
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_in(expected :Array) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if not expected.has(current):
|
||||
return report_error(GdAssertMessages.error_is_in(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_in(expected :Array) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if expected.has(current):
|
||||
return report_error(GdAssertMessages.error_is_not_in(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_between(from :float, to :float) -> GdUnitFloatAssert:
|
||||
var current = current_value()
|
||||
if current == null or current < from or current > to:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.BETWEEN_EQUAL, current, from, to))
|
||||
return report_success()
|
||||
159
addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd
Normal file
159
addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
extends GdUnitFuncAssert
|
||||
|
||||
|
||||
const GdUnitTools := preload("res://addons/gdUnit4/src/core/GdUnitTools.gd")
|
||||
const DEFAULT_TIMEOUT := 2000
|
||||
|
||||
|
||||
var _current_value_provider :ValueProvider
|
||||
var _current_error_message :String = ""
|
||||
var _custom_failure_message :String = ""
|
||||
var _line_number := -1
|
||||
var _timeout := DEFAULT_TIMEOUT
|
||||
var _interrupted := false
|
||||
var _sleep_timer :Timer = null
|
||||
|
||||
|
||||
func _init(instance :Object, func_name :String, args := Array()):
|
||||
_line_number = GdUnitAssertions.get_line_number()
|
||||
GdAssertReports.reset_last_error_line_number()
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
# verify at first the function name exists
|
||||
if not instance.has_method(func_name):
|
||||
report_error("The function '%s' do not exists checked instance '%s'." % [func_name, instance])
|
||||
_interrupted = true
|
||||
else:
|
||||
_current_value_provider = CallBackValueProvider.new(instance, func_name, args)
|
||||
|
||||
|
||||
func _notification(_what):
|
||||
if is_instance_valid(_current_value_provider):
|
||||
_current_value_provider.dispose()
|
||||
_current_value_provider = null
|
||||
if is_instance_valid(_sleep_timer):
|
||||
Engine.get_main_loop().root.remove_child(_sleep_timer)
|
||||
_sleep_timer.stop()
|
||||
_sleep_timer.free()
|
||||
_sleep_timer = null
|
||||
|
||||
|
||||
func report_success() -> GdUnitFuncAssert:
|
||||
GdAssertReports.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error_message :String) -> GdUnitFuncAssert:
|
||||
_current_error_message = error_message if _custom_failure_message == "" else _custom_failure_message
|
||||
GdAssertReports.report_error(_current_error_message, _line_number)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _current_error_message
|
||||
|
||||
|
||||
func send_report(report :GdUnitReport)-> void:
|
||||
GdUnitSignals.instance().gdunit_report.emit(report)
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitFuncAssert:
|
||||
_custom_failure_message = message
|
||||
return self
|
||||
|
||||
|
||||
func wait_until(timeout := 2000) -> GdUnitFuncAssert:
|
||||
if timeout <= 0:
|
||||
push_warning("Invalid timeout param, alloed timeouts must be grater than 0. Use default timeout instead")
|
||||
_timeout = DEFAULT_TIMEOUT
|
||||
else:
|
||||
_timeout = timeout
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitFuncAssert:
|
||||
await _validate_callback(cb_is_null)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitFuncAssert:
|
||||
await _validate_callback(cb_is_not_null)
|
||||
return self
|
||||
|
||||
|
||||
func is_false() -> GdUnitFuncAssert:
|
||||
await _validate_callback(cb_is_false)
|
||||
return self
|
||||
|
||||
|
||||
func is_true() -> GdUnitFuncAssert:
|
||||
await _validate_callback(cb_is_true)
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitFuncAssert:
|
||||
await _validate_callback(cb_is_equal, expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitFuncAssert:
|
||||
await _validate_callback(cb_is_not_equal, expected)
|
||||
return self
|
||||
|
||||
|
||||
# we need actually to define this Callable as functions otherwise we results into leaked scripts here
|
||||
# this is actually a Godot bug and needs this kind of workaround
|
||||
func cb_is_null(c, _e): return c == null
|
||||
func cb_is_not_null(c, _e): return c != null
|
||||
func cb_is_false(c, _e): return c == false
|
||||
func cb_is_true(c, _e): return c == true
|
||||
func cb_is_equal(c, e): return GdObjects.equals(c,e)
|
||||
func cb_is_not_equal(c, e): return not GdObjects.equals(c, e)
|
||||
|
||||
|
||||
func _validate_callback(predicate :Callable, expected = null):
|
||||
if _interrupted:
|
||||
return
|
||||
GdUnitMemoryObserver.guard_instance(self)
|
||||
var time_scale = Engine.get_time_scale()
|
||||
var timer := Timer.new()
|
||||
timer.set_name("gdunit_funcassert_interrupt_timer_%d" % timer.get_instance_id())
|
||||
Engine.get_main_loop().root.add_child(timer)
|
||||
timer.add_to_group("GdUnitTimers")
|
||||
timer.timeout.connect(func do_interrupt():
|
||||
_interrupted = true
|
||||
, CONNECT_DEFERRED)
|
||||
timer.set_one_shot(true)
|
||||
timer.start((_timeout/1000.0)*time_scale)
|
||||
_sleep_timer = Timer.new()
|
||||
_sleep_timer.set_name("gdunit_funcassert_sleep_timer_%d" % _sleep_timer.get_instance_id() )
|
||||
Engine.get_main_loop().root.add_child(_sleep_timer)
|
||||
|
||||
while true:
|
||||
var current = await next_current_value()
|
||||
# is interupted or predicate success
|
||||
if _interrupted or predicate.call(current, expected):
|
||||
break
|
||||
if is_instance_valid(_sleep_timer):
|
||||
_sleep_timer.start(0.05)
|
||||
await _sleep_timer.timeout
|
||||
|
||||
_sleep_timer.stop()
|
||||
await Engine.get_main_loop().process_frame
|
||||
if _interrupted:
|
||||
# https://github.com/godotengine/godot/issues/73052
|
||||
#var predicate_name = predicate.get_method()
|
||||
var predicate_name :String = str(predicate).split('::')[1]
|
||||
report_error(GdAssertMessages.error_interrupted(predicate_name.strip_edges().trim_prefix("cb_"), expected, LocalTime.elapsed(_timeout)))
|
||||
else:
|
||||
report_success()
|
||||
_sleep_timer.free()
|
||||
timer.free()
|
||||
GdUnitMemoryObserver.unguard_instance(self)
|
||||
|
||||
|
||||
func next_current_value() -> Variant:
|
||||
@warning_ignore("redundant_await")
|
||||
if is_instance_valid(_current_value_provider):
|
||||
return await _current_value_provider.get_value()
|
||||
return "invalid value"
|
||||
106
addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd
Normal file
106
addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
extends GdUnitGodotErrorAssert
|
||||
|
||||
var _current_error_message :String
|
||||
var _callable :Callable
|
||||
|
||||
|
||||
func _init(callable :Callable):
|
||||
# we only support Godot 4.1.x+ because of await issue https://github.com/godotengine/godot/issues/80292
|
||||
assert(Engine.get_version_info().hex >= 0x40100,
|
||||
"This assertion is not supported for Godot 4.0.x. Please upgrade to the minimum version Godot 4.1.0!")
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
GdAssertReports.reset_last_error_line_number()
|
||||
_callable = callable
|
||||
|
||||
|
||||
func _execute() -> Array[ErrorLogEntry]:
|
||||
# execute the given code and monitor for runtime errors
|
||||
if _callable == null or not _callable.is_valid():
|
||||
_report_error("Invalid Callable '%s'" % _callable)
|
||||
else:
|
||||
await _callable.call()
|
||||
return await _error_monitor().scan(true)
|
||||
|
||||
|
||||
func _error_monitor() -> GodotGdErrorMonitor:
|
||||
return GdUnitThreadManager.get_current_context().get_execution_context().error_monitor
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _current_error_message
|
||||
|
||||
|
||||
func _report_success() -> GdUnitAssert:
|
||||
GdAssertReports.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func _report_error(error_message :String, failure_line_number: int = -1) -> GdUnitAssert:
|
||||
var line_number := failure_line_number if failure_line_number != -1 else GdUnitAssertions.get_line_number()
|
||||
_current_error_message = error_message
|
||||
GdAssertReports.report_error(error_message, line_number)
|
||||
return self
|
||||
|
||||
|
||||
func _has_log_entry(log_entries :Array[ErrorLogEntry], type :ErrorLogEntry.TYPE, error :String) -> bool:
|
||||
for entry in log_entries:
|
||||
if entry._type == type and entry._message == error:
|
||||
# Erase the log entry we already handled it by this assertion, otherwise it will report at twice
|
||||
_error_monitor().erase_log_entry(entry)
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _to_list(log_entries :Array[ErrorLogEntry]) -> String:
|
||||
if log_entries.is_empty():
|
||||
return "no errors"
|
||||
if log_entries.size() == 1:
|
||||
return log_entries[0]._message
|
||||
var value := ""
|
||||
for entry in log_entries:
|
||||
value += "'%s'\n" % entry._message
|
||||
return value
|
||||
|
||||
|
||||
func is_success() -> GdUnitGodotErrorAssert:
|
||||
var log_entries := await _execute()
|
||||
if log_entries.is_empty():
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: no error's are ocured.
|
||||
but found: '%s'
|
||||
""".dedent().trim_prefix("\n") % _to_list(log_entries))
|
||||
|
||||
|
||||
func is_runtime_error(expected_error :String) -> GdUnitGodotErrorAssert:
|
||||
var log_entries := await _execute()
|
||||
if _has_log_entry(log_entries, ErrorLogEntry.TYPE.SCRIPT_ERROR, expected_error):
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: a runtime error is triggered.
|
||||
message: '%s'
|
||||
found: %s
|
||||
""".dedent().trim_prefix("\n") % [expected_error, _to_list(log_entries)])
|
||||
|
||||
|
||||
func is_push_warning(expected_warning :String) -> GdUnitGodotErrorAssert:
|
||||
var log_entries := await _execute()
|
||||
if _has_log_entry(log_entries, ErrorLogEntry.TYPE.PUSH_WARNING, expected_warning):
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: push_warning() is called.
|
||||
message: '%s'
|
||||
found: %s
|
||||
""".dedent().trim_prefix("\n") % [expected_warning, _to_list(log_entries)])
|
||||
|
||||
|
||||
func is_push_error(expected_error :String) -> GdUnitGodotErrorAssert:
|
||||
var log_entries := await _execute()
|
||||
if _has_log_entry(log_entries, ErrorLogEntry.TYPE.PUSH_ERROR, expected_error):
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: push_error() is called.
|
||||
message: '%s'
|
||||
found: %s
|
||||
""".dedent().trim_prefix("\n") % [expected_error, _to_list(log_entries)])
|
||||
153
addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd
Normal file
153
addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
extends GdUnitIntAssert
|
||||
|
||||
var _base: GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not GdUnitAssertions.validate_value_type(current, TYPE_INT):
|
||||
report_error("GdUnitIntAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func current_value() -> Variant:
|
||||
return _base.current_value()
|
||||
|
||||
|
||||
func report_success() -> GdUnitIntAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitIntAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitIntAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitIntAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitIntAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected :int) -> GdUnitIntAssert:
|
||||
_base.is_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected :int) -> GdUnitIntAssert:
|
||||
_base.is_not_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_less(expected :int) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current >= expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.LESS_THAN, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_less_equal(expected :int) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current > expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.LESS_EQUAL, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_greater(expected :int) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current <= expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.GREATER_THAN, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_greater_equal(expected :int) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current < expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.GREATER_EQUAL, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_even() -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current % 2 != 0:
|
||||
return report_error(GdAssertMessages.error_is_even(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_odd() -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current % 2 == 0:
|
||||
return report_error(GdAssertMessages.error_is_odd(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_negative() -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current >= 0:
|
||||
return report_error(GdAssertMessages.error_is_negative(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_negative() -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current < 0:
|
||||
return report_error(GdAssertMessages.error_is_not_negative(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_zero() -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current != 0:
|
||||
return report_error(GdAssertMessages.error_is_zero(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_zero() -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == 0:
|
||||
return report_error(GdAssertMessages.error_is_not_zero())
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_in(expected :Array) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if not expected.has(current):
|
||||
return report_error(GdAssertMessages.error_is_in(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_in(expected :Array) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if expected.has(current):
|
||||
return report_error(GdAssertMessages.error_is_not_in(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_between(from :int, to :int) -> GdUnitIntAssert:
|
||||
var current = current_value()
|
||||
if current == null or current < from or current > to:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.BETWEEN_EQUAL, current, from, to))
|
||||
return report_success()
|
||||
109
addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd
Normal file
109
addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
extends GdUnitObjectAssert
|
||||
|
||||
var _base :GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if (current != null
|
||||
and (GdUnitAssertions.validate_value_type(current, TYPE_BOOL)
|
||||
or GdUnitAssertions.validate_value_type(current, TYPE_INT)
|
||||
or GdUnitAssertions.validate_value_type(current, TYPE_FLOAT)
|
||||
or GdUnitAssertions.validate_value_type(current, TYPE_STRING))):
|
||||
report_error("GdUnitObjectAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func current_value() -> Variant:
|
||||
return _base.current_value()
|
||||
|
||||
|
||||
func report_success() -> GdUnitObjectAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitObjectAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitObjectAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitObjectAssert:
|
||||
_base.is_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitObjectAssert:
|
||||
_base.is_not_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitObjectAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitObjectAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
@warning_ignore("shadowed_global_identifier")
|
||||
func is_same(expected) -> GdUnitObjectAssert:
|
||||
var current :Variant = current_value()
|
||||
if not is_same(current, expected):
|
||||
report_error(GdAssertMessages.error_is_same(current, expected))
|
||||
return self
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_same(expected) -> GdUnitObjectAssert:
|
||||
var current = current_value()
|
||||
if is_same(current, expected):
|
||||
report_error(GdAssertMessages.error_not_same(current, expected))
|
||||
return self
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_instanceof(type :Object) -> GdUnitObjectAssert:
|
||||
var current = current_value()
|
||||
if current == null or not is_instance_of(current, type):
|
||||
var result_expected: = GdObjects.extract_class_name(type)
|
||||
var result_current: = GdObjects.extract_class_name(current)
|
||||
report_error(GdAssertMessages.error_is_instanceof(result_current, result_expected))
|
||||
return self
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_instanceof(type) -> GdUnitObjectAssert:
|
||||
var current :Variant = current_value()
|
||||
if is_instance_of(current, type):
|
||||
var result: = GdObjects.extract_class_name(type)
|
||||
if result.is_success():
|
||||
report_error("Expected not be a instance of <%s>" % result.value())
|
||||
else:
|
||||
push_error("Internal ERROR: %s" % result.error_message())
|
||||
return self
|
||||
report_success()
|
||||
return self
|
||||
121
addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd
Normal file
121
addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
extends GdUnitResultAssert
|
||||
|
||||
var _base :GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not validate_value_type(current):
|
||||
report_error("GdUnitResultAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func validate_value_type(value) -> bool:
|
||||
return value == null or value is GdUnitResult
|
||||
|
||||
|
||||
func current_value() -> GdUnitResult:
|
||||
return _base.current_value() as GdUnitResult
|
||||
|
||||
|
||||
func report_success() -> GdUnitResultAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitResultAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitResultAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitResultAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
func is_not_null() -> GdUnitResultAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_empty() -> GdUnitResultAssert:
|
||||
var result := current_value()
|
||||
if result == null or not result.is_empty():
|
||||
report_error(GdAssertMessages.error_result_is_empty(result))
|
||||
else:
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_success() -> GdUnitResultAssert:
|
||||
var result := current_value()
|
||||
if result == null or not result.is_success():
|
||||
report_error(GdAssertMessages.error_result_is_success(result))
|
||||
else:
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_warning() -> GdUnitResultAssert:
|
||||
var result := current_value()
|
||||
if result == null or not result.is_warn():
|
||||
report_error(GdAssertMessages.error_result_is_warning(result))
|
||||
else:
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_error() -> GdUnitResultAssert:
|
||||
var result := current_value()
|
||||
if result == null or not result.is_error():
|
||||
report_error(GdAssertMessages.error_result_is_error(result))
|
||||
else:
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func contains_message(expected :String) -> GdUnitResultAssert:
|
||||
var result := current_value()
|
||||
if result == null:
|
||||
report_error(GdAssertMessages.error_result_has_message("<null>", expected))
|
||||
return self
|
||||
if result.is_success():
|
||||
report_error(GdAssertMessages.error_result_has_message_on_success(expected))
|
||||
elif result.is_error() and result.error_message() != expected:
|
||||
report_error(GdAssertMessages.error_result_has_message(result.error_message(), expected))
|
||||
elif result.is_warn() and result.warn_message() != expected:
|
||||
report_error(GdAssertMessages.error_result_has_message(result.warn_message(), expected))
|
||||
else:
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_value(expected) -> GdUnitResultAssert:
|
||||
var result := current_value()
|
||||
var value = null if result == null else result.value()
|
||||
if not GdObjects.equals(value, expected):
|
||||
report_error(GdAssertMessages.error_result_is_value(value, expected))
|
||||
else:
|
||||
report_success()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitResultAssert:
|
||||
return is_value(expected)
|
||||
110
addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd
Normal file
110
addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
extends GdUnitSignalAssert
|
||||
|
||||
const DEFAULT_TIMEOUT := 2000
|
||||
|
||||
var _signal_collector :GdUnitSignalCollector
|
||||
var _emitter :Object
|
||||
var _current_error_message :String = ""
|
||||
var _custom_failure_message :String = ""
|
||||
var _line_number := -1
|
||||
var _timeout := DEFAULT_TIMEOUT
|
||||
var _interrupted := false
|
||||
|
||||
|
||||
func _init(emitter :Object):
|
||||
# save the actual assert instance on the current thread context
|
||||
var context := GdUnitThreadManager.get_current_context()
|
||||
context.set_assert(self)
|
||||
_signal_collector = context.get_signal_collector()
|
||||
_line_number = GdUnitAssertions.get_line_number()
|
||||
_emitter = emitter
|
||||
GdAssertReports.reset_last_error_line_number()
|
||||
|
||||
|
||||
func report_success() -> GdUnitAssert:
|
||||
GdAssertReports.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_warning(message :String) -> GdUnitAssert:
|
||||
GdAssertReports.report_warning(message, GdUnitAssertions.get_line_number())
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error_message :String) -> GdUnitAssert:
|
||||
_current_error_message = error_message if _custom_failure_message == "" else _custom_failure_message
|
||||
GdAssertReports.report_error(_current_error_message, _line_number)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _current_error_message
|
||||
|
||||
|
||||
func send_report(report :GdUnitReport)-> void:
|
||||
GdUnitSignals.instance().gdunit_report.emit(report)
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitSignalAssert:
|
||||
_custom_failure_message = message
|
||||
return self
|
||||
|
||||
|
||||
func wait_until(timeout := 2000) -> GdUnitSignalAssert:
|
||||
if timeout <= 0:
|
||||
report_warning("Invalid timeout parameter, allowed timeouts must be greater than 0, use default timeout instead!")
|
||||
_timeout = DEFAULT_TIMEOUT
|
||||
else:
|
||||
_timeout = timeout
|
||||
return self
|
||||
|
||||
|
||||
# Verifies the signal exists checked the emitter
|
||||
func is_signal_exists(signal_name :String) -> GdUnitSignalAssert:
|
||||
if not _emitter.has_signal(signal_name):
|
||||
report_error("The signal '%s' not exists checked object '%s'." % [signal_name, _emitter.get_class()])
|
||||
return self
|
||||
|
||||
|
||||
# Verifies that given signal is emitted until waiting time
|
||||
func is_emitted(name :String, args := []) -> GdUnitSignalAssert:
|
||||
_line_number = GdUnitAssertions.get_line_number()
|
||||
return await _wail_until_signal(name, args, false)
|
||||
|
||||
|
||||
# Verifies that given signal is NOT emitted until waiting time
|
||||
func is_not_emitted(name :String, args := []) -> GdUnitSignalAssert:
|
||||
_line_number = GdUnitAssertions.get_line_number()
|
||||
return await _wail_until_signal(name, args, true)
|
||||
|
||||
|
||||
func _wail_until_signal(signal_name :String, expected_args :Array, expect_not_emitted: bool) -> GdUnitSignalAssert:
|
||||
if _emitter == null:
|
||||
report_error("Can't wait for signal checked a NULL object.")
|
||||
return self
|
||||
# first verify the signal is defined
|
||||
if not _emitter.has_signal(signal_name):
|
||||
report_error("Can't wait for non-existion signal '%s' checked object '%s'." % [signal_name,_emitter.get_class()])
|
||||
return self
|
||||
_signal_collector.register_emitter(_emitter)
|
||||
var time_scale = Engine.get_time_scale()
|
||||
var timer := Timer.new()
|
||||
Engine.get_main_loop().root.add_child(timer)
|
||||
timer.add_to_group("GdUnitTimers")
|
||||
timer.set_one_shot(true)
|
||||
timer.timeout.connect(func on_timeout(): _interrupted = true)
|
||||
timer.start((_timeout/1000.0)*time_scale)
|
||||
var is_signal_emitted = false
|
||||
while not _interrupted and not is_signal_emitted:
|
||||
await Engine.get_main_loop().process_frame
|
||||
if is_instance_valid(_emitter):
|
||||
is_signal_emitted = _signal_collector.match(_emitter, signal_name, expected_args)
|
||||
if is_signal_emitted and expect_not_emitted:
|
||||
report_error(GdAssertMessages.error_signal_emitted(signal_name, expected_args, LocalTime.elapsed(int(_timeout-timer.time_left*1000))))
|
||||
|
||||
if _interrupted and not expect_not_emitted:
|
||||
report_error(GdAssertMessages.error_wait_signal(signal_name, expected_args, LocalTime.elapsed(_timeout)))
|
||||
timer.free()
|
||||
if is_instance_valid(_emitter):
|
||||
_signal_collector.reset_received_signals(_emitter, signal_name, expected_args)
|
||||
return self
|
||||
176
addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd
Normal file
176
addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
extends GdUnitStringAssert
|
||||
|
||||
var _base :GdUnitAssert
|
||||
|
||||
|
||||
func _init(current):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if current != null and typeof(current) != TYPE_STRING and typeof(current) != TYPE_STRING_NAME:
|
||||
report_error("GdUnitStringAssert inital error, unexpected type <%s>" % GdObjects.typeof_as_string(current))
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func current_value():
|
||||
var current = _base.current_value()
|
||||
if current == null:
|
||||
return null
|
||||
return current as String
|
||||
|
||||
|
||||
func report_success() -> GdUnitStringAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitStringAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitStringAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitStringAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitStringAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_equal(current, expected))
|
||||
if not GdObjects.equals(current, expected):
|
||||
var diffs := GdDiffTool.string_diff(current, expected)
|
||||
var formatted_current := GdAssertMessages.colored_array_div(diffs[1])
|
||||
return report_error(GdAssertMessages.error_equal(formatted_current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_equal_ignoring_case(expected) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_equal_ignoring_case(current, expected))
|
||||
if not GdObjects.equals(current, expected, true):
|
||||
var diffs := GdDiffTool.string_diff(current, expected)
|
||||
var formatted_current := GdAssertMessages.colored_array_div(diffs[1])
|
||||
return report_error(GdAssertMessages.error_equal_ignoring_case(formatted_current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_equal(expected) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if GdObjects.equals(current, expected):
|
||||
return report_error(GdAssertMessages.error_not_equal(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_equal_ignoring_case(expected) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if GdObjects.equals(current, expected, true):
|
||||
return report_error(GdAssertMessages.error_not_equal(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_empty() -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null or not current.is_empty():
|
||||
return report_error(GdAssertMessages.error_is_empty(current))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_empty() -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null or current.is_empty():
|
||||
return report_error(GdAssertMessages.error_is_not_empty())
|
||||
return report_success()
|
||||
|
||||
|
||||
func contains(expected :String) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null or current.find(expected) == -1:
|
||||
return report_error(GdAssertMessages.error_contains(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func not_contains(expected :String) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current != null and current.find(expected) != -1:
|
||||
return report_error(GdAssertMessages.error_not_contains(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func contains_ignoring_case(expected :String) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null or current.findn(expected) == -1:
|
||||
return report_error(GdAssertMessages.error_contains_ignoring_case(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func not_contains_ignoring_case(expected :String) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current != null and current.findn(expected) != -1:
|
||||
return report_error(GdAssertMessages.error_not_contains_ignoring_case(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func starts_with(expected :String) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null or current.find(expected) != 0:
|
||||
return report_error(GdAssertMessages.error_starts_with(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func ends_with(expected :String) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_ends_with(current, expected))
|
||||
var find = current.length() - expected.length()
|
||||
if current.rfind(expected) != find:
|
||||
return report_error(GdAssertMessages.error_ends_with(current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
# gdlint:disable=max-returns
|
||||
func has_length(expected :int, comparator :int = Comparator.EQUAL) -> GdUnitStringAssert:
|
||||
var current = current_value()
|
||||
if current == null:
|
||||
return report_error(GdAssertMessages.error_has_length(current, expected, comparator))
|
||||
match comparator:
|
||||
Comparator.EQUAL:
|
||||
if current.length() != expected:
|
||||
return report_error(GdAssertMessages.error_has_length(current, expected, comparator))
|
||||
Comparator.LESS_THAN:
|
||||
if current.length() >= expected:
|
||||
return report_error(GdAssertMessages.error_has_length(current, expected, comparator))
|
||||
Comparator.LESS_EQUAL:
|
||||
if current.length() > expected:
|
||||
return report_error(GdAssertMessages.error_has_length(current, expected, comparator))
|
||||
Comparator.GREATER_THAN:
|
||||
if current.length() <= expected:
|
||||
return report_error(GdAssertMessages.error_has_length(current, expected, comparator))
|
||||
Comparator.GREATER_EQUAL:
|
||||
if current.length() < expected:
|
||||
return report_error(GdAssertMessages.error_has_length(current, expected, comparator))
|
||||
_:
|
||||
return report_error("Comparator '%d' not implemented!" % comparator)
|
||||
return report_success()
|
||||
172
addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd
Normal file
172
addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
extends GdUnitVectorAssert
|
||||
|
||||
var _base: GdUnitAssert
|
||||
var _current_type :int
|
||||
|
||||
|
||||
func _init(current :Variant):
|
||||
_base = ResourceLoader.load("res://addons/gdUnit4/src/asserts/GdUnitAssertImpl.gd", "GDScript",
|
||||
ResourceLoader.CACHE_MODE_REUSE).new(current)
|
||||
# save the actual assert instance on the current thread context
|
||||
GdUnitThreadManager.get_current_context().set_assert(self)
|
||||
if not _validate_value_type(current):
|
||||
report_error("GdUnitVectorAssert error, the type <%s> is not supported." % GdObjects.typeof_as_string(current))
|
||||
_current_type = typeof(current)
|
||||
|
||||
|
||||
func _notification(event):
|
||||
if event == NOTIFICATION_PREDELETE:
|
||||
if _base != null:
|
||||
_base.notification(event)
|
||||
_base = null
|
||||
|
||||
|
||||
func _validate_value_type(value) -> bool:
|
||||
return (
|
||||
value == null
|
||||
or typeof(value) in [
|
||||
TYPE_VECTOR2,
|
||||
TYPE_VECTOR2I,
|
||||
TYPE_VECTOR3,
|
||||
TYPE_VECTOR3I,
|
||||
TYPE_VECTOR4,
|
||||
TYPE_VECTOR4I
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
func _validate_is_vector_type(value :Variant) -> bool:
|
||||
var type := typeof(value)
|
||||
if type == _current_type or _current_type == TYPE_NIL:
|
||||
return true
|
||||
report_error(GdAssertMessages.error_is_wrong_type(_current_type, type))
|
||||
return false
|
||||
|
||||
|
||||
func current_value() -> Variant:
|
||||
return _base.current_value()
|
||||
|
||||
|
||||
func report_success() -> GdUnitVectorAssert:
|
||||
_base.report_success()
|
||||
return self
|
||||
|
||||
|
||||
func report_error(error :String) -> GdUnitVectorAssert:
|
||||
_base.report_error(error)
|
||||
return self
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
return _base._current_error_message
|
||||
|
||||
|
||||
func override_failure_message(message :String) -> GdUnitVectorAssert:
|
||||
_base.override_failure_message(message)
|
||||
return self
|
||||
|
||||
|
||||
func is_null() -> GdUnitVectorAssert:
|
||||
_base.is_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_not_null() -> GdUnitVectorAssert:
|
||||
_base.is_not_null()
|
||||
return self
|
||||
|
||||
|
||||
func is_equal(expected :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected):
|
||||
return self
|
||||
_base.is_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
func is_not_equal(expected :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected):
|
||||
return self
|
||||
_base.is_not_equal(expected)
|
||||
return self
|
||||
|
||||
|
||||
@warning_ignore("shadowed_global_identifier")
|
||||
func is_equal_approx(expected :Variant, approx :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected) or not _validate_is_vector_type(approx):
|
||||
return self
|
||||
var current = current_value()
|
||||
var from = expected - approx
|
||||
var to = expected + approx
|
||||
if current == null or (not _is_equal_approx(current, from, to)):
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.BETWEEN_EQUAL, current, from, to))
|
||||
return report_success()
|
||||
|
||||
|
||||
func _is_equal_approx(current, from, to) -> bool:
|
||||
match typeof(current):
|
||||
TYPE_VECTOR2, TYPE_VECTOR2I:
|
||||
return ((current.x >= from.x and current.y >= from.y)
|
||||
and (current.x <= to.x and current.y <= to.y))
|
||||
TYPE_VECTOR3, TYPE_VECTOR3I:
|
||||
return ((current.x >= from.x and current.y >= from.y and current.z >= from.z)
|
||||
and (current.x <= to.x and current.y <= to.y and current.z <= to.z))
|
||||
TYPE_VECTOR4, TYPE_VECTOR4I:
|
||||
return ((current.x >= from.x and current.y >= from.y and current.z >= from.z and current.w >= from.w)
|
||||
and (current.x <= to.x and current.y <= to.y and current.z <= to.z and current.w <= to.w))
|
||||
_:
|
||||
push_error("Missing implementation '_is_equal_approx' for vector type %s" % typeof(current))
|
||||
return false
|
||||
|
||||
|
||||
func is_less(expected :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected):
|
||||
return self
|
||||
var current = current_value()
|
||||
if current == null or current >= expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.LESS_THAN, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_less_equal(expected :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected):
|
||||
return self
|
||||
var current = current_value()
|
||||
if current == null or current > expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.LESS_EQUAL, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_greater(expected :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected):
|
||||
return self
|
||||
var current = current_value()
|
||||
if current == null or current <= expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.GREATER_THAN, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_greater_equal(expected :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(expected):
|
||||
return self
|
||||
var current = current_value()
|
||||
if current == null or current < expected:
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.GREATER_EQUAL, current, expected))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_between(from :Variant, to :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(from) or not _validate_is_vector_type(to):
|
||||
return self
|
||||
var current = current_value()
|
||||
if current == null or not (current >= from and current <= to):
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.BETWEEN_EQUAL, current, from, to))
|
||||
return report_success()
|
||||
|
||||
|
||||
func is_not_between(from :Variant, to :Variant) -> GdUnitVectorAssert:
|
||||
if not _validate_is_vector_type(from) or not _validate_is_vector_type(to):
|
||||
return self
|
||||
var current = current_value()
|
||||
if (current != null and current >= from and current <= to):
|
||||
return report_error(GdAssertMessages.error_is_value(Comparator.NOT_BETWEEN_EQUAL, current, from, to))
|
||||
return report_success()
|
||||
6
addons/gdUnit4/src/asserts/ValueProvider.gd
Normal file
6
addons/gdUnit4/src/asserts/ValueProvider.gd
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# base interface for assert value provider
|
||||
class_name ValueProvider
|
||||
extends RefCounted
|
||||
|
||||
func get_value():
|
||||
pass
|
||||
Loading…
Add table
Add a link
Reference in a new issue