summaryrefslogtreecommitdiff
path: root/addons/gut/test.gd
diff options
context:
space:
mode:
authorSophia Pearson <codergal89@gmail.com>2022-10-03 22:22:50 +0200
committerSophia Pearson <codergal89@gmail.com>2022-10-04 22:18:18 +0200
commite127ad39e742396030352240d829bc903b1d4464 (patch)
tree10cc21d70bf13181aef7c8ad0344077ff63579a3 /addons/gut/test.gd
parentddbb045f6387a8ba23b1210b27a745516a387a52 (diff)
downloadtexty-e127ad39e742396030352240d829bc903b1d4464.tar.xz
texty-e127ad39e742396030352240d829bc903b1d4464.zip
godot: inital Godot 4 migration
Diffstat (limited to 'addons/gut/test.gd')
-rw-r--r--addons/gut/test.gd1687
1 files changed, 0 insertions, 1687 deletions
diff --git a/addons/gut/test.gd b/addons/gut/test.gd
deleted file mode 100644
index 3fc0e8f..0000000
--- a/addons/gut/test.gd
+++ /dev/null
@@ -1,1687 +0,0 @@
-class_name GutTest
-# ##############################################################################
-#(G)odot (U)nit (T)est class
-#
-# ##############################################################################
-# The MIT License (MIT)
-# =====================
-#
-# Copyright (c) 2020 Tom "Butch" Wesley
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# ##############################################################################
-# View readme for usage details.
-#
-# Version - see gut.gd
-# ##############################################################################
-# Class that all test scripts must extend.
-#
-# This provides all the asserts and other testing features. Test scripts are
-# run by the Gut class in gut.gd
-# ##############################################################################
-extends Node
-
-# ------------------------------------------------------------------------------
-# Helper class to hold info for objects to double. This extracts info and has
-# some convenience methods. This is key in being able to make the "smart double"
-# method which makes doubling much easier for the user.
-# -----------------------------------------------------------------------------
-class DoubleInfo:
- var path
- var subpath
- var strategy
- var make_partial
- var extension
- var _utils = load('res://addons/gut/utils.gd').get_instance()
- var _is_native = false
- var is_valid = false
-
- # Flexible init method. p2 can be subpath or stategy unless p3 is
- # specified, then p2 must be subpath and p3 is strategy.
- #
- # Examples:
- # (object_to_double)
- # (object_to_double, subpath)
- # (object_to_double, strategy)
- # (object_to_double, subpath, strategy)
- func _init(thing, p2=null, p3=null):
- strategy = p2
-
- # short-circuit and ensure that is_valid
- # is not set to true.
- if(_utils.is_instance(thing)):
- return
-
- if(typeof(p2) == TYPE_STRING):
- strategy = p3
- subpath = p2
-
- if(typeof(thing) == TYPE_OBJECT):
- if(_utils.is_native_class(thing)):
- path = thing
- _is_native = true
- extension = 'native_class_not_used'
- else:
- path = thing.resource_path
- else:
- path = thing
-
- if(!_is_native):
- extension = path.get_extension()
-
- is_valid = true
-
- func is_scene():
- return extension == 'tscn'
-
- func is_script():
- return extension == 'gd'
-
- func is_native():
- return _is_native
-
-# ------------------------------------------------------------------------------
-# Begin test.gd
-# ------------------------------------------------------------------------------
-var _utils = load('res://addons/gut/utils.gd').get_instance()
-var _compare = _utils.Comparator.new()
-
-# constant for signal when calling yield_for
-const YIELD = 'timeout'
-
-# Need a reference to the instance that is running the tests. This
-# is set by the gut class when it runs the tests. This gets you
-# access to the asserts in the tests you write.
-var gut = null
-
-var _disable_strict_datatype_checks = false
-# Holds all the text for a test's fail/pass. This is used for testing purposes
-# to see the text of a failed sub-test in test_test.gd
-var _fail_pass_text = []
-
-const EDITOR_PROPERTY = PROPERTY_USAGE_SCRIPT_VARIABLE | PROPERTY_USAGE_DEFAULT
-const VARIABLE_PROPERTY = PROPERTY_USAGE_SCRIPT_VARIABLE
-
-# Used with assert_setget
-enum {
- DEFAULT_SETTER_GETTER,
- SETTER_ONLY,
- GETTER_ONLY
-}
-
-# Summary counts for the test.
-var _summary = {
- asserts = 0,
- passed = 0,
- failed = 0,
- tests = 0,
- pending = 0
-}
-
-# This is used to watch signals so we can make assertions about them.
-var _signal_watcher = load('res://addons/gut/signal_watcher.gd').new()
-
-# Convenience copy of _utils.DOUBLE_STRATEGY
-var DOUBLE_STRATEGY = null
-var _lgr = _utils.get_logger()
-var _strutils = _utils.Strutils.new()
-
-# syntax sugar
-var ParameterFactory = _utils.ParameterFactory
-var CompareResult = _utils.CompareResult
-var InputFactory = _utils.InputFactory
-var InputSender = _utils.InputSender
-
-func _init():
- DOUBLE_STRATEGY = _utils.DOUBLE_STRATEGY # yes, this is right
-
-func _str(thing):
- return _strutils.type2str(thing)
-
-# ------------------------------------------------------------------------------
-# Fail an assertion. Causes test and script to fail as well.
-# ------------------------------------------------------------------------------
-func _fail(text):
- _summary.asserts += 1
- _summary.failed += 1
- _fail_pass_text.append('failed: ' + text)
- if(gut):
- _lgr.failed(text)
- gut._fail(text)
-
-# ------------------------------------------------------------------------------
-# Pass an assertion.
-# ------------------------------------------------------------------------------
-func _pass(text):
- _summary.asserts += 1
- _summary.passed += 1
- _fail_pass_text.append('passed: ' + text)
- if(gut):
- _lgr.passed(text)
- gut._pass(text)
-
-# ------------------------------------------------------------------------------
-# Checks if the datatypes passed in match. If they do not then this will cause
-# a fail to occur. If they match then TRUE is returned, FALSE if not. This is
-# used in all the assertions that compare values.
-# ------------------------------------------------------------------------------
-func _do_datatypes_match__fail_if_not(got, expected, text):
- var did_pass = true
-
- if(!_disable_strict_datatype_checks):
- var got_type = typeof(got)
- var expect_type = typeof(expected)
- if(got_type != expect_type and got != null and expected != null):
- # If we have a mismatch between float and int (types 2 and 3) then
- # print out a warning but do not fail.
- if([2, 3].has(got_type) and [2, 3].has(expect_type)):
- _lgr.warn(str('Warn: Float/Int comparison. Got ', _strutils.types[got_type],
- ' but expected ', _strutils.types[expect_type]))
- else:
- _fail('Cannot compare ' + _strutils.types[got_type] + '[' + _str(got) + '] to ' + \
- _strutils.types[expect_type] + '[' + _str(expected) + ']. ' + text)
- did_pass = false
-
- return did_pass
-
-# ------------------------------------------------------------------------------
-# Create a string that lists all the methods that were called on an spied
-# instance.
-# ------------------------------------------------------------------------------
-func _get_desc_of_calls_to_instance(inst):
- var BULLET = ' * '
- var calls = gut.get_spy().get_call_list_as_string(inst)
- # indent all the calls
- calls = BULLET + calls.replace("\n", "\n" + BULLET)
- # remove trailing newline and bullet
- calls = calls.substr(0, calls.length() - BULLET.length() - 1)
- return "Calls made on " + str(inst) + "\n" + calls
-
-# ------------------------------------------------------------------------------
-# Signal assertion helper. Do not call directly, use _can_make_signal_assertions
-# ------------------------------------------------------------------------------
-func _fail_if_does_not_have_signal(object, signal_name):
- var did_fail = false
- if(!_signal_watcher.does_object_have_signal(object, signal_name)):
- _fail(str('Object ', object, ' does not have the signal [', signal_name, ']'))
- did_fail = true
- return did_fail
-
-# ------------------------------------------------------------------------------
-# Signal assertion helper. Do not call directly, use _can_make_signal_assertions
-# ------------------------------------------------------------------------------
-func _fail_if_not_watching(object):
- var did_fail = false
- if(!_signal_watcher.is_watching_object(object)):
- _fail(str('Cannot make signal assertions because the object ', object, \
- ' is not being watched. Call watch_signals(some_object) to be able to make assertions about signals.'))
- did_fail = true
- return did_fail
-
-# ------------------------------------------------------------------------------
-# Returns text that contains original text and a list of all the signals that
-# were emitted for the passed in object.
-# ------------------------------------------------------------------------------
-func _get_fail_msg_including_emitted_signals(text, object):
- return str(text," (Signals emitted: ", _signal_watcher.get_signals_emitted(object), ")")
-
-# ------------------------------------------------------------------------------
-# This validates that parameters is an array and generates a specific error
-# and a failure with a specific message
-# ------------------------------------------------------------------------------
-func _fail_if_parameters_not_array(parameters):
- var invalid = parameters != null and typeof(parameters) != TYPE_ARRAY
- if(invalid):
- _lgr.error('The "parameters" parameter must be an array of expected parameter values.')
- _fail('Cannot compare paramter values because an array was not passed.')
- return invalid
-
-
-func _create_obj_from_type(type):
- var obj = null
- if type.is_class("PackedScene"):
- obj = type.instance()
- add_child(obj)
- else:
- obj = type.new()
- return obj
-
-
-# #######################
-# Virtual Methods
-# #######################
-
-# alias for prerun_setup
-func before_all():
- pass
-
-# alias for setup
-func before_each():
- pass
-
-# alias for postrun_teardown
-func after_all():
- pass
-
-# alias for teardown
-func after_each():
- pass
-
-# #######################
-# Public
-# #######################
-
-func get_logger():
- return _lgr
-
-func set_logger(logger):
- _lgr = logger
-
-
-# #######################
-# Asserts
-# #######################
-
-# ------------------------------------------------------------------------------
-# Asserts that the expected value equals the value got.
-# ------------------------------------------------------------------------------
-func assert_eq(got, expected, text=""):
-
- if(_do_datatypes_match__fail_if_not(got, expected, text)):
- var disp = "[" + _str(got) + "] expected to equal [" + _str(expected) + "]: " + text
- var result = null
-
- if(typeof(got) == TYPE_ARRAY):
- result = _compare.shallow(got, expected)
- else:
- result = _compare.simple(got, expected)
-
- if(typeof(got) in [TYPE_ARRAY, TYPE_DICTIONARY]):
- disp = str(result.summary, ' ', text)
-
- if(result.are_equal):
- _pass(disp)
- else:
- _fail(disp)
-
-
-# ------------------------------------------------------------------------------
-# Asserts that the value got does not equal the "not expected" value.
-# ------------------------------------------------------------------------------
-func assert_ne(got, not_expected, text=""):
- if(_do_datatypes_match__fail_if_not(got, not_expected, text)):
- var disp = "[" + _str(got) + "] expected to not equal [" + _str(not_expected) + "]: " + text
- var result = null
-
- if(typeof(got) == TYPE_ARRAY):
- result = _compare.shallow(got, not_expected)
- else:
- result = _compare.simple(got, not_expected)
-
- if(typeof(got) in [TYPE_ARRAY, TYPE_DICTIONARY]):
- disp = str(result.summary, ' ', text)
-
- if(result.are_equal):
- _fail(disp)
- else:
- _pass(disp)
-
-
-# ------------------------------------------------------------------------------
-# Asserts that the expected value almost equals the value got.
-# ------------------------------------------------------------------------------
-func assert_almost_eq(got, expected, error_interval, text=''):
- var disp = "[" + _str(got) + "] expected to equal [" + _str(expected) + "] +/- [" + str(error_interval) + "]: " + text
- if(_do_datatypes_match__fail_if_not(got, expected, text) and _do_datatypes_match__fail_if_not(got, error_interval, text)):
- if not _is_almost_eq(got, expected, error_interval):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that the expected value does not almost equal the value got.
-# ------------------------------------------------------------------------------
-func assert_almost_ne(got, not_expected, error_interval, text=''):
- var disp = "[" + _str(got) + "] expected to not equal [" + _str(not_expected) + "] +/- [" + str(error_interval) + "]: " + text
- if(_do_datatypes_match__fail_if_not(got, not_expected, text) and _do_datatypes_match__fail_if_not(got, error_interval, text)):
- if _is_almost_eq(got, not_expected, error_interval):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Helper function which correctly compares two variables,
-# while properly handling vector2/3 types
-# ------------------------------------------------------------------------------
-func _is_almost_eq(got, expected, error_interval) -> bool:
- var result = false
- if typeof(got) == TYPE_VECTOR2:
- if got.x >= (expected.x - error_interval.x) and got.x <= (expected.x + error_interval.x):
- if got.y >= (expected.y - error_interval.y) and got.y <= (expected.y + error_interval.y):
- result = true
- elif typeof(got) == TYPE_VECTOR3:
- if got.x >= (expected.x - error_interval.x) and got.x <= (expected.x + error_interval.x):
- if got.y >= (expected.y - error_interval.y) and got.y <= (expected.y + error_interval.y):
- if got.z >= (expected.z - error_interval.z) and got.z <= (expected.z + error_interval.z):
- result = true
- elif(got >= (expected - error_interval) and got <= (expected + error_interval)):
- result = true
- return(result)
-
-# ------------------------------------------------------------------------------
-# Asserts got is greater than expected
-# ------------------------------------------------------------------------------
-func assert_gt(got, expected, text=""):
- var disp = "[" + _str(got) + "] expected to be > than [" + _str(expected) + "]: " + text
- if(_do_datatypes_match__fail_if_not(got, expected, text)):
- if(got > expected):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts got is less than expected
-# ------------------------------------------------------------------------------
-func assert_lt(got, expected, text=""):
- var disp = "[" + _str(got) + "] expected to be < than [" + _str(expected) + "]: " + text
- if(_do_datatypes_match__fail_if_not(got, expected, text)):
- if(got < expected):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# asserts that got is true
-# ------------------------------------------------------------------------------
-func assert_true(got, text=""):
- if(typeof(got) == TYPE_BOOL):
- if(got):
- _pass(text)
- else:
- _fail(text)
- else:
- var msg = str("Cannot convert ", _strutils.type2str(got), " to boolean")
- _fail(msg)
-
-# ------------------------------------------------------------------------------
-# Asserts that got is false
-# ------------------------------------------------------------------------------
-func assert_false(got, text=""):
- if(typeof(got) == TYPE_BOOL):
- if(got):
- _fail(text)
- else:
- _pass(text)
- else:
- var msg = str("Cannot convert ", _strutils.type2str(got), " to boolean")
- _fail(msg)
-
-# ------------------------------------------------------------------------------
-# Asserts value is between (inclusive) the two expected values.
-# ------------------------------------------------------------------------------
-func assert_between(got, expect_low, expect_high, text=""):
- var disp = "[" + _str(got) + "] expected to be between [" + _str(expect_low) + "] and [" + str(expect_high) + "]: " + text
-
- if(_do_datatypes_match__fail_if_not(got, expect_low, text) and _do_datatypes_match__fail_if_not(got, expect_high, text)):
- if(expect_low > expect_high):
- disp = "INVALID range. [" + str(expect_low) + "] is not less than [" + str(expect_high) + "]"
- _fail(disp)
- else:
- if(got < expect_low or got > expect_high):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts value is not between (exclusive) the two expected values.
-# ------------------------------------------------------------------------------
-func assert_not_between(got, expect_low, expect_high, text=""):
- var disp = "[" + _str(got) + "] expected not to be between [" + _str(expect_low) + "] and [" + str(expect_high) + "]: " + text
-
- if(_do_datatypes_match__fail_if_not(got, expect_low, text) and _do_datatypes_match__fail_if_not(got, expect_high, text)):
- if(expect_low > expect_high):
- disp = "INVALID range. [" + str(expect_low) + "] is not less than [" + str(expect_high) + "]"
- _fail(disp)
- else:
- if(got > expect_low and got < expect_high):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Uses the 'has' method of the object passed in to determine if it contains
-# the passed in element.
-# ------------------------------------------------------------------------------
-func assert_has(obj, element, text=""):
- var disp = str('Expected [', _str(obj), '] to contain value: [', _str(element), ']: ', text)
- if(obj.has(element)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-func assert_does_not_have(obj, element, text=""):
- var disp = str('Expected [', _str(obj), '] to NOT contain value: [', _str(element), ']: ', text)
- if(obj.has(element)):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that a file exists
-# ------------------------------------------------------------------------------
-func assert_file_exists(file_path):
- var disp = 'expected [' + file_path + '] to exist.'
- var f = File.new()
- if(f.file_exists(file_path)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that a file should not exist
-# ------------------------------------------------------------------------------
-func assert_file_does_not_exist(file_path):
- var disp = 'expected [' + file_path + '] to NOT exist'
- var f = File.new()
- if(!f.file_exists(file_path)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts the specified file is empty
-# ------------------------------------------------------------------------------
-func assert_file_empty(file_path):
- var disp = 'expected [' + file_path + '] to be empty'
- var f = File.new()
- if(f.file_exists(file_path) and gut.is_file_empty(file_path)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts the specified file is not empty
-# ------------------------------------------------------------------------------
-func assert_file_not_empty(file_path):
- var disp = 'expected [' + file_path + '] to contain data'
- if(!gut.is_file_empty(file_path)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts the object has the specified method
-# ------------------------------------------------------------------------------
-func assert_has_method(obj, method, text=''):
- var disp = _str(obj) + ' should have method: ' + method
- if(text != ''):
- disp = _str(obj) + ' ' + text
- assert_true(obj.has_method(method), disp)
-
-# Old deprecated method name
-func assert_get_set_methods(obj, property, default, set_to):
- _lgr.deprecated('assert_get_set_methods', 'assert_accessors')
- assert_accessors(obj, property, default, set_to)
-
-# ------------------------------------------------------------------------------
-# Verifies the object has get and set methods for the property passed in. The
-# property isn't tied to anything, just a name to be appended to the end of
-# get_ and set_. Asserts the get_ and set_ methods exist, if not, it stops there.
-# If they exist then it asserts get_ returns the expected default then calls
-# set_ and asserts get_ has the value it was set to.
-# ------------------------------------------------------------------------------
-func assert_accessors(obj, property, default, set_to):
- var fail_count = _summary.failed
- var get_func = 'get_' + property
- var set_func = 'set_' + property
-
- if(obj.has_method('is_' + property)):
- get_func = 'is_' + property
-
- assert_has_method(obj, get_func, 'should have getter starting with get_ or is_')
- assert_has_method(obj, set_func)
- # SHORT CIRCUIT
- if(_summary.failed > fail_count):
- return
- assert_eq(obj.call(get_func), default, 'It should have the expected default value.')
- obj.call(set_func, set_to)
- assert_eq(obj.call(get_func), set_to, 'The set value should have been returned.')
-
-
-# ---------------------------------------------------------------------------
-# Property search helper. Used to retrieve Dictionary of specified property
-# from passed object. Returns null if not found.
-# If provided, property_usage constrains the type of property returned by
-# passing either:
-# EDITOR_PROPERTY for properties defined as: export(int) var some_value
-# VARIABLE_PROPERTY for properties defined as: var another_value
-# ---------------------------------------------------------------------------
-func _find_object_property(obj, property_name, property_usage=null):
- var result = null
- var found = false
- var properties = obj.get_property_list()
-
- while !found and !properties.empty():
- var property = properties.pop_back()
- if property['name'] == property_name:
- if property_usage == null or property['usage'] == property_usage:
- result = property
- found = true
- return result
-
-# ------------------------------------------------------------------------------
-# Asserts a class exports a variable.
-# ------------------------------------------------------------------------------
-func assert_exports(obj, property_name, type):
- var disp = 'expected %s to have editor property [%s]' % [_str(obj), property_name]
- var property = _find_object_property(obj, property_name, EDITOR_PROPERTY)
- if property != null:
- disp += ' of type [%s]. Got type [%s].' % [_strutils.types[type], _strutils.types[property['type']]]
- if property['type'] == type:
- _pass(disp)
- else:
- _fail(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Signal assertion helper.
-#
-# Verifies that the object and signal are valid for making signal assertions.
-# This will fail with specific messages that indicate why they are not valid.
-# This returns true/false to indicate if the object and signal are valid.
-# ------------------------------------------------------------------------------
-func _can_make_signal_assertions(object, signal_name):
- return !(_fail_if_not_watching(object) or _fail_if_does_not_have_signal(object, signal_name))
-
-# ------------------------------------------------------------------------------
-# Check if an object is connected to a signal on another object. Returns True
-# if it is and false otherwise
-# ------------------------------------------------------------------------------
-func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name=""):
- if(method_name != ""):
- return signaler_obj.is_connected(signal_name, connect_to_obj, method_name)
- else:
- var connections = signaler_obj.get_signal_connection_list(signal_name)
- for conn in connections:
- if((conn.source == signaler_obj) and (conn.target == connect_to_obj)):
- return true
- return false
-# ------------------------------------------------------------------------------
-# Watch the signals for an object. This must be called before you can make
-# any assertions about the signals themselves.
-# ------------------------------------------------------------------------------
-func watch_signals(object):
- _signal_watcher.watch_signals(object)
-
-# ------------------------------------------------------------------------------
-# Asserts that an object is connected to a signal on another object
-#
-# This will fail with specific messages if the target object is not connected
-# to the specified signal on the source object.
-# ------------------------------------------------------------------------------
-func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name=""):
- pass
- var method_disp = ''
- if (method_name != ""):
- method_disp = str(' using method: [', method_name, '] ')
- var disp = str('Expected object ', _str(signaler_obj),\
- ' to be connected to signal: [', signal_name, '] on ',\
- _str(connect_to_obj), method_disp)
- if(_is_connected(signaler_obj, connect_to_obj, signal_name, method_name)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that an object is not connected to a signal on another object
-#
-# This will fail with specific messages if the target object is connected
-# to the specified signal on the source object.
-# ------------------------------------------------------------------------------
-func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name=""):
- var method_disp = ''
- if (method_name != ""):
- method_disp = str(' using method: [', method_name, '] ')
- var disp = str('Expected object ', _str(signaler_obj),\
- ' to not be connected to signal: [', signal_name, '] on ',\
- _str(connect_to_obj), method_disp)
- if(_is_connected(signaler_obj, connect_to_obj, signal_name, method_name)):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that a signal has been emitted at least once.
-#
-# This will fail with specific messages if the object is not being watched or
-# the object does not have the specified signal
-# ------------------------------------------------------------------------------
-func assert_signal_emitted(object, signal_name, text=""):
- var disp = str('Expected object ', _str(object), ' to have emitted signal [', signal_name, ']: ', text)
- if(_can_make_signal_assertions(object, signal_name)):
- if(_signal_watcher.did_emit(object, signal_name)):
- _pass(disp)
- else:
- _fail(_get_fail_msg_including_emitted_signals(disp, object))
-
-# ------------------------------------------------------------------------------
-# Asserts that a signal has not been emitted.
-#
-# This will fail with specific messages if the object is not being watched or
-# the object does not have the specified signal
-# ------------------------------------------------------------------------------
-func assert_signal_not_emitted(object, signal_name, text=""):
- var disp = str('Expected object ', _str(object), ' to NOT emit signal [', signal_name, ']: ', text)
- if(_can_make_signal_assertions(object, signal_name)):
- if(_signal_watcher.did_emit(object, signal_name)):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that a signal was fired with the specified parameters. The expected
-# parameters should be passed in as an array. An optional index can be passed
-# when a signal has fired more than once. The default is to retrieve the most
-# recent emission of the signal.
-#
-# This will fail with specific messages if the object is not being watched or
-# the object does not have the specified signal
-# ------------------------------------------------------------------------------
-func assert_signal_emitted_with_parameters(object, signal_name, parameters, index=-1):
- if(typeof(parameters) != TYPE_ARRAY):
- _lgr.error("The expected parameters must be wrapped in an array, you passed: " + _str(parameters))
- _fail("Bad Parameters")
- return
-
- var disp = str('Expected object ', _str(object), ' to emit signal [', signal_name, '] with parameters ', parameters, ', got ')
- if(_can_make_signal_assertions(object, signal_name)):
- if(_signal_watcher.did_emit(object, signal_name)):
- var parms_got = _signal_watcher.get_signal_parameters(object, signal_name, index)
- var diff_result = _compare.deep(parameters, parms_got)
- if(diff_result.are_equal()):
- _pass(str(disp, parms_got))
- else:
- _fail(str('Expected object ', _str(object), ' to emit signal [', signal_name, '] with parameters ', diff_result.summarize()))
- else:
- var text = str('Object ', object, ' did not emit signal [', signal_name, ']')
- _fail(_get_fail_msg_including_emitted_signals(text, object))
-
-# ------------------------------------------------------------------------------
-# Assert that a signal has been emitted a specific number of times.
-#
-# This will fail with specific messages if the object is not being watched or
-# the object does not have the specified signal
-# ------------------------------------------------------------------------------
-func assert_signal_emit_count(object, signal_name, times, text=""):
- if(_can_make_signal_assertions(object, signal_name)):
- var count = _signal_watcher.get_emit_count(object, signal_name)
- var disp = str('Expected the signal [', signal_name, '] emit count of [', count, '] to equal [', times, ']: ', text)
- if(count== times):
- _pass(disp)
- else:
- _fail(_get_fail_msg_including_emitted_signals(disp, object))
-
-# ------------------------------------------------------------------------------
-# Assert that the passed in object has the specified signal
-# ------------------------------------------------------------------------------
-func assert_has_signal(object, signal_name, text=""):
- var disp = str('Expected object ', _str(object), ' to have signal [', signal_name, ']: ', text)
- if(_signal_watcher.does_object_have_signal(object, signal_name)):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Returns the number of times a signal was emitted. -1 returned if the object
-# is not being watched.
-# ------------------------------------------------------------------------------
-func get_signal_emit_count(object, signal_name):
- return _signal_watcher.get_emit_count(object, signal_name)
-
-# ------------------------------------------------------------------------------
-# Get the parmaters of a fired signal. If the signal was not fired null is
-# returned. You can specify an optional index (use get_signal_emit_count to
-# determine the number of times it was emitted). The default index is the
-# latest time the signal was fired (size() -1 insetead of 0). The parameters
-# returned are in an array.
-# ------------------------------------------------------------------------------
-func get_signal_parameters(object, signal_name, index=-1):
- return _signal_watcher.get_signal_parameters(object, signal_name, index)
-
-# ------------------------------------------------------------------------------
-# Get the parameters for a method call to a doubled object. By default it will
-# return the most recent call. You can optionally specify an index.
-#
-# Returns:
-# * an array of parameter values if a call the method was found
-# * null when a call to the method was not found or the index specified was
-# invalid.
-# ------------------------------------------------------------------------------
-func get_call_parameters(object, method_name, index=-1):
- var to_return = null
- if(_utils.is_double(object)):
- to_return = gut.get_spy().get_call_parameters(object, method_name, index)
- else:
- _lgr.error('You must pass a doulbed object to get_call_parameters.')
-
- return to_return
-
-# ------------------------------------------------------------------------------
-# Returns the call count for a method with optional paramter matching.
-# ------------------------------------------------------------------------------
-func get_call_count(object, method_name, parameters=null):
- return gut.get_spy().call_count(object, method_name, parameters)
-
-# ------------------------------------------------------------------------------
-# Deprecated. Use assert_is.
-# ------------------------------------------------------------------------------
-func assert_extends(object, a_class, text=''):
- _lgr.deprecated('assert_extends', 'assert_is')
- assert_is(object, a_class, text)
-
-# ------------------------------------------------------------------------------
-# Assert that object is an instance of a_class
-# ------------------------------------------------------------------------------
-func assert_is(object, a_class, text=''):
- var disp = ''#var disp = str('Expected [', _str(object), '] to be type of [', a_class, ']: ', text)
- var NATIVE_CLASS = 'GDScriptNativeClass'
- var GDSCRIPT_CLASS = 'GDScript'
- var bad_param_2 = 'Parameter 2 must be a Class (like Node2D or Label). You passed '
-
- if(typeof(object) != TYPE_OBJECT):
- _fail(str('Parameter 1 must be an instance of an object. You passed: ', _str(object)))
- elif(typeof(a_class) != TYPE_OBJECT):
- _fail(str(bad_param_2, _str(a_class)))
- else:
- var a_str = _str(a_class)
- disp = str('Expected [', _str(object), '] to extend [', a_str, ']: ', text)
- if(a_class.get_class() != NATIVE_CLASS and a_class.get_class() != GDSCRIPT_CLASS):
- _fail(str(bad_param_2, a_str))
- else:
- if(object is a_class):
- _pass(disp)
- else:
- _fail(disp)
-
-func _get_typeof_string(the_type):
- var to_return = ""
- if(_strutils.types.has(the_type)):
- to_return += str(the_type, '(', _strutils.types[the_type], ')')
- else:
- to_return += str(the_type)
- return to_return
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-func assert_typeof(object, type, text=''):
- var disp = str('Expected [typeof(', object, ') = ')
- disp += _get_typeof_string(typeof(object))
- disp += '] to equal ['
- disp += _get_typeof_string(type) + ']'
- disp += '. ' + text
- if(typeof(object) == type):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-func assert_not_typeof(object, type, text=''):
- var disp = str('Expected [typeof(', object, ') = ')
- disp += _get_typeof_string(typeof(object))
- disp += '] to not equal ['
- disp += _get_typeof_string(type) + ']'
- disp += '. ' + text
- if(typeof(object) != type):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Assert that text contains given search string.
-# The match_case flag determines case sensitivity.
-# ------------------------------------------------------------------------------
-func assert_string_contains(text, search, match_case=true):
- var empty_search = 'Expected text and search strings to be non-empty. You passed \'%s\' and \'%s\'.'
- var disp = 'Expected \'%s\' to contain \'%s\', match_case=%s' % [text, search, match_case]
- if(text == '' or search == ''):
- _fail(empty_search % [text, search])
- elif(match_case):
- if(text.find(search) == -1):
- _fail(disp)
- else:
- _pass(disp)
- else:
- if(text.to_lower().find(search.to_lower()) == -1):
- _fail(disp)
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Assert that text starts with given search string.
-# match_case flag determines case sensitivity.
-# ------------------------------------------------------------------------------
-func assert_string_starts_with(text, search, match_case=true):
- var empty_search = 'Expected text and search strings to be non-empty. You passed \'%s\' and \'%s\'.'
- var disp = 'Expected \'%s\' to start with \'%s\', match_case=%s' % [text, search, match_case]
- if(text == '' or search == ''):
- _fail(empty_search % [text, search])
- elif(match_case):
- if(text.find(search) == 0):
- _pass(disp)
- else:
- _fail(disp)
- else:
- if(text.to_lower().find(search.to_lower()) == 0):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Assert that text ends with given search string.
-# match_case flag determines case sensitivity.
-# ------------------------------------------------------------------------------
-func assert_string_ends_with(text, search, match_case=true):
- var empty_search = 'Expected text and search strings to be non-empty. You passed \'%s\' and \'%s\'.'
- var disp = 'Expected \'%s\' to end with \'%s\', match_case=%s' % [text, search, match_case]
- var required_index = len(text) - len(search)
- if(text == '' or search == ''):
- _fail(empty_search % [text, search])
- elif(match_case):
- if(text.find(search) == required_index):
- _pass(disp)
- else:
- _fail(disp)
- else:
- if(text.to_lower().find(search.to_lower()) == required_index):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Assert that a method was called on an instance of a doubled class. If
-# parameters are supplied then the params passed in when called must match.
-# TODO make 3rd parameter "param_or_text" and add fourth parameter of "text" and
-# then work some magic so this can have a "text" parameter without being
-# annoying.
-# ------------------------------------------------------------------------------
-func assert_called(inst, method_name, parameters=null):
- var disp = str('Expected [',method_name,'] to have been called on ',_str(inst))
-
- if(_fail_if_parameters_not_array(parameters)):
- return
-
- if(!_utils.is_double(inst)):
- _fail('You must pass a doubled instance to assert_called. Check the wiki for info on using double.')
- else:
- if(gut.get_spy().was_called(inst, method_name, parameters)):
- _pass(disp)
- else:
- if(parameters != null):
- disp += str(' with parameters ', parameters)
- _fail(str(disp, "\n", _get_desc_of_calls_to_instance(inst)))
-
-# ------------------------------------------------------------------------------
-# Assert that a method was not called on an instance of a doubled class. If
-# parameters are specified then this will only fail if it finds a call that was
-# sent matching parameters.
-# ------------------------------------------------------------------------------
-func assert_not_called(inst, method_name, parameters=null):
- var disp = str('Expected [', method_name, '] to NOT have been called on ', _str(inst))
-
- if(_fail_if_parameters_not_array(parameters)):
- return
-
- if(!_utils.is_double(inst)):
- _fail('You must pass a doubled instance to assert_not_called. Check the wiki for info on using double.')
- else:
- if(gut.get_spy().was_called(inst, method_name, parameters)):
- if(parameters != null):
- disp += str(' with parameters ', parameters)
- _fail(str(disp, "\n", _get_desc_of_calls_to_instance(inst)))
- else:
- _pass(disp)
-
-# ------------------------------------------------------------------------------
-# Assert that a method on an instance of a doubled class was called a number
-# of times. If parameters are specified then only calls with matching
-# parameter values will be counted.
-# ------------------------------------------------------------------------------
-func assert_call_count(inst, method_name, expected_count, parameters=null):
- var count = gut.get_spy().call_count(inst, method_name, parameters)
-
- if(_fail_if_parameters_not_array(parameters)):
- return
-
- var param_text = ''
- if(parameters):
- param_text = ' with parameters ' + str(parameters)
- var disp = 'Expected [%s] on %s to be called [%s] times%s. It was called [%s] times.'
- disp = disp % [method_name, _str(inst), expected_count, param_text, count]
-
- if(!_utils.is_double(inst)):
- _fail('You must pass a doubled instance to assert_call_count. Check the wiki for info on using double.')
- else:
- if(count == expected_count):
- _pass(disp)
- else:
- _fail(str(disp, "\n", _get_desc_of_calls_to_instance(inst)))
-
-# ------------------------------------------------------------------------------
-# Asserts the passed in value is null
-# ------------------------------------------------------------------------------
-func assert_null(got, text=''):
- var disp = str('Expected [', _str(got), '] to be NULL: ', text)
- if(got == null):
- _pass(disp)
- else:
- _fail(disp)
-
-# ------------------------------------------------------------------------------
-# Asserts the passed in value is null
-# ------------------------------------------------------------------------------
-func assert_not_null(got, text=''):
- var disp = str('Expected [', _str(got), '] to be anything but NULL: ', text)
- if(got == null):
- _fail(disp)
- else:
- _pass(disp)
-
-# -----------------------------------------------------------------------------
-# Asserts object has been freed from memory
-# We pass in a title (since if it is freed, we lost all identity data)
-# -----------------------------------------------------------------------------
-func assert_freed(obj, title='something'):
- var disp = title
- if(is_instance_valid(obj)):
- disp = _strutils.type2str(obj) + title
- assert_true(not is_instance_valid(obj), "Expected [%s] to be freed" % disp)
-
-# ------------------------------------------------------------------------------
-# Asserts Object has not been freed from memory
-# -----------------------------------------------------------------------------
-func assert_not_freed(obj, title):
- var disp = title
- if(is_instance_valid(obj)):
- disp = _strutils.type2str(obj) + title
- assert_true(is_instance_valid(obj), "Expected [%s] to not be freed" % disp)
-
-# ------------------------------------------------------------------------------
-# Asserts that the current test has not introduced any new orphans. This only
-# applies to the test code that preceedes a call to this method so it should be
-# the last thing your test does.
-# ------------------------------------------------------------------------------
-func assert_no_new_orphans(text=''):
- var count = gut.get_orphan_counter().get_counter('test')
- var msg = ''
- if(text != ''):
- msg = ': ' + text
- # Note that get_counter will return -1 if the counter does not exist. This
- # can happen with a misplaced assert_no_new_orphans. Checking for > 0
- # ensures this will not cause some weird failure.
- if(count > 0):
- _fail(str('Expected no orphans, but found ', count, msg))
- else:
- _pass('No new orphans found.' + msg)
-
-# ------------------------------------------------------------------------------
-# Returns a dictionary that contains
-# - an is_valid flag whether validation was successful or not and
-# - a message that gives some information about the validation errors.
-# ------------------------------------------------------------------------------
-func _validate_assert_setget_called_input(type, name_property
- , name_setter, name_getter):
- var obj = null
- var result = {"is_valid": true, "msg": ""}
-
- if null == type or typeof(type) != TYPE_OBJECT or not type.is_class("Resource"):
- result.is_valid = false
- result.msg = str("The type parameter should be a ressource, ", _str(type), ' was passed.')
- return result
-
- if null == double(type):
- result.is_valid = false
- result.msg = str("Attempt to double the type parameter failed. The type parameter should be a ressource that can be doubled.")
- return result
-
- obj = _create_obj_from_type(type)
- var property = _find_object_property(obj, str(name_property))
-
- if null == property:
- result.is_valid = false
- result.msg += str("The property %s does not exist." % _str(name_property))
- if name_setter == "" and name_getter == "":
- result.is_valid = false
- result.msg += str("Either setter or getter method must be specified.")
- if name_setter != "" and not obj.has_method(str(name_setter)):
- result.is_valid = false
- result.msg += str("Setter method %s does not exist. " % _str(name_setter))
- if name_getter != "" and not obj.has_method(str(name_getter)):
- result.is_valid = false
- result.msg += str("Getter method %s does not exist. " %_str(name_getter))
-
- obj.free()
- return result
-
-# ------------------------------------------------------------------------------
-# Validates the singleton_name is a string and exists. Errors when conditions
-# are not met. Returns true/false if singleton_name is valid or not.
-# ------------------------------------------------------------------------------
-func _validate_singleton_name(singleton_name):
- var is_valid = true
- if(typeof(singleton_name) != TYPE_STRING):
- _lgr.error("double_singleton requires a Godot singleton name, you passed " + _str(singleton_name))
- is_valid = false
- # Sometimes they have underscores in front of them, sometimes they do not.
- # The doubler is smart enought of ind the right thing, so this has to be
- # that smart as well.
- elif(!ClassDB.class_exists(singleton_name) and !ClassDB.class_exists('_' + singleton_name)):
- var txt = str("The singleton [", singleton_name, "] could not be found. ",
- "Check the GlobalScope page for a list of singletons.")
- _lgr.error(txt)
- is_valid = false
- return is_valid
-
-
-# ------------------------------------------------------------------------------
-# Asserts the given setter and getter methods are called when the given property
-# is accessed.
-# ------------------------------------------------------------------------------
-func _assert_setget_called(type, name_property, setter = "", getter = ""):
- var name_setter = _utils.nvl(setter, "")
- var name_getter = _utils.nvl(getter, "")
-
- var validation = _validate_assert_setget_called_input(type, name_property, str(name_setter), str(name_getter))
- if not validation.is_valid:
- _fail(validation.msg)
- return
-
- var message = ""
- var amount_calls_setter = 0
- var amount_calls_getter = 0
- var expected_calls_setter = 0
- var expected_calls_getter = 0
- var obj = _create_obj_from_type(double(type))
-
- if name_setter != '':
- expected_calls_setter = 1
- stub(obj, name_setter).to_do_nothing()
- obj.set(name_property, null)
- amount_calls_setter = gut.get_spy().call_count(obj, str(name_setter))
-
- if name_getter != '':
- expected_calls_getter = 1
- stub(obj, name_getter).to_do_nothing()
- var __new_property = obj.get(name_property)
- amount_calls_getter = gut.get_spy().call_count(obj, str(name_getter))
-
- obj.free()
-
- # assert
-
- if amount_calls_setter == expected_calls_setter and amount_calls_getter == expected_calls_getter:
- _pass(str("setget for %s is correctly configured." % _str(name_property)))
- else:
- if amount_calls_setter < expected_calls_setter:
- message += " The setter was not called."
- elif amount_calls_setter > expected_calls_setter:
- message += " The setter was called but should not have been."
- if amount_calls_getter < expected_calls_getter:
- message += " The getter was not called."
- elif amount_calls_getter > expected_calls_getter:
- message += " The getter was called but should not have been."
- _fail(str(message))
-
-# ------------------------------------------------------------------------------
-# Wrapper: invokes assert_setget_called but provides a slightly more convenient
-# signature
-# ------------------------------------------------------------------------------
-func assert_setget(
- instance, name_property,
- const_or_setter = DEFAULT_SETTER_GETTER, getter="__not_set__"):
-
- var getter_name = null
- if(getter != "__not_set__"):
- getter_name = getter
-
- var setter_name = null
- if(typeof(const_or_setter) == TYPE_INT):
- if(const_or_setter in [SETTER_ONLY, DEFAULT_SETTER_GETTER]):
- setter_name = str("set_", name_property)
-
- if(const_or_setter in [GETTER_ONLY, DEFAULT_SETTER_GETTER]):
- getter_name = str("get_", name_property)
- else:
- setter_name = const_or_setter
-
- var resource = null
- if instance.is_class("Resource"):
- resource = instance
- else:
- resource = instance.get_script()
-
- _assert_setget_called(resource, str(name_property), setter_name, getter_name)
-
-
-# ------------------------------------------------------------------------------
-# Wrapper: asserts if the property exists, the accessor methods exist and the
-# setget keyword is set for accessor methods
-# ------------------------------------------------------------------------------
-func assert_property(instance, name_property, default_value, new_value) -> void:
- var free_me = []
- var resource = null
- var obj = null
- if instance.is_class("Resource"):
- resource = instance
- obj = _create_obj_from_type(resource)
- free_me.append(obj)
- else:
- resource = instance.get_script()
- obj = instance
-
- var name_setter = "set_" + str(name_property)
- var name_getter = "get_" + str(name_property)
-
- var pre_fail_count = get_fail_count()
- assert_accessors(obj, str(name_property), default_value, new_value)
- _assert_setget_called(resource, str(name_property), name_setter, name_getter)
-
- for entry in free_me:
- entry.free()
-
- # assert
- if get_fail_count() == pre_fail_count:
- _pass(str("The property is set up as expected."))
- else:
- _fail(str("The property is not set up as expected. Examine subtests to see what failed."))
-
-
-# ------------------------------------------------------------------------------
-# Mark the current test as pending.
-# ------------------------------------------------------------------------------
-func pending(text=""):
- _summary.pending += 1
- if(gut):
- _lgr.pending(text)
- gut._pending(text)
-
-# ------------------------------------------------------------------------------
-# Returns the number of times a signal was emitted. -1 returned if the object
-# is not being watched.
-# ------------------------------------------------------------------------------
-
-# ------------------------------------------------------------------------------
-# Yield for the time sent in. The optional message will be printed when
-# Gut detects the yield. When the time expires the YIELD signal will be
-# emitted.
-# ------------------------------------------------------------------------------
-func yield_for(time, msg=''):
- return gut.set_yield_time(time, msg)
-
-# ------------------------------------------------------------------------------
-# Yield to a signal or a maximum amount of time, whichever comes first. When
-# the conditions are met the YIELD signal will be emitted.
-# ------------------------------------------------------------------------------
-func yield_to(obj, signal_name, max_wait, msg=''):
- watch_signals(obj)
- gut.set_yield_signal_or_time(obj, signal_name, max_wait, msg)
-
- return gut
-
-# ------------------------------------------------------------------------------
-# Yield for a number of frames. The optional message will be printed. when
-# Gut detects a yield. When the number of frames have elapsed (counted in gut's
-# _process function) the YIELD signal will be emitted.
-# ------------------------------------------------------------------------------
-func yield_frames(frames, msg=''):
- if(frames <= 0):
- var text = str('yeild_frames: frames must be > 0, you passed ', frames, '. 0 frames waited.')
- _lgr.error(text)
- frames = 0
-
- gut.set_yield_frames(frames, msg)
- return gut
-
-# ------------------------------------------------------------------------------
-# Ends a test that had a yield in it. You only need to use this if you do
-# not make assertions after a yield.
-# ------------------------------------------------------------------------------
-func end_test():
- _lgr.deprecated('end_test is no longer necessary, you can remove it.')
- #gut.end_yielded_test()
-
-func get_summary():
- return _summary
-
-func get_fail_count():
- return _summary.failed
-
-func get_pass_count():
- return _summary.passed
-
-func get_pending_count():
- return _summary.pending
-
-func get_assert_count():
- return _summary.asserts
-
-func clear_signal_watcher():
- _signal_watcher.clear()
-
-func get_double_strategy():
- return gut.get_doubler().get_strategy()
-
-func set_double_strategy(double_strategy):
- gut.get_doubler().set_strategy(double_strategy)
-
-func pause_before_teardown():
- gut.pause_before_teardown()
-
-# ------------------------------------------------------------------------------
-# Convert the _summary dictionary into text
-# ------------------------------------------------------------------------------
-func get_summary_text():
- var to_return = get_script().get_path() + "\n"
- to_return += str(' ', _summary.passed, ' of ', _summary.asserts, ' passed.')
- if(_summary.pending > 0):
- to_return += str("\n ", _summary.pending, ' pending')
- if(_summary.failed > 0):
- to_return += str("\n ", _summary.failed, ' failed.')
- return to_return
-
-# ------------------------------------------------------------------------------
-# Double a script, inner class, or scene using a path or a loaded script/scene.
-#
-#
-# ------------------------------------------------------------------------------
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-func _smart_double(double_info):
- var override_strat = _utils.nvl(double_info.strategy, gut.get_doubler().get_strategy())
- var to_return = null
-
- if(double_info.is_scene()):
- if(double_info.make_partial):
- to_return = gut.get_doubler().partial_double_scene(double_info.path, override_strat)
- else:
- to_return = gut.get_doubler().double_scene(double_info.path, override_strat)
-
- elif(double_info.is_native()):
- if(double_info.make_partial):
- to_return = gut.get_doubler().partial_double_gdnative(double_info.path)
- else:
- to_return = gut.get_doubler().double_gdnative(double_info.path)
-
- elif(double_info.is_script()):
- if(double_info.subpath == null):
- if(double_info.make_partial):
- to_return = gut.get_doubler().partial_double(double_info.path, override_strat)
- else:
- to_return = gut.get_doubler().double(double_info.path, override_strat)
- else:
- if(double_info.make_partial):
- to_return = gut.get_doubler().partial_double_inner(double_info.path, double_info.subpath, override_strat)
- else:
- to_return = gut.get_doubler().double_inner(double_info.path, double_info.subpath, override_strat)
- return to_return
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-func double(thing, p2=null, p3=null):
- var double_info = DoubleInfo.new(thing, p2, p3)
- if(!double_info.is_valid):
- _lgr.error('double requires a class or path, you passed an instance: ' + _str(thing))
- return null
-
- double_info.make_partial = false
-
- return _smart_double(double_info)
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-func partial_double(thing, p2=null, p3=null):
- var double_info = DoubleInfo.new(thing, p2, p3)
- if(!double_info.is_valid):
- _lgr.error('partial_double requires a class or path, you passed an instance: ' + _str(thing))
- return null
-
- double_info.make_partial = true
-
- return _smart_double(double_info)
-
-# ------------------------------------------------------------------------------
-# Doubles a Godot singleton
-# ------------------------------------------------------------------------------
-func double_singleton(singleton_name):
- return null
- # var to_return = null
- # if(_validate_singleton_name(singleton_name)):
- # to_return = gut.get_doubler().double_singleton(singleton_name)
- # return to_return
-
-# ------------------------------------------------------------------------------
-# Partial Doubles a Godot singleton
-# ------------------------------------------------------------------------------
-func partial_double_singleton(singleton_name):
- return null
- # var to_return = null
- # if(_validate_singleton_name(singleton_name)):
- # to_return = gut.get_doubler().partial_double_singleton(singleton_name)
- # return to_return
-
-# ------------------------------------------------------------------------------
-# Specifically double a scene
-# ------------------------------------------------------------------------------
-func double_scene(path, strategy=null):
- var override_strat = _utils.nvl(strategy, gut.get_doubler().get_strategy())
- return gut.get_doubler().double_scene(path, override_strat)
-
-# ------------------------------------------------------------------------------
-# Specifically double a script
-# ------------------------------------------------------------------------------
-func double_script(path, strategy=null):
- var override_strat = _utils.nvl(strategy, gut.get_doubler().get_strategy())
- return gut.get_doubler().double(path, override_strat)
-
-# ------------------------------------------------------------------------------
-# Specifically double an Inner class in a a script
-# ------------------------------------------------------------------------------
-func double_inner(path, subpath, strategy=null):
- var override_strat = _utils.nvl(strategy, gut.get_doubler().get_strategy())
- return gut.get_doubler().double_inner(path, subpath, override_strat)
-
-
-# ------------------------------------------------------------------------------
-# Add a method that the doubler will ignore. You can pass this the path to a
-# script or scene or a loaded script or scene. When running tests, these
-# ignores are cleared after every test.
-# ------------------------------------------------------------------------------
-func ignore_method_when_doubling(thing, method_name):
- var double_info = DoubleInfo.new(thing)
- var path = double_info.path
-
- if(double_info.is_scene()):
- var inst = thing.instance()
- if(inst.get_script()):
- path = inst.get_script().get_path()
-
- gut.get_doubler().add_ignored_method(path, method_name)
-
-# ------------------------------------------------------------------------------
-# Stub something.
-#
-# Parameters
-# 1: the thing to stub, a file path or a instance or a class
-# 2: either an inner class subpath or the method name
-# 3: the method name if an inner class subpath was specified
-# NOTE: right now we cannot stub inner classes at the path level so this should
-# only be called with two parameters. I did the work though so I'm going
-# to leave it but not update the wiki.
-# ------------------------------------------------------------------------------
-func stub(thing, p2, p3=null):
- if(_utils.is_instance(thing) and !_utils.is_double(thing)):
- _lgr.error(str('You cannot use stub on ', _str(thing), ' because it is not a double.'))
- return _utils.StubParams.new()
-
- var method_name = p2
- var subpath = null
- if(p3 != null):
- subpath = p2
- method_name = p3
-
- var sp = _utils.StubParams.new(thing, method_name, subpath)
- gut.get_stubber().add_stub(sp)
- return sp
-
-# ------------------------------------------------------------------------------
-# convenience wrapper.
-# ------------------------------------------------------------------------------
-func simulate(obj, times, delta):
- gut.simulate(obj, times, delta)
-
-# ------------------------------------------------------------------------------
-# Replace the node at base_node.get_node(path) with with_this. All references
-# to the node via $ and get_node(...) will now return with_this. with_this will
-# get all the groups that the node that was replaced had.
-#
-# The node that was replaced is queued to be freed.
-#
-# TODO see replace_by method, this could simplify the logic here.
-# ------------------------------------------------------------------------------
-func replace_node(base_node, path_or_node, with_this):
- var path = path_or_node
-
- if(typeof(path_or_node) != TYPE_STRING):
- # This will cause an engine error if it fails. It always returns a
- # NodePath, even if it fails. Checking the name count is the only way
- # I found to check if it found something or not (after it worked I
- # didn't look any farther).
- path = base_node.get_path_to(path_or_node)
- if(path.get_name_count() == 0):
- _lgr.error('You passed an object that base_node does not have. Cannot replace node.')
- return
-
- if(!base_node.has_node(path)):
- _lgr.error(str('Could not find node at path [', path, ']'))
- return
-
- var to_replace = base_node.get_node(path)
- var parent = to_replace.get_parent()
- var replace_name = to_replace.get_name()
-
- parent.remove_child(to_replace)
- parent.add_child(with_this)
- with_this.set_name(replace_name)
- with_this.set_owner(parent)
-
- var groups = to_replace.get_groups()
- for i in range(groups.size()):
- with_this.add_to_group(groups[i])
-
- to_replace.queue_free()
-
-
-# ------------------------------------------------------------------------------
-# This method does a somewhat complicated dance with Gut. It assumes that Gut
-# will clear its parameter handler after it finishes calling a parameterized test
-# enough times.
-# ------------------------------------------------------------------------------
-func use_parameters(params):
- var ph = gut.get_parameter_handler()
- if(ph == null):
- ph = _utils.ParameterHandler.new(params)
- gut.set_parameter_handler(ph)
-
- var output = str('(call #', ph.get_call_count() + 1, ') with parameters: ', ph.get_current_parameters())
- _lgr.log(output)
- _lgr.inc_indent()
- return ph.next_parameters()
-
-# ------------------------------------------------------------------------------
-# Marks whatever is passed in to be freed after the test finishes. It also
-# returns what is passed in so you can save a line of code.
-# var thing = autofree(Thing.new())
-# ------------------------------------------------------------------------------
-func autofree(thing):
- gut.get_autofree().add_free(thing)
- return thing
-
-# ------------------------------------------------------------------------------
-# Works the same as autofree except queue_free will be called on the object
-# instead. This also imparts a brief pause after the test finishes so that
-# the queued object has time to free.
-# ------------------------------------------------------------------------------
-func autoqfree(thing):
- gut.get_autofree().add_queue_free(thing)
- return thing
-
-# ------------------------------------------------------------------------------
-# The same as autofree but it also adds the object as a child of the test.
-# ------------------------------------------------------------------------------
-func add_child_autofree(node, legible_unique_name = false):
- gut.get_autofree().add_free(node)
- # Explicitly calling super here b/c add_child MIGHT change and I don't want
- # a bug sneaking its way in here.
- .add_child(node, legible_unique_name)
- return node
-
-# ------------------------------------------------------------------------------
-# The same as autoqfree but it also adds the object as a child of the test.
-# ------------------------------------------------------------------------------
-func add_child_autoqfree(node, legible_unique_name=false):
- gut.get_autofree().add_queue_free(node)
- # Explicitly calling super here b/c add_child MIGHT change and I don't want
- # a bug sneaking its way in here.
- .add_child(node, legible_unique_name)
- return node
-
-# ------------------------------------------------------------------------------
-# Returns true if the test is passing as of the time of this call. False if not.
-# ------------------------------------------------------------------------------
-func is_passing():
- if(gut.get_current_test_object() != null and
- !['before_all', 'after_all'].has(gut.get_current_test_object().name)):
- return gut.get_current_test_object().passed and \
- gut.get_current_test_object().assert_count > 0
- else:
- _lgr.error('No current test object found. is_passing must be called inside a test.')
- return null
-
-# ------------------------------------------------------------------------------
-# Returns true if the test is failing as of the time of this call. False if not.
-# ------------------------------------------------------------------------------
-func is_failing():
- if(gut.get_current_test_object() != null and
- !['before_all', 'after_all'].has(gut.get_current_test_object().name)):
- return !gut.get_current_test_object().passed
- else:
- _lgr.error('No current test object found. is_failing must be called inside a test.')
- return null
-
-# ------------------------------------------------------------------------------
-# Marks the test as passing. Does not override any failing asserts or calls to
-# fail_test. Same as a passing assert.
-# ------------------------------------------------------------------------------
-func pass_test(text):
- _pass(text)
-
-# ------------------------------------------------------------------------------
-# Marks the test as failing. Same as a failing assert.
-# ------------------------------------------------------------------------------
-func fail_test(text):
- _fail(text)
-
-# ------------------------------------------------------------------------------
-# Peforms a deep compare on both values, a CompareResult instnace is returned.
-# The optional max_differences paramter sets the max_differences to be displayed.
-# ------------------------------------------------------------------------------
-func compare_deep(v1, v2, max_differences=null):
- var result = _compare.deep(v1, v2)
- if(max_differences != null):
- result.max_differences = max_differences
- return result
-
-# ------------------------------------------------------------------------------
-# Peforms a shallow compare on both values, a CompareResult instnace is returned.
-# The optional max_differences paramter sets the max_differences to be displayed.
-# ------------------------------------------------------------------------------
-func compare_shallow(v1, v2, max_differences=null):
- var result = _compare.shallow(v1, v2)
- if(max_differences != null):
- result.max_differences = max_differences
- return result
-
-# ------------------------------------------------------------------------------
-# Performs a deep compare and asserts the values are equal
-# ------------------------------------------------------------------------------
-func assert_eq_deep(v1, v2):
- var result = compare_deep(v1, v2)
- if(result.are_equal):
- _pass(result.get_short_summary())
- else:
- _fail(result.summary)
-
-# ------------------------------------------------------------------------------
-# Performs a deep compare and asserts the values are not equal
-# ------------------------------------------------------------------------------
-func assert_ne_deep(v1, v2):
- var result = compare_deep(v1, v2)
- if(!result.are_equal):
- _pass(result.get_short_summary())
- else:
- _fail(result.get_short_summary())
-
-# ------------------------------------------------------------------------------
-# Performs a shallow compare and asserts the values are equal
-# ------------------------------------------------------------------------------
-func assert_eq_shallow(v1, v2):
- var result = compare_shallow(v1, v2)
- if(result.are_equal):
- _pass(result.get_short_summary())
- else:
- _fail(result.summary)
-
-# ------------------------------------------------------------------------------
-# Performs a shallow compare and asserts the values are not equal
-# ------------------------------------------------------------------------------
-func assert_ne_shallow(v1, v2):
- var result = compare_shallow(v1, v2)
- if(!result.are_equal):
- _pass(result.get_short_summary())
- else:
- _fail(result.get_short_summary())
-
-
-# ------------------------------------------------------------------------------
-# Checks the passed in version string (x.x.x) against the engine version to see
-# if the engine version is less than the expected version. If it is then the
-# test is mareked as passed (for a lack of anything better to do). The result
-# of the check is returned.
-#
-# Example:
-# if(skip_if_godot_version_lt('3.5.0')):
-# return
-# ------------------------------------------------------------------------------
-func skip_if_godot_version_lt(expected):
- var should_skip = !_utils.is_godot_version_gte(expected)
- if(should_skip):
- _pass(str('Skipping ', _utils.godot_version(), ' is less than ', expected))
- return should_skip
-
-
-# ------------------------------------------------------------------------------
-# Checks if the passed in version matches the engine version. The passed in
-# version can contain just the major, major.minor or major.minor.path. If
-# the version is not the same then the test is marked as passed. The result of
-# the check is returned.
-#
-# Example:
-# if(skip_if_godot_version_ne('3.4')):
-# return
-# ------------------------------------------------------------------------------
-func skip_if_godot_version_ne(expected):
- var should_skip = !_utils.is_godot_version(expected)
- if(should_skip):
- _pass(str('Skipping ', _utils.godot_version(), ' is not ', expected))
- return should_skip \ No newline at end of file