chore: add GUT test framework
This commit is contained in:
87
addons/gut/test/integration/test_abstract_class_doubling.gd
Normal file
87
addons/gut/test/integration/test_abstract_class_doubling.gd
Normal file
@@ -0,0 +1,87 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
@abstract
|
||||
class AbstractClass:
|
||||
|
||||
@abstract func abstract_method()
|
||||
|
||||
|
||||
@abstract
|
||||
class ExtendsAbstractClass:
|
||||
extends AbstractClass
|
||||
|
||||
func abstract_method():
|
||||
return "implemented"
|
||||
|
||||
@abstract
|
||||
func another_abstract_method()
|
||||
|
||||
|
||||
func before_all():
|
||||
register_inner_classes(get_script())
|
||||
|
||||
|
||||
# Our implementaiton assumes that the order of get_script_method_list() is
|
||||
# from child to parents. The following test will show when future godot
|
||||
# versions change the behavior.
|
||||
func test_method_order_assumption():
|
||||
var method_list = (ExtendsAbstractClass as Variant).get_script_method_list()
|
||||
|
||||
assert_eq(method_list[0].name, "abstract_method")
|
||||
assert_eq(method_list[0].flags, 1)
|
||||
|
||||
assert_eq(method_list[1].name, "another_abstract_method")
|
||||
|
||||
assert_eq(method_list[2].name, "abstract_method")
|
||||
assert_eq(method_list[2].flags, 129)
|
||||
|
||||
|
||||
func test_can_double_abstract():
|
||||
var dbl = double(AbstractClass)
|
||||
assert_not_null(dbl)
|
||||
|
||||
|
||||
func test_can_stub_to_return_for_abstract_method_at_sctipt_level():
|
||||
stub(AbstractClass, 'abstract_method').to_return('a')
|
||||
var inst = double(AbstractClass).new()
|
||||
assert_eq(inst.abstract_method(), 'a')
|
||||
|
||||
|
||||
func test_can_stub_to_return_for_abstract_method_at_double_level():
|
||||
var Dbl = double(AbstractClass)
|
||||
stub(Dbl, 'abstract_method').to_return(9)
|
||||
var inst = Dbl.new()
|
||||
assert_eq(inst.abstract_method(), 9)
|
||||
|
||||
|
||||
func test_can_stub_to_return_for_abstract_method_at_instance_level():
|
||||
var inst = double(AbstractClass).new()
|
||||
stub(inst.abstract_method).to_return(7)
|
||||
assert_eq(inst.abstract_method(), 7)
|
||||
|
||||
|
||||
func test_error_when_stubbing_to_call_super_at_script_level():
|
||||
stub(AbstractClass, 'abstract_method').to_call_super()
|
||||
assert_tracked_gut_error(gut, 0)
|
||||
|
||||
|
||||
func test_error_when_stubbing_to_call_super_at_instance_level():
|
||||
# Arrange
|
||||
var doubled = autofree(double(AbstractClass).new())
|
||||
stub(doubled.abstract_method).to_call_super()
|
||||
|
||||
# Act
|
||||
var result = doubled.abstract_method()
|
||||
|
||||
# Assert
|
||||
assert_null(result)
|
||||
var current_test_errors = gut.error_tracker.get_current_test_errors()
|
||||
assert_eq(current_test_errors[0].code, "Cannot call super() because method abstract_method is abstract.")
|
||||
assert_tracked_gut_error()
|
||||
|
||||
|
||||
func test_can_stub_implemented_abstract_to_call_super():
|
||||
var inst = double(ExtendsAbstractClass).new()
|
||||
stub(inst.abstract_method).to_call_super()
|
||||
assert_eq(inst.abstract_method(), 'implemented')
|
||||
@@ -0,0 +1 @@
|
||||
uid://ckw6xee3xj3e3
|
||||
74
addons/gut/test/integration/test_doubler_and_spy.gd
Normal file
74
addons/gut/test/integration/test_doubler_and_spy.gd
Normal file
@@ -0,0 +1,74 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
class TestBoth:
|
||||
extends GutInternalTester
|
||||
|
||||
const INIT_PARAMETERS = 'res://test/resources/stub_test_objects/init_parameters.gd'
|
||||
var InitParameters = load(INIT_PARAMETERS)
|
||||
|
||||
var _spy = null
|
||||
var _doubler = null
|
||||
|
||||
func before_each():
|
||||
_spy = GutUtils.Spy.new()
|
||||
_doubler = GutUtils.Doubler.new()
|
||||
_doubler.set_spy(_spy)
|
||||
# var stubber = GutUtils.Stubber.new()
|
||||
# _doubler.set_stubber(stubber)
|
||||
|
||||
func after_each():
|
||||
_spy.clear()
|
||||
|
||||
func test_spy_is_set_in_metadata():
|
||||
var inst = autofree(_doubler.double(DoubleMe).new())
|
||||
assert_eq(inst.__gutdbl.spy_ref.get_ref(), _spy)
|
||||
|
||||
func test_when_doubled_method_called_spy_sees_it():
|
||||
var inst = autofree(_doubler.double(DoubleMe).new())
|
||||
inst.set_value(5)
|
||||
assert_true(_spy.was_called(inst, 'set_value'))
|
||||
|
||||
func test_when_doubled_method_called_it_sends_parameters():
|
||||
var inst = autofree(_doubler.double(DoubleMe).new())
|
||||
inst.set_value(5)
|
||||
assert_true(_spy.was_called(inst, 'set_value', [5]))
|
||||
|
||||
func test_it_works_with_two_parameters_too():
|
||||
var inst = autofree(_doubler.double(DoubleMe).new())
|
||||
inst.has_two_params_one_default('a', 'b')
|
||||
assert_false(_spy.was_called(inst, 'has_two_params_one_default', ['c', 'd']), 'should not match')
|
||||
assert_true(_spy.was_called(inst, 'has_two_params_one_default', ['a', 'b']), 'should match')
|
||||
|
||||
func test_can_spy_on_built_ins_when_doing_a_full_double():
|
||||
_doubler.set_strategy(DOUBLE_STRATEGY.INCLUDE_NATIVE)
|
||||
var inst = autofree(_doubler.double(DoubleMe).new())
|
||||
# add_user_signal is a function on Object that isn't in our subclass.
|
||||
inst.add_user_signal('new_signal', [])
|
||||
inst.add_user_signal('signal_with_params', ['a', 'b'])
|
||||
assert_true(_spy.was_called(inst, 'add_user_signal'), 'added first signal')
|
||||
assert_true(_spy.was_called(inst, 'add_user_signal', ['signal_with_params', ['a', 'b']]), 'second signal added')
|
||||
|
||||
func test_can_spy_on_native_doubles():
|
||||
var inst = autofree(_doubler.partial_double_gdnative(Node2D).new())
|
||||
inst.set_position(Vector2(20, 20))
|
||||
assert_true(_spy.was_called(inst, 'set_position'))
|
||||
assert_true(_spy.was_called(inst, 'set_position', [Vector2(20, 20)]))
|
||||
|
||||
func test_can_spy_on_singleton_doubles():
|
||||
var inst = _doubler.double_singleton(Input).new()
|
||||
inst.is_action_just_pressed("foobar")
|
||||
assert_true(_spy.was_called(inst, "is_action_just_pressed"))
|
||||
|
||||
func test_can_spy_on_singleton_parameters():
|
||||
var inst = _doubler.double_singleton(OS).new()
|
||||
inst.is_process_running(5)
|
||||
assert_true(_spy.was_called(inst, 'is_process_running', [5]))
|
||||
|
||||
func test_can_spy_on_init():
|
||||
var inst = _doubler.double(InitParameters).new('test_value')
|
||||
assert_true(_spy.was_called(inst, '_init'))
|
||||
|
||||
func test_can_spy_on_init_parameters():
|
||||
var inst = _doubler.double(InitParameters).new('test_value')
|
||||
assert_true(_spy.was_called(inst, '_init', ['test_value']))
|
||||
1
addons/gut/test/integration/test_doubler_and_spy.gd.uid
Normal file
1
addons/gut/test/integration/test_doubler_and_spy.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cule2ck72y45b
|
||||
380
addons/gut/test/integration/test_doubler_and_stubber.gd
Normal file
380
addons/gut/test/integration/test_doubler_and_stubber.gd
Normal file
@@ -0,0 +1,380 @@
|
||||
extends "res://addons/gut/test.gd"
|
||||
|
||||
class BaseTest:
|
||||
extends GutTest
|
||||
var Stubber = load('res://addons/gut/stubber.gd')
|
||||
var Doubler = load('res://addons/gut/doubler.gd')
|
||||
var StubParams = load('res://addons/gut/stub_params.gd')
|
||||
var Wm = GutUtils.WarningsManager
|
||||
|
||||
|
||||
const DOUBLE_ME_PATH = 'res://test/resources/doubler_test_objects/double_me.gd'
|
||||
const DOUBLE_ME_SCENE_PATH = 'res://test/resources/doubler_test_objects/double_me_scene.tscn'
|
||||
const DOUBLE_EXTENDS_NODE2D = 'res://test/resources/doubler_test_objects/double_extends_node2d.gd'
|
||||
const DOUBLE_EXTENDS_WINDOW_DIALOG = 'res://test/resources/doubler_test_objects/double_extends_window_dialog.gd'
|
||||
const TO_STUB_PATH = 'res://test/resources/stub_test_objects/to_stub.gd'
|
||||
const DOUBLE_WITH_STATIC = 'res://test/resources/doubler_test_objects/has_static_method.gd'
|
||||
const INIT_PARAMETERS = 'res://test/resources/stub_test_objects/init_parameters.gd'
|
||||
const INNER_CLASSES_PATH = 'res://test/resources/doubler_test_objects/inner_classes.gd'
|
||||
const DOUBLE_DEFAULT_PARAMETERS = 'res://test/resources/doubler_test_objects/double_default_parameters.gd'
|
||||
|
||||
var DoubleMe = Wm.load_script_ignoring_all_warnings(DOUBLE_ME_PATH)
|
||||
var DoubleExtendsNode2D = Wm.load_script_ignoring_all_warnings(DOUBLE_EXTENDS_NODE2D)
|
||||
var DoubleExtendsWindowDialog = Wm.load_script_ignoring_all_warnings(DOUBLE_EXTENDS_WINDOW_DIALOG)
|
||||
var DoubleWithStatic = Wm.load_script_ignoring_all_warnings(DOUBLE_WITH_STATIC)
|
||||
var DoubleMeScene = Wm.load_script_ignoring_all_warnings(DOUBLE_ME_SCENE_PATH)
|
||||
var InnerClasses = Wm.load_script_ignoring_all_warnings(INNER_CLASSES_PATH)
|
||||
var DoubleDefaultParameters = Wm.load_script_ignoring_all_warnings(DOUBLE_DEFAULT_PARAMETERS)
|
||||
var InitParameters = Wm.load_script_ignoring_all_warnings(INIT_PARAMETERS)
|
||||
|
||||
|
||||
|
||||
|
||||
class TestTheBasics:
|
||||
extends BaseTest
|
||||
|
||||
var gr = {
|
||||
doubler = null,
|
||||
stubber = null
|
||||
}
|
||||
|
||||
|
||||
func before_each():
|
||||
gr.doubler = Doubler.new()
|
||||
gr.stubber = Stubber.new()
|
||||
gr.doubler.set_stubber(gr.stubber)
|
||||
gr.doubler.add_ignored_method(DoubleMe, '_notification')
|
||||
|
||||
|
||||
func test_stubbing_method_returns_expected_value():
|
||||
var D = gr.doubler.double(DoubleMe)
|
||||
var sp = StubParams.new(DOUBLE_ME_PATH, 'get_value').to_return(7)
|
||||
gr.stubber.add_stub(sp)
|
||||
var dbl = autofree(D.new())
|
||||
assert_is(dbl, DoubleMe, 'it is a DoubleMe')
|
||||
assert_eq(dbl.get_value(), 7)
|
||||
if(is_failing()):
|
||||
print(DoubleMe, D, dbl)
|
||||
# print(gr.stubber.to_s())
|
||||
|
||||
func test_can_stub_non_local_methods():
|
||||
var D = autofree(gr.doubler.double(DoubleMe))
|
||||
var sp = StubParams.new(DOUBLE_ME_PATH, 'get_position').to_return(Vector2(11, 11))
|
||||
gr.stubber.add_stub(sp)
|
||||
assert_eq(autofree(D.new()).get_position(), Vector2(11, 11))
|
||||
|
||||
func test_when_non_local_methods_not_stubbed_super_is_returned():
|
||||
var D = autofree(gr.doubler.double(DoubleMe))
|
||||
var d = autofree(D.new())
|
||||
assert_eq(d.get_child_count(), 0)
|
||||
|
||||
func test_can_stub_doubled_instance_values():
|
||||
var D = autofree(gr.doubler.double(DoubleMe))
|
||||
var d1 = autofree(D.new())
|
||||
var d2 = autofree(D.new())
|
||||
|
||||
var sp1 = StubParams.new(DOUBLE_ME_PATH, 'get_value').to_return(5)
|
||||
gr.stubber.add_stub(sp1)
|
||||
var sp2 = StubParams.new(d1, 'get_value').to_return(10)
|
||||
gr.stubber.add_stub(sp2)
|
||||
|
||||
assert_eq(d1.get_value(), 10, 'instantiate gets right value')
|
||||
assert_eq(d2.get_value(), 5, 'other instantiate gets class value')
|
||||
|
||||
func test_stubbed_methods_send_parameters_in_callback():
|
||||
var sp = StubParams.new(DOUBLE_ME_PATH, 'has_one_param')
|
||||
sp.to_return(10).when_passed(1)
|
||||
gr.stubber.add_stub(sp)
|
||||
var d = autofree(gr.doubler.double(DoubleMe).new())
|
||||
assert_eq(d.has_one_param(1), 10)
|
||||
assert_eq(d.has_one_param('asdf'), null)
|
||||
|
||||
func test_stub_with_nothing_works_with_parameters():
|
||||
var sp1 = StubParams.new(DOUBLE_ME_PATH, 'has_one_param').to_return(5)
|
||||
var sp2 = StubParams.new(DOUBLE_ME_PATH, 'has_one_param')
|
||||
sp2.to_return(10).when_passed(1)
|
||||
gr.stubber.add_stub(sp1)
|
||||
gr.stubber.add_stub(sp2)
|
||||
|
||||
var d = autofree(gr.doubler.double(DoubleMe).new())
|
||||
assert_eq(d.has_one_param(), 5)
|
||||
if(is_failing()):
|
||||
print(gr.stubber.to_s())
|
||||
|
||||
func test_can_stub_doubled_scenes():
|
||||
var sp = StubParams.new(DOUBLE_ME_SCENE_PATH, 'return_hello')
|
||||
sp.to_return('world')
|
||||
gr.stubber.add_stub(sp)
|
||||
var inst = autofree(gr.doubler.double_scene(DoubleMeScene).instantiate())
|
||||
assert_eq(inst.return_hello(), 'world')
|
||||
|
||||
func test_when_stubbed_to_call_super_then_super_is_called():
|
||||
var doubled = autofree(gr.doubler.double(DoubleMe).new())
|
||||
var params = GutUtils.StubParams.new(doubled, 'set_value').to_call_super()
|
||||
gr.stubber.add_stub(params)
|
||||
doubled.set_value(99)
|
||||
assert_eq(doubled._value, 99)
|
||||
|
||||
func test_when_super_awaits_the_method_awaits():
|
||||
var doubled = add_child_autofree(gr.doubler.double(DoubleMe).new())
|
||||
var params = GutUtils.StubParams.new(doubled.await_seconds).to_call_super()
|
||||
gr.stubber.add_stub(params)
|
||||
var before = Time.get_ticks_msec()
|
||||
await doubled.await_seconds(1)
|
||||
var elapsed = Time.get_ticks_msec() - before
|
||||
assert_almost_eq(elapsed, 1000, 300) # 300 seems like a lot, but i guess it's not.
|
||||
|
||||
func test_can_stub_native_methods():
|
||||
var d_node2d = autofree(gr.doubler.double_gdnative(Node2D).new())
|
||||
var params = GutUtils.StubParams.new(d_node2d, 'get_position').to_return(-1)
|
||||
gr.stubber.add_stub(params)
|
||||
assert_eq(d_node2d.get_position(), -1)
|
||||
|
||||
func test_partial_double_of_Node2D_returns_super_values():
|
||||
var pd_node_2d = autofree(gr.doubler.partial_double_gdnative(Node2D).new())
|
||||
assert_eq(pd_node_2d.is_blocking_signals(), false)
|
||||
|
||||
func test_can_stub_all_Node2D_doubles():
|
||||
var d_node2d = autofree(gr.doubler.double_gdnative(Node2D).new())
|
||||
var params = GutUtils.StubParams.new(Node2D, 'get_position').to_return(-1)
|
||||
gr.stubber.add_stub(params)
|
||||
assert_eq(d_node2d.get_position(), -1)
|
||||
if(is_failing()):
|
||||
print("Node2D = ", Node2D)
|
||||
print(gr.stubber.to_s())
|
||||
|
||||
func test_double_can_have_default_param_values_stubbed():
|
||||
var params = GutUtils.StubParams.new(INIT_PARAMETERS, '_init')
|
||||
params.param_defaults(["override_default"])
|
||||
gr.stubber.add_stub(params)
|
||||
var inst = gr.doubler.double(InitParameters).new()
|
||||
assert_eq(inst.value, 'override_default')
|
||||
if(is_failing()):
|
||||
print(gr.stubber.to_s())
|
||||
|
||||
func test_double_can_have_default_param_values_stubbed_after_double_created():
|
||||
var Dbl = gr.doubler.double(InitParameters)
|
||||
var params = GutUtils.StubParams.new(INIT_PARAMETERS, '_init')
|
||||
params.param_defaults(["override_default"])
|
||||
gr.stubber.add_stub(params)
|
||||
var inst = Dbl.new()
|
||||
assert_eq(inst.value, 'override_default')
|
||||
if(is_failing()):
|
||||
print(gr.stubber.to_s())
|
||||
|
||||
|
||||
|
||||
class TestInnerClasses:
|
||||
extends BaseTest
|
||||
|
||||
var doubler = null
|
||||
var stubber = null
|
||||
|
||||
func before_each():
|
||||
doubler = Doubler.new()
|
||||
stubber = GutUtils.Stubber.new()
|
||||
doubler.set_stubber(stubber)
|
||||
|
||||
|
||||
func test_can_stub_inner_using_loaded_inner_class():
|
||||
doubler.inner_class_registry.register(InnerClasses)
|
||||
var sp = StubParams.new(InnerClasses.InnerA, 'get_a').to_return(5)
|
||||
stubber.add_stub(sp)
|
||||
var dbl_inner_a = doubler.double(InnerClasses.InnerA).new()
|
||||
assert_eq(stubber.get_return(dbl_inner_a, 'get_a'), 5)
|
||||
|
||||
|
||||
|
||||
# Since defaults are only available for built-in methods these tests verify
|
||||
# specific method parameters that were found to cause a problem.
|
||||
class TestDefaultParameters:
|
||||
extends BaseTest
|
||||
|
||||
|
||||
|
||||
var doubler = null
|
||||
var stubber = null
|
||||
|
||||
func before_all():
|
||||
register_inner_classes(get_script())
|
||||
|
||||
func before_each():
|
||||
doubler = Doubler.new(GutUtils.DOUBLE_STRATEGY.INCLUDE_NATIVE)
|
||||
stubber = GutUtils.Stubber.new()
|
||||
doubler.set_stubber(stubber)
|
||||
|
||||
|
||||
func test_default_values_are_set_in_stubber():
|
||||
var dbl = autofree(doubler.double(DoubleDefaultParameters).new())
|
||||
var default_value = stubber.get_default_value(DoubleDefaultParameters, 'default_string', 0)
|
||||
assert_eq(default_value, 's')
|
||||
if(is_failing()):
|
||||
print(stubber.to_s())
|
||||
|
||||
func test_partial_gets_deault_values():
|
||||
var dbl = autofree(doubler.partial_double(DoubleDefaultParameters).new())
|
||||
var result = dbl.return_passed()
|
||||
assert_eq(result, 'ab', 'the defauts are a and b')
|
||||
|
||||
func test_partial_gets_passed_values_and_defaults():
|
||||
var dbl = autofree(doubler.partial_double(DoubleDefaultParameters).new())
|
||||
var result = dbl.return_passed('foo')
|
||||
assert_eq(result, 'foob')
|
||||
|
||||
func test_partial_gets_all_values_passed():
|
||||
var dbl = autofree(doubler.partial_double(DoubleDefaultParameters).new())
|
||||
var result = dbl.return_passed('foo', 'bar')
|
||||
assert_eq(result, 'foobar')
|
||||
|
||||
func test_default_parameters_for_double_when_stubbed():
|
||||
var dbl = autofree(doubler.double(DoubleDefaultParameters, DOUBLE_STRATEGY.SCRIPT_ONLY).new())
|
||||
var params = GutUtils.StubParams.new(
|
||||
dbl.defaulted_second_parameter.bind("jump"))\
|
||||
.to_return('hello')
|
||||
stubber.add_stub(params)
|
||||
assert_eq(stubber.get_default_value(dbl, 'defaulted_second_parameter', 0), null)
|
||||
assert_eq(stubber.get_default_value(dbl, 'defaulted_second_parameter', 1), 'p2')
|
||||
|
||||
|
||||
|
||||
class TestMonkeyPatching:
|
||||
extends BaseTest
|
||||
|
||||
var doubler = null
|
||||
var stubber = null
|
||||
|
||||
|
||||
var call_this_value = null
|
||||
func call_this(value):
|
||||
call_this_value = value
|
||||
|
||||
var return_this_value = 99
|
||||
func return_this():
|
||||
return return_this_value
|
||||
|
||||
func return_passed(p1=null, p2=null, p3=null, p4=null, p5=null, p6=null):
|
||||
return [p1, p2, p3, p4, p5, p6]
|
||||
|
||||
func before_each():
|
||||
call_this_value = null
|
||||
|
||||
doubler = Doubler.new()
|
||||
stubber = GutUtils.Stubber.new()
|
||||
doubler.set_stubber(stubber)
|
||||
|
||||
|
||||
func test_stubbed_method_calls_method():
|
||||
var dbl = autofree(doubler.double(DoubleMe).new())
|
||||
var params = GutUtils.StubParams.new(dbl.set_value).to_call(call_this)
|
||||
stubber.add_stub(params)
|
||||
dbl.set_value(9)
|
||||
assert_eq(call_this_value, 9)
|
||||
|
||||
|
||||
func test_stubbed_method_returns_value():
|
||||
var dbl = autofree(doubler.double(DoubleMe).new())
|
||||
var params = GutUtils.StubParams.new(dbl.get_value).to_call(return_this)
|
||||
stubber.add_stub(params)
|
||||
var result = dbl.get_value()
|
||||
assert_eq(result, 99)
|
||||
|
||||
|
||||
func test_with_bound_parameters():
|
||||
var dbl = autofree(doubler.double(DoubleMe).new())
|
||||
var params = GutUtils.StubParams.new(dbl.has_two_params_one_default)
|
||||
params.to_call(return_passed.bind('three', 'four'))
|
||||
stubber.add_stub(params)
|
||||
var result = dbl.has_two_params_one_default('one', 'two')
|
||||
assert_eq(result, ["one", "two", "three", "four", null, null])
|
||||
|
||||
|
||||
func test_with_lambda_that_awaits():
|
||||
var lambda = func(p1, _p2=null):
|
||||
await get_tree().create_timer(p1).timeout
|
||||
var dbl = autofree(doubler.double(DoubleMe).new())
|
||||
|
||||
var params = GutUtils.StubParams.new(dbl.has_two_params_one_default)
|
||||
params.to_call(lambda)
|
||||
stubber.add_stub(params)
|
||||
|
||||
var before = Time.get_ticks_msec()
|
||||
await dbl.has_two_params_one_default(1, 2)
|
||||
var elapsed = Time.get_ticks_msec() - before
|
||||
|
||||
assert_almost_eq(elapsed, 1000, 300) # yea, 300 is what you need.
|
||||
|
||||
|
||||
class TestSingletons:
|
||||
extends GutInternalTester
|
||||
|
||||
var doubler = null
|
||||
var stubber = null
|
||||
|
||||
func before_each():
|
||||
doubler = GutUtils.Doubler.new()
|
||||
stubber = GutUtils.Stubber.new()
|
||||
doubler.set_stubber(stubber)
|
||||
|
||||
func test_can_stub_singleton_method_via_class_to_return_value():
|
||||
var params = GutUtils.StubParams.new(Time.get_ticks_msec).to_return(99)
|
||||
stubber.add_stub(params)
|
||||
var dbl = doubler.double_singleton(Time).new()
|
||||
assert_eq(dbl.get_ticks_msec(), 99)
|
||||
|
||||
func test_can_stub_singleton_double_to_return_value():
|
||||
var dbl = doubler.double_singleton(Time).new()
|
||||
var params = GutUtils.StubParams.new(dbl.get_ticks_msec).to_return(10)
|
||||
stubber.add_stub(params)
|
||||
assert_eq(dbl.get_ticks_msec(), 10)
|
||||
|
||||
func test_can_stub_method_to_return_based_on_parameters():
|
||||
var params = GutUtils.StubParams.new(OS.get_system_dir)\
|
||||
.to_return("/asdf")\
|
||||
.when_passed('foo', true)
|
||||
stubber.add_stub(params)
|
||||
var dbl = doubler.double_singleton(OS).new()
|
||||
assert_eq(dbl.get_system_dir('bar', true), null)
|
||||
assert_eq(dbl.get_system_dir('foo', true), '/asdf')
|
||||
|
||||
func test_can_stub_method_to_return_based_on_parameters_without_specifying_defaults():
|
||||
var params = GutUtils.StubParams.new(OS.get_system_dir)\
|
||||
.to_return("/asdf")\
|
||||
.when_passed('foo', true)
|
||||
stubber.add_stub(params)
|
||||
var dbl = doubler.double_singleton(OS).new()
|
||||
assert_eq(dbl.get_system_dir('bar'), null)
|
||||
assert_eq(dbl.get_system_dir('foo'), '/asdf')
|
||||
|
||||
func test_can_stub_singleton_to_call_a_func():
|
||||
var params = GutUtils.StubParams.new(OS.get_system_dir)\
|
||||
.to_call(func(a, b): return '/hello')\
|
||||
.when_passed('foo', true)
|
||||
stubber.add_stub(params)
|
||||
var dbl = doubler.double_singleton(OS).new()
|
||||
assert_eq(dbl.get_system_dir('foo'), '/hello')
|
||||
|
||||
func test_can_stub_method_to_use_singleton_method():
|
||||
var dbl = doubler.double_singleton(Time).new()
|
||||
var params = GutUtils.StubParams.new(dbl.get_date_dict_from_unix_time)\
|
||||
.to_use_singleton()
|
||||
stubber.add_stub(params)
|
||||
assert_eq(dbl.get_date_dict_from_unix_time(10), Time.get_date_dict_from_unix_time(10))
|
||||
|
||||
func test_default_method_paramters_for_input_singleton():
|
||||
var dbl = doubler.double_singleton(Input).new()
|
||||
var method = 'is_action_just_pressed'
|
||||
assert_eq(stubber.get_default_value(dbl, method, 0), null)
|
||||
assert_eq(stubber.get_default_value(dbl, method, 1), false)
|
||||
# if(is_failing()):
|
||||
# print(stubber.to_s())
|
||||
|
||||
func test_default_method_paramters_for_input_singleton_when_stubbed():
|
||||
var dbl = doubler.double_singleton(Input).new()
|
||||
var method = 'is_action_just_pressed'
|
||||
var params = GutUtils.StubParams.new(
|
||||
dbl.is_action_just_pressed.bind("jump"))\
|
||||
.to_return(true)
|
||||
stubber.add_stub(params)
|
||||
|
||||
assert_eq(stubber.get_default_value(dbl, method, 0), null)
|
||||
assert_eq(stubber.get_default_value(dbl, method, 1), false)
|
||||
@@ -0,0 +1 @@
|
||||
uid://csj3khcpdpx1k
|
||||
61
addons/gut/test/integration/test_everything_together.gd
Normal file
61
addons/gut/test/integration/test_everything_together.gd
Normal file
@@ -0,0 +1,61 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
class TestLogging:
|
||||
extends GutInternalTester
|
||||
|
||||
var _gut = null
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
_gut._should_print_versions = false
|
||||
_gut.log_level = 0
|
||||
add_child_autofree(_gut)
|
||||
|
||||
|
||||
func test_gut_sets_doublers_logger():
|
||||
assert_eq(_gut.get_doubler().get_logger(), _gut.logger, 'Doubler logger')
|
||||
assert_eq(_gut.get_doubler()._method_maker.get_logger(), _gut.logger, 'MethodMaker logger')
|
||||
|
||||
func test_gut_sets_stubber_logger():
|
||||
assert_eq(_gut.get_stubber().get_logger(), _gut.logger)
|
||||
|
||||
# This test makes assertion using THIS test script instance since it would
|
||||
# be super hard to get a test object that was being run.
|
||||
func test_gut_sets_logger_on_tests():
|
||||
assert_eq(gut.logger, get_logger())
|
||||
|
||||
func test_gut_sets_logger_on_test_collector():
|
||||
assert_eq(_gut._test_collector.get_logger(), _gut.logger)
|
||||
|
||||
func test_gut_sets_logger_on_spy():
|
||||
assert_eq(_gut.get_spy().get_logger(), _gut.logger)
|
||||
|
||||
func test_method_maker_has_same_logger():
|
||||
var mm = _gut.get_doubler()._method_maker
|
||||
assert_eq(mm.get_logger(), _gut.logger)
|
||||
|
||||
func test_test_colledtor_has_same_logger():
|
||||
assert_eq(_gut.get_test_collector().get_logger(), _gut.logger)
|
||||
|
||||
|
||||
class TestMemoryMgmt:
|
||||
extends GutTest
|
||||
|
||||
func after_each():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_GutTest():
|
||||
var t = GutTest.new()
|
||||
add_child(t)
|
||||
t.free()
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_GutTest_with_waits():
|
||||
var t = GutTest.new()
|
||||
add_child(t)
|
||||
await wait_physics_frames(10)
|
||||
t.free()
|
||||
await wait_physics_frames(10)
|
||||
assert_no_new_orphans()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://c8puh05o6ilmp
|
||||
506
addons/gut/test/integration/test_gut_and_error_tracker.gd
Normal file
506
addons/gut/test/integration/test_gut_and_error_tracker.gd
Normal file
@@ -0,0 +1,506 @@
|
||||
extends GutTest
|
||||
|
||||
|
||||
class TestDefaults:
|
||||
extends GutInternalTester
|
||||
|
||||
func test_gut_uses_utils_error_tracker_by_default():
|
||||
var g = autofree(Gut.new(GutLogger.new()))
|
||||
assert_eq(g.error_tracker, GutUtils.get_error_tracker())
|
||||
|
||||
|
||||
|
||||
|
||||
class TestErrorFailures:
|
||||
extends GutInternalTester
|
||||
|
||||
func should_skip_script():
|
||||
return skip_if_debugger_active()
|
||||
|
||||
var _gut = null
|
||||
|
||||
func before_all():
|
||||
gut.error_tracker.disabled = true
|
||||
verbose = false
|
||||
DynamicGutTest.should_print_source = verbose
|
||||
|
||||
|
||||
func before_each():
|
||||
_gut = add_child_autofree(new_gut(verbose))
|
||||
GutErrorTracker.register_logger(_gut.error_tracker)
|
||||
|
||||
|
||||
func after_each():
|
||||
GutErrorTracker.deregister_logger(_gut.error_tracker)
|
||||
|
||||
|
||||
func after_all():
|
||||
gut.error_tracker.disabled = false
|
||||
|
||||
var _src_push_error = """
|
||||
func test_with_push_error():
|
||||
push_error('pushed error')
|
||||
assert_true(true, 'passing assert')
|
||||
"""
|
||||
|
||||
var _src_gut_error = """
|
||||
func test_with_gut_error():
|
||||
_lgr.error('this is a gut error')
|
||||
assert_true(true, 'passing assert')
|
||||
"""
|
||||
|
||||
var _src_script_error_in_called_method = """
|
||||
func divide_them(a, b):
|
||||
return a / b
|
||||
|
||||
func test_with_script_error():
|
||||
divide_them('one', 44)
|
||||
assert_true(true, 'passing assert')
|
||||
"""
|
||||
|
||||
# this one has to fool the parser with "get_first" otherwise the parser
|
||||
# will catch it and it errors on making the script.
|
||||
var _src_script_error_in_test = """
|
||||
func get_first():
|
||||
return "one"
|
||||
|
||||
func test_with_script_error():
|
||||
var a = get_first() / 44
|
||||
assert_true(true, 'passing assert')
|
||||
"""
|
||||
|
||||
func test_push_error_causes_failure():
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_push_error)
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1, 'one failing')
|
||||
assert_eq(t.passing, 1, 'one passing')
|
||||
|
||||
|
||||
func test_gut_error_causes_failure():
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_gut_error)
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1, 'one failing')
|
||||
assert_eq(t.passing, 1, 'one passing')
|
||||
|
||||
|
||||
func test_script_error_causes_failure():
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_script_error_in_called_method)
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1, 'one failing')
|
||||
assert_eq(t.passing, 1, 'one passing')
|
||||
|
||||
|
||||
func test_script_error_in_test_causes_failure():
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_script_error_in_test)
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1, 'one failing')
|
||||
assert_eq(t.passing, 0, 'no passing because of early exit from error')
|
||||
|
||||
|
||||
|
||||
|
||||
class TestErrorAsserts:
|
||||
extends GutInternalTester
|
||||
|
||||
func should_skip_script():
|
||||
return skip_if_debugger_active()
|
||||
|
||||
var _gut = null
|
||||
|
||||
func before_all():
|
||||
verbose = false
|
||||
gut.error_tracker.disabled = true
|
||||
DynamicGutTest.should_print_source = verbose
|
||||
|
||||
|
||||
func before_each():
|
||||
_gut = add_child_autofree(new_gut(verbose))
|
||||
GutErrorTracker.register_logger(_gut.error_tracker)
|
||||
|
||||
|
||||
func after_each():
|
||||
GutErrorTracker.deregister_logger(_gut.error_tracker)
|
||||
|
||||
|
||||
func after_all():
|
||||
gut.error_tracker.disabled = false
|
||||
|
||||
|
||||
var _src_divide_them = """
|
||||
func divide_them(a, b):
|
||||
return a / b
|
||||
"""
|
||||
|
||||
# ---------------------
|
||||
# assert_push_error_count
|
||||
# ---------------------
|
||||
func test_asserting_one_push_error_prevents_failure():
|
||||
var test_func = func(me):
|
||||
push_error('error 1')
|
||||
me.assert_push_error_count(1)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_asserting_two_push_error_prevents_failure():
|
||||
var test_func = func(me):
|
||||
push_error('error 1')
|
||||
push_error('error 2')
|
||||
me.assert_push_error_count(2)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_asserting_non_matching_push_error_causes_failure():
|
||||
var test_func = func(me):
|
||||
push_error('error 1')
|
||||
push_error('error 2')
|
||||
push_error('error 3')
|
||||
me.assert_push_error_count(1)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
# 2 failures, one for assert and one for the unexpected errors that
|
||||
# were not handled by the assert
|
||||
assert_eq(t.failing, 2)
|
||||
|
||||
|
||||
|
||||
# ---------------------
|
||||
# assert_push_error
|
||||
# ---------------------
|
||||
func test_push_error_with_matching_text_prevents_failure():
|
||||
var test_func = func(me):
|
||||
push_error('_special_ text')
|
||||
me.assert_push_error('_special_')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
func test_push_error_with_non_matching_text_fails():
|
||||
var test_func = func(me):
|
||||
push_error('_special_ text')
|
||||
me.assert_push_error('nope')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 2)
|
||||
|
||||
func test_push_error_with_matching_text_only_consumes_one():
|
||||
var test_func = func(me):
|
||||
push_error('_special_ one')
|
||||
push_error('_special_ two')
|
||||
me.assert_push_error('_special_')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
assert_eq(t.failing, 1)
|
||||
|
||||
func test_push_error_can_assert_multiple_different_texts():
|
||||
var test_func = func(me):
|
||||
push_error('_special_ one')
|
||||
push_error('_special_ two')
|
||||
me.assert_push_error('one')
|
||||
me.assert_push_error('two')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 2)
|
||||
assert_eq(t.failing, 0)
|
||||
|
||||
func test_asserting_multiple_push_error_with_same_text():
|
||||
var test_func = func(me):
|
||||
push_error('distinct_error')
|
||||
push_error('distinct_error')
|
||||
me.assert_push_error("distinct_error")
|
||||
me.assert_push_error("distinct_error")
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 2)
|
||||
assert_eq(t.failing, 0)
|
||||
|
||||
# ---------------------
|
||||
# assert_engine_error_count
|
||||
# ---------------------
|
||||
func test_asserting_engine_error_prevents_failure():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.assert_engine_error_count(1)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_asserting_multiple_engine_error_prevents_failure():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
me.assert_engine_error_count(3)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_asserting_non_matching_count_causes_two_failures():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
me.assert_engine_error_count(2)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
# 2 failures, one for assert and one for the unexpected errors that
|
||||
# were not handled by the assert
|
||||
assert_eq(t.failing, 2)
|
||||
|
||||
|
||||
# ---------------------
|
||||
# Engine error text
|
||||
# ---------------------
|
||||
func test_engine_with_matching_text_prevents_failure():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.assert_engine_error('Invalid operands')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_engine_with_non_matching_text_fails():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.assert_engine_error('nope')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 2)
|
||||
|
||||
|
||||
func test_engine_with_matching_text_only_consumes_one():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
me.assert_engine_error('Invalid operands')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
assert_eq(t.failing, 1)
|
||||
|
||||
|
||||
func test_engine_can_assert_multiple_different_texts():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 0)
|
||||
me.assert_engine_error('Invalid operands')
|
||||
me.assert_engine_error('Division by zero')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 2)
|
||||
assert_eq(t.failing, 0)
|
||||
|
||||
# ---------------------
|
||||
# assert_push_warning_count
|
||||
# ---------------------
|
||||
func test_asserting_one_push_warning_when_none_causes_failure():
|
||||
var test_func = func(me):
|
||||
me.assert_push_warning_count(1)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1)
|
||||
|
||||
|
||||
func test_asserting_matching_push_warning_count_passes():
|
||||
var test_func = func(me):
|
||||
push_warning('warn 1')
|
||||
me.assert_push_warning_count(1)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_asserting_two_push_warnings_passes():
|
||||
var test_func = func(me):
|
||||
push_warning('warn 1')
|
||||
push_warning('warn 2')
|
||||
me.assert_push_warning_count(2)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
# ---------------------
|
||||
# assert_push_warning
|
||||
# ---------------------
|
||||
func test_asserting_push_warning_when_no_warnings_causes_failure():
|
||||
var test_func = func(me):
|
||||
me.assert_push_warning("nothing")
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1)
|
||||
|
||||
|
||||
func test_asserting_push_warning_with_matching_text_passes():
|
||||
var test_func = func(me):
|
||||
push_warning("warn 1")
|
||||
me.assert_push_warning("warn")
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1)
|
||||
|
||||
|
||||
func test_asserting_non_matching_push_warning_causes_failure():
|
||||
var test_func = func(me):
|
||||
push_warning('warn 1')
|
||||
push_warning('warn 2')
|
||||
push_warning('warn 3')
|
||||
me.assert_push_warning('hello')
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.failing, 1)
|
||||
|
||||
|
||||
# ---------------------
|
||||
# misc
|
||||
# ---------------------
|
||||
func test_can_assert_multiple_error_types():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
push_error('push error 1')
|
||||
me.assert_engine_error_count(2)
|
||||
me.assert_push_error_count(1)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 2)
|
||||
|
||||
|
||||
# ---------------------
|
||||
# get_errors
|
||||
# ---------------------
|
||||
func test_can_get_all_errors_that_occur():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
push_error('pushe error 1')
|
||||
var errs = me.get_errors()
|
||||
me.assert_eq(errs.size(), 3)
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1, 'pass count')
|
||||
# Errors are not consumed so they still cause errors.
|
||||
assert_eq(t.failing, 1, 'fail count')
|
||||
|
||||
|
||||
func test_can_mark_all_errors_handled_manually():
|
||||
var test_func = func(me):
|
||||
me.divide_them(1, 'b')
|
||||
me.divide_them(1, 'b')
|
||||
push_error('push error 1')
|
||||
var errs = me.get_errors()
|
||||
me.assert_eq(errs.size(), 3)
|
||||
for e in errs:
|
||||
e.handled = true
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_src_divide_them)
|
||||
s.add_lambda_test(test_func, 'test_something')
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 1, 'pass count')
|
||||
# Errors are not consumed so they still cause errors.
|
||||
assert_eq(t.failing, 0, 'fail count')
|
||||
|
||||
|
||||
func test_parameterized_tests_do_not_compound_error_counts():
|
||||
var src_test_with_params = """
|
||||
var params = [1, 2, 3, 4, 5]
|
||||
func test_parameterized_and_errors(p=use_parameters(params)):
|
||||
push_error(str("Error ", p))
|
||||
assert_push_error_count(1)
|
||||
"""
|
||||
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(src_test_with_params)
|
||||
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.passing, 5, '5 params, 1 assert each: pass count')
|
||||
assert_eq(t.failing, 0, 'fail count')
|
||||
@@ -0,0 +1 @@
|
||||
uid://3bg1hnu6os70
|
||||
25
addons/gut/test/integration/test_gut_and_spy.gd
Normal file
25
addons/gut/test/integration/test_gut_and_spy.gd
Normal file
@@ -0,0 +1,25 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
func test_can_get_spy():
|
||||
var g = autofree(new_gut(verbose))
|
||||
assert_ne(g.get_spy(), null)
|
||||
|
||||
func test_spy_for_doubler_is_guts_spy():
|
||||
var g = autofree(new_gut(verbose))
|
||||
assert_eq(g.get_doubler().get_spy(), g.get_spy())
|
||||
|
||||
|
||||
# ---------------------------------
|
||||
# these two tests use the gut instance that is passed to THIS test. This isn't
|
||||
# PURE testing but it appears to cover the bases ok.
|
||||
class TestGutClearsSpyBetweenTests:
|
||||
extends 'res://addons/gut/test.gd'
|
||||
|
||||
func test_spy_cleared_between_tests_setup():
|
||||
gut.get_spy().add_call('thing', 'method')
|
||||
assert_true(gut.get_spy().was_called('thing', 'method'))
|
||||
|
||||
func test_spy_cleared_between_tests():
|
||||
assert_false(gut.get_spy().was_called('thing', 'method'))
|
||||
# ---------------------------------
|
||||
1
addons/gut/test/integration/test_gut_and_spy.gd.uid
Normal file
1
addons/gut/test/integration/test_gut_and_spy.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://brp8tj0vlp8vb
|
||||
51
addons/gut/test/integration/test_gut_and_stubber.gd
Normal file
51
addons/gut/test/integration/test_gut_and_stubber.gd
Normal file
@@ -0,0 +1,51 @@
|
||||
extends GutInternalTester
|
||||
|
||||
var StubParams = load('res://addons/gut/stub_params.gd')
|
||||
|
||||
func test_can_get_stubber():
|
||||
var g = autofree(new_gut(verbose))
|
||||
assert_ne(g.get_stubber(), null)
|
||||
|
||||
# ---------------------------------
|
||||
# these two tests use the gut instance that is passed to THIS test. This isn't
|
||||
# PURE testing but it appears to cover the bases ok.
|
||||
# ------
|
||||
func test_stubber_cleared_between_tests_setup():
|
||||
var sp = StubParams.new('thing', 'method').to_return(5)
|
||||
gut.get_stubber().add_stub(sp)
|
||||
pass_test('this sets up for next test')
|
||||
|
||||
|
||||
func test_stubber_cleared_between_tests():
|
||||
assert_eq(gut.get_stubber().get_return('thing', 'method'), null)
|
||||
# ---------------------------------
|
||||
|
||||
func test_can_get_doubler():
|
||||
var g = autofree(new_gut(verbose))
|
||||
assert_ne(g.get_doubler(), null)
|
||||
|
||||
func test_doublers_stubber_is_guts_stubber():
|
||||
var g = autofree(new_gut(verbose))
|
||||
assert_eq(g.get_doubler().get_stubber(), g.get_stubber())
|
||||
|
||||
# Since the stubber and doubler are "global" to gut, this is the best place
|
||||
# to test this so that the _double_count in the doubler isn't reset which
|
||||
# causes some super confusing side effects. This test is here because the
|
||||
# opposite used to be true when things were indexed in the stubber by their
|
||||
# path. This is no longer possible to do, but it doesn't seem like a big
|
||||
# loss, you can still stub instances just fine. Not sure of a scenario where
|
||||
# you would want to stub all instances of a scene one way and all instances
|
||||
# of a script another way. And if there is a scenrio where this is needed, you
|
||||
# can just stub all the instances.
|
||||
func test_scene_and_script_are_the_same_when_stubbing_resource():
|
||||
var script_path = DOUBLE_ME_SCENE_PATH.replace('.tscn', '.gd')
|
||||
|
||||
var scene = double(DoubleMeScene).instantiate()
|
||||
var script = double(load(script_path)).new()
|
||||
|
||||
# order here matters. The 2nd will overwrite the first.
|
||||
stub(DOUBLE_ME_SCENE_PATH, 'return_hello').to_return('scene')
|
||||
stub(script_path, 'return_hello').to_return('script')
|
||||
|
||||
assert_eq(scene.return_hello(), 'script')
|
||||
assert_eq(script.return_hello(), 'script')
|
||||
1
addons/gut/test/integration/test_gut_and_stubber.gd.uid
Normal file
1
addons/gut/test/integration/test_gut_and_stubber.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bedsk56wsq44a
|
||||
84
addons/gut/test/integration/test_gut_import_export.gd
Normal file
84
addons/gut/test/integration/test_gut_import_export.gd
Normal file
@@ -0,0 +1,84 @@
|
||||
extends GutInternalTester
|
||||
|
||||
var _test_gut = null
|
||||
const EXPORT_FILE = 'res://test/exported_tests.cfg'
|
||||
|
||||
func before_each():
|
||||
_test_gut = new_gut()
|
||||
_test_gut.log_level = 4
|
||||
# _test_gut._should_print_versions = false
|
||||
autofree(_test_gut)
|
||||
|
||||
func after_each():
|
||||
gut.file_delete(EXPORT_FILE)
|
||||
_test_gut = null
|
||||
|
||||
func test_export_test_exports_tests():
|
||||
_test_gut.add_directory('res://test/resources/parsing_and_loading_samples')
|
||||
_test_gut.export_tests(EXPORT_FILE)
|
||||
assert_file_not_empty(EXPORT_FILE)
|
||||
|
||||
func test_export_uses_export_path_if_no_path_sent():
|
||||
_test_gut.add_directory('res://test/resources/parsing_and_loading_samples')
|
||||
_test_gut.export_path = EXPORT_FILE
|
||||
_test_gut.export_tests()
|
||||
assert_file_not_empty(EXPORT_FILE)
|
||||
|
||||
func test_if_export_path_not_set_and_no_path_passed_error_is_generated():
|
||||
_test_gut.add_directory('res://test/resources/parsing_and_loading_samples')
|
||||
_test_gut.export_tests()
|
||||
assert_tracked_gut_error(_test_gut)
|
||||
|
||||
func test_importing_tests_populates_test_collector():
|
||||
_test_gut.add_directory('res://test/resources/parsing_and_loading_samples')
|
||||
_test_gut.export_tests(EXPORT_FILE)
|
||||
|
||||
var _import_gut = add_child_autofree(new_gut())
|
||||
_import_gut.import_tests(EXPORT_FILE)
|
||||
|
||||
assert_eq(
|
||||
_import_gut.get_test_collector().scripts.size(),
|
||||
_test_gut.get_test_collector().scripts.size())
|
||||
|
||||
|
||||
func test_import_tests_uses_export_path_by_default():
|
||||
_test_gut.add_directory('res://test/resources/parsing_and_loading_samples')
|
||||
_test_gut.export_tests(EXPORT_FILE)
|
||||
|
||||
var _import_gut = add_child_autofree(new_gut())
|
||||
_import_gut.export_path = EXPORT_FILE
|
||||
_import_gut.import_tests()
|
||||
|
||||
assert_eq(
|
||||
_import_gut.get_test_collector().scripts.size(),
|
||||
_test_gut.get_test_collector().scripts.size())
|
||||
|
||||
func test_import_errors_if_file_does_not_exist():
|
||||
_test_gut.import_tests('res://file_does_not_exist.txt')
|
||||
assert_tracked_gut_error(_test_gut)
|
||||
|
||||
func test_gut_runs_the_imported_tests():
|
||||
pending('this is failing and I think it is related to import/export not working yet.')
|
||||
return
|
||||
|
||||
_test_gut.add_directory('res://test/resources/parsing_and_loading_samples')
|
||||
_test_gut.export_tests(EXPORT_FILE)
|
||||
|
||||
var _import_gut = new_gut()
|
||||
add_child(_import_gut)
|
||||
_import_gut.export_path = EXPORT_FILE
|
||||
_import_gut.import_tests()
|
||||
_import_gut.test_scripts()
|
||||
|
||||
var import_totals = _import_gut.get_summary().get_totals()
|
||||
# The magic numbers in these asserts were picked from running the same set
|
||||
# of scripts through the test_summary.gd script and checking the output.
|
||||
assert_eq(import_totals.scripts, 13, 'total scripts')
|
||||
assert_eq(import_totals.tests, 37, 'total tests')
|
||||
|
||||
# picked some arbitrary number since these assert counts could change
|
||||
# over time. Last run was 16 passing. This is probably a sign that this
|
||||
# shouldn't be reusing parsing_and_loading_samples but the world isn't
|
||||
# perfect alright? I'm trying here, but lay off a bit why dontcha.
|
||||
assert_gt(import_totals.passing, 10, 'min total passing')
|
||||
_import_gut.free()
|
||||
@@ -0,0 +1 @@
|
||||
uid://chc2xdt1g5qs
|
||||
59
addons/gut/test/integration/test_gut_integration.gd
Normal file
59
addons/gut/test/integration/test_gut_integration.gd
Normal file
@@ -0,0 +1,59 @@
|
||||
extends GutTest
|
||||
|
||||
class CoupledScriptTest:
|
||||
extends GutInternalTester
|
||||
|
||||
var _gut = null
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
_gut._should_print_versions = false
|
||||
_gut._should_print_summary = false
|
||||
add_child_autofree(_gut)
|
||||
|
||||
func _same_name():
|
||||
return gut.get_current_test_object().name
|
||||
|
||||
func _run_tests(script_path, inner_class, test_name):
|
||||
_gut.add_script(script_path)
|
||||
|
||||
if(inner_class != null):
|
||||
_gut.inner_class_name = inner_class
|
||||
|
||||
if(test_name != null):
|
||||
_gut.unit_test_name = test_name
|
||||
|
||||
_gut.wait_log_delay = wait_log_delay
|
||||
_gut.test_scripts()
|
||||
|
||||
|
||||
func _assert_pass_fail_count(passing, failing):
|
||||
assert_eq(_gut.get_pass_count(), passing, 'Pass count does not match')
|
||||
assert_eq(_gut.get_fail_count(), failing, 'Failing count does not match')
|
||||
|
||||
|
||||
class TestYieldInBeforeAfterMethods:
|
||||
extends CoupledScriptTest
|
||||
|
||||
const SCRIPT_PATH = 'res://test/resources/yield_in_before_after_methods.gd'
|
||||
|
||||
func test_gut_waits_for_yield_in_before_all():
|
||||
_run_tests(SCRIPT_PATH, 'TestYieldInBeforeAll', null)
|
||||
await wait_for_signal(_gut.end_run, 10)
|
||||
_assert_pass_fail_count(1, 0)
|
||||
|
||||
func test_gut_waits_for_yield_in_after_all():
|
||||
var start_time = Time.get_ticks_msec()
|
||||
_run_tests(SCRIPT_PATH, 'TestYieldInAfterAll', null)
|
||||
await wait_for_signal(_gut.end_run, 10)
|
||||
assert_gt(Time.get_ticks_msec() - start_time, 1000)
|
||||
|
||||
func test_gut_waits_for_yield_in_after_each():
|
||||
_run_tests(SCRIPT_PATH, 'TestYieldInAfterEach', null)
|
||||
await wait_for_signal(_gut.end_run, 10)
|
||||
_assert_pass_fail_count(1, 1)
|
||||
|
||||
func test_gut_waits_for_yield_in_before_each():
|
||||
_run_tests(SCRIPT_PATH, 'TestYieldInBeforeEach', null)
|
||||
await wait_for_signal(_gut.end_run, 10)
|
||||
_assert_pass_fail_count(1, 0)
|
||||
1
addons/gut/test/integration/test_gut_integration.gd.uid
Normal file
1
addons/gut/test/integration/test_gut_integration.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dv1bo3sdwop65
|
||||
132
addons/gut/test/integration/test_gut_skip_scripts.gd
Normal file
132
addons/gut/test/integration/test_gut_skip_scripts.gd
Normal file
@@ -0,0 +1,132 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
var _src_passing_test = """
|
||||
func test_is_passing():
|
||||
assert_true(true)
|
||||
"""
|
||||
var _src_should_skip_script_method_ret_true = """
|
||||
func should_skip_script():
|
||||
return true
|
||||
"""
|
||||
var _src_should_skip_script_method_ret_false = """
|
||||
func should_skip_script():
|
||||
return false
|
||||
"""
|
||||
var _src_should_skip_script_method_ret_string = """
|
||||
func should_skip_script():
|
||||
return 'skip me'
|
||||
"""
|
||||
var _scr_awaiting_should_skip_script = """
|
||||
func should_skip_script():
|
||||
print("Awaiting before skipping.")
|
||||
await wait_seconds(1)
|
||||
print("Now skip.")
|
||||
return true
|
||||
"""
|
||||
|
||||
var _gut = null
|
||||
|
||||
func before_all():
|
||||
verbose = false
|
||||
DynamicGutTest.should_print_source = verbose
|
||||
|
||||
|
||||
func before_each():
|
||||
_gut = add_child_autofree(new_gut(verbose))
|
||||
|
||||
# --------------
|
||||
# skip var
|
||||
# --------------
|
||||
func test_using_skip_script_variable_is_deprecated():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source("var skip_script = 'skip me thanks'")
|
||||
s.add_source(_src_passing_test)
|
||||
var t = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(t.deprecated, 1, 'Should be one deprecation.')
|
||||
|
||||
|
||||
func test_when_skip_script_var_is_string_script_is_skipped():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source("var skip_script = 'skip me'")
|
||||
s.add_source(_src_passing_test)
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
|
||||
assert_eq(smry.tests, 0, 'no tests should be ran')
|
||||
assert_eq(smry.risky, 1, 'Should be marked as risky due to skip')
|
||||
|
||||
func test_when_skip_script_var_is_null_the_script_is_ran():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source("var skip_script = null")
|
||||
s.add_source(_src_passing_test)
|
||||
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(smry.tests, 1, 'the one test should be ran')
|
||||
assert_eq(smry.risky, 0, 'not marked risky just for having var')
|
||||
|
||||
func test_when_skip_scrpt_var_is_true_the_script_is_skipped():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source("var skip_script = true")
|
||||
s.add_source(_src_passing_test)
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
|
||||
assert_eq(smry.tests, 0, 'no tests should be ran')
|
||||
assert_eq(smry.risky, 1, 'Should be marked as risky due to skip')
|
||||
|
||||
func test_awaiting_before_should_skip_script():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source(_scr_awaiting_should_skip_script)
|
||||
await s.run_tests_in_gut_await(_gut)
|
||||
await wait_for_signal(_gut.end_run, 3, "Should take exactly 1 second")
|
||||
var summery = GutUtils.Summary.new()
|
||||
var totals = summery.get_totals(_gut)
|
||||
|
||||
assert_eq(totals.tests, 0, 'no tests should be ran')
|
||||
assert_eq(totals.risky, 1, 'Should be marked as risky due to skip')
|
||||
|
||||
|
||||
# --------------
|
||||
# skip method
|
||||
# --------------
|
||||
func test_should_skip_script_method_returns_false_by_default():
|
||||
var test = autofree(GutTest.new())
|
||||
assert_false(test.should_skip_script())
|
||||
|
||||
|
||||
func test_when_should_skip_script_returns_false_script_is_run():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source(_src_should_skip_script_method_ret_false)
|
||||
s.add_source(_src_passing_test)
|
||||
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
assert_eq(smry.tests, 1, 'Tests should run')
|
||||
assert_eq(smry.risky, 0, 'Should not be risky')
|
||||
|
||||
|
||||
func test_when_should_skip_script_returns_true_script_is_skipped():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source(_src_should_skip_script_method_ret_true)
|
||||
s.add_source(_src_passing_test)
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
|
||||
assert_eq(smry.tests, 0, 'no tests should be ran')
|
||||
assert_eq(smry.risky, 1, 'Should be marked as risky due to skip')
|
||||
|
||||
|
||||
func test_when_should_skip_script_returns_string_script_is_skipped():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source(_src_should_skip_script_method_ret_string)
|
||||
s.add_source(_src_passing_test)
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
|
||||
assert_eq(smry.tests, 0, 'no tests should be ran')
|
||||
assert_eq(smry.risky, 1, 'Should be marked as risky due to skip')
|
||||
|
||||
|
||||
func test_using_should_skip_script_method_is_not_deprecated():
|
||||
var s = DynamicGutTest.new()
|
||||
s.add_source(_src_should_skip_script_method_ret_true)
|
||||
s.add_source(_src_passing_test)
|
||||
var smry = await s.run_tests_in_gut_await(_gut)
|
||||
|
||||
assert_eq(smry.deprecated, 0, 'nothing is deprecated')
|
||||
1
addons/gut/test/integration/test_gut_skip_scripts.gd.uid
Normal file
1
addons/gut/test/integration/test_gut_skip_scripts.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://beskegy2ok1wg
|
||||
@@ -0,0 +1,16 @@
|
||||
extends GutTest
|
||||
|
||||
var scene_path = "res://test/resources/simple_scene.tscn"
|
||||
var Scene = load(scene_path)
|
||||
|
||||
func test_with_change_scene_to_file():
|
||||
get_tree().change_scene_to_file(scene_path)
|
||||
await get_tree().scene_changed
|
||||
autofree(get_tree().current_scene)
|
||||
pass_test('passing')
|
||||
|
||||
func test_with_change_scene_to_packed():
|
||||
get_tree().change_scene_to_packed(Scene)
|
||||
await get_tree().scene_changed
|
||||
autofree(get_tree().current_scene)
|
||||
pass_test('passing')
|
||||
@@ -0,0 +1 @@
|
||||
uid://igdfkcutuncs
|
||||
117
addons/gut/test/integration/test_junit_xml_export.gd
Normal file
117
addons/gut/test/integration/test_junit_xml_export.gd
Normal file
@@ -0,0 +1,117 @@
|
||||
extends GutInternalTester
|
||||
|
||||
var JunitExporter = GutUtils.JunitXmlExport
|
||||
|
||||
var _test_gut = null
|
||||
|
||||
const RESULT_XML_VALID_TAGS := {
|
||||
"testsuite": [ "name", "tests", "failures", "skipped", "time" ],
|
||||
"testcase": [ "name", "assertions", "status", "classname", "time" ],
|
||||
"testsuites": [ "name", "failures", "tests" ],
|
||||
"failure": [ "message" ],
|
||||
"skipped": [ "message" ]
|
||||
}
|
||||
|
||||
# Returns a new gut object, all setup for testing.
|
||||
func get_a_gut():
|
||||
var g = new_gut(verbose)
|
||||
return g
|
||||
|
||||
|
||||
func run_scripts(g, one_or_more):
|
||||
var scripts = one_or_more
|
||||
if(typeof(scripts) != TYPE_ARRAY):
|
||||
scripts = [scripts]
|
||||
for s in scripts:
|
||||
g.add_script(export_script(s))
|
||||
g.test_scripts()
|
||||
await g.end_run
|
||||
|
||||
|
||||
# Very simple xml validator. Matches closing tags to opening tags as they
|
||||
# are encountered and any validation provided by XMLParser (which is very
|
||||
# little). Does not catch malformed attributes among other things probably.
|
||||
# Additionally checks for valid tags as defined by RESULT_XML_VALID_TAGS
|
||||
func assert_is_valid_xml(xml : String)->void:
|
||||
var tags = []
|
||||
var pba = xml.to_utf8_buffer()
|
||||
var parser = XMLParser.new()
|
||||
var result = parser.open_buffer(pba)
|
||||
|
||||
while(result == OK):
|
||||
if(parser.get_node_type() == parser.NODE_ELEMENT):
|
||||
var tag_name := parser.get_node_name()
|
||||
tags.push_back(tag_name)
|
||||
|
||||
if (tag_name in RESULT_XML_VALID_TAGS):
|
||||
# check for required attributes
|
||||
var required_attributes : Array = RESULT_XML_VALID_TAGS[tag_name].duplicate()
|
||||
var missing_attributes := required_attributes.filter(func(attribute): return !parser.has_attribute(attribute))
|
||||
assert_eq(missing_attributes, [], str(tag_name, ": Required attribute(s) missing ", missing_attributes))
|
||||
|
||||
# check for unexpected attributes
|
||||
var unexpected_attributes : Array[String] = []
|
||||
for attribute_index : int in parser.get_attribute_count():
|
||||
var attribute_name := parser.get_attribute_name(attribute_index)
|
||||
if not attribute_name in RESULT_XML_VALID_TAGS[tag_name]:
|
||||
unexpected_attributes.push_back(attribute_name)
|
||||
assert_eq(unexpected_attributes, [], str(tag_name, " Unexpected attribute(s) ", unexpected_attributes))
|
||||
else:
|
||||
fail_test("%s is not one of the expected tags: %s" % [tag_name, RESULT_XML_VALID_TAGS.keys()])
|
||||
|
||||
elif(parser.get_node_type() == parser.NODE_ELEMENT_END):
|
||||
var last_tag = tags.pop_back()
|
||||
if(last_tag != parser.get_node_name()):
|
||||
var msg = str("End tag does not match. Expected: ", last_tag, ', got: ', parser.get_node_name())
|
||||
push_error(msg)
|
||||
result = -1
|
||||
|
||||
if(result != -1):
|
||||
result = parser.read()
|
||||
|
||||
assert_eq(result, ERR_FILE_EOF, 'Parsing xml should reach EOF')
|
||||
|
||||
|
||||
func export_script(n):
|
||||
return str('res://test/resources/exporter_test_files/', n)
|
||||
|
||||
func before_each():
|
||||
_test_gut = get_a_gut()
|
||||
add_child_autoqfree(_test_gut)
|
||||
|
||||
|
||||
func test_can_make_one():
|
||||
assert_not_null(JunitExporter.new())
|
||||
|
||||
func test_no_tests_returns_valid_xml():
|
||||
await run_scripts(_test_gut, [])
|
||||
var re = JunitExporter.new()
|
||||
var result = re.get_results_xml(_test_gut)
|
||||
assert_is_valid_xml(result)
|
||||
|
||||
func test_spot_check():
|
||||
await run_scripts(_test_gut, ['test_simple_2.gd', 'test_simple.gd', 'test_with_inner_classes.gd', 'test_special_chars_in_test_output.gd'])
|
||||
var re = JunitExporter.new()
|
||||
var result = re.get_results_xml(_test_gut)
|
||||
assert_is_valid_xml(result)
|
||||
|
||||
func test_res_removed_from_classname_path():
|
||||
await run_scripts(_test_gut, 'test_simple_2.gd')
|
||||
var re = JunitExporter.new()
|
||||
var result = re.get_results_xml(_test_gut)
|
||||
assert_false(result.contains("classname=\"res://test/resources/exporter_test_files/test_simple_2.gd\""))
|
||||
assert_string_contains(result, "classname=\"test/resources/exporter_test_files/test_simple_2.gd\"")
|
||||
|
||||
func test_write_file_creates_file():
|
||||
await run_scripts(_test_gut, 'test_simple_2.gd')
|
||||
var fname = "user://test_junit_exporter.xml"
|
||||
var re = JunitExporter.new()
|
||||
re.write_file(_test_gut, fname)
|
||||
assert_file_not_empty(fname)
|
||||
gut.file_delete(fname)
|
||||
|
||||
func test_xml_is_valid_when_test_skip_message_is_null():
|
||||
await run_scripts(_test_gut, ['test_special_chars_in_test_output.gd'])
|
||||
var re = JunitExporter.new()
|
||||
var result = re.get_results_xml(_test_gut)
|
||||
assert_is_valid_xml(result)
|
||||
1
addons/gut/test/integration/test_junit_xml_export.gd.uid
Normal file
1
addons/gut/test/integration/test_junit_xml_export.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dul1tj2lxkeev
|
||||
191
addons/gut/test/integration/test_more_input_ideas.gd
Normal file
191
addons/gut/test/integration/test_more_input_ideas.gd
Normal file
@@ -0,0 +1,191 @@
|
||||
extends GutTest
|
||||
|
||||
class SuperButton:
|
||||
extends Button
|
||||
|
||||
func p(s1='', s2='', s3='', s4='', s5='', s6=''):
|
||||
print(s1, s2, s3, s4, s5, s6)
|
||||
|
||||
func pevent(txt, event):
|
||||
return
|
||||
print(txt, ': ', event)
|
||||
# if(event is InputEventMouse):
|
||||
# print(txt, ': ', event.position, event.global_position)
|
||||
# else:
|
||||
# print(txt, ': ', event)
|
||||
|
||||
func _gui_input(event):
|
||||
pevent('gui: ', event)
|
||||
|
||||
func _input(event):
|
||||
pevent('input: ', event)
|
||||
|
||||
func _unhandled_input(event):
|
||||
pevent('unhandled: ', event)
|
||||
|
||||
|
||||
class DraggableButton:
|
||||
extends SuperButton
|
||||
|
||||
var _mouse_down = false
|
||||
|
||||
func _gui_input(event):
|
||||
super._gui_input(event)
|
||||
if(event is InputEventMouseButton):
|
||||
_mouse_down = event.pressed
|
||||
elif(event is InputEventMouseMotion and _mouse_down):
|
||||
position += event.relative
|
||||
|
||||
func should_skip_script():
|
||||
return 'takes too long and these shouldnt even be here'
|
||||
|
||||
|
||||
func _print_emitted_signals(thing):
|
||||
_signal_watcher.print_signal_summary(thing)
|
||||
return
|
||||
|
||||
|
||||
func test_draw_mouse():
|
||||
var sender = InputSender.new(Input)
|
||||
sender.mouse_warp = false
|
||||
sender.draw_mouse = true
|
||||
var pos = Vector2(200, 200)
|
||||
sender\
|
||||
.mouse_left_button_down(pos)\
|
||||
.wait(1)\
|
||||
.mouse_left_button_up()\
|
||||
.mouse_right_button_down()\
|
||||
.wait(1)\
|
||||
.mouse_right_button_up()\
|
||||
.mouse_relative_motion(Vector2(10, 10)).wait(.5)\
|
||||
.mouse_relative_motion(Vector2(10, 10)).wait(.5)\
|
||||
.mouse_left_button_down().hold_for(.5)\
|
||||
.mouse_relative_motion(Vector2(10, 10)).wait(.5)\
|
||||
.mouse_relative_motion(Vector2(10, 10)).wait(.5)\
|
||||
.mouse_right_button_down().hold_for(.5)\
|
||||
.mouse_relative_motion(Vector2(10, 10)).wait(.5)\
|
||||
.mouse_left_button_down()\
|
||||
.mouse_right_button_down()\
|
||||
.wait(2)
|
||||
|
||||
await sender.idle
|
||||
|
||||
|
||||
func test_drag_something():
|
||||
var btn = DraggableButton.new()
|
||||
watch_signals(btn)
|
||||
btn.size = Vector2(100, 100)
|
||||
btn.position = Vector2(50, 50)
|
||||
add_child_autofree(btn)
|
||||
|
||||
# works with Input and btn, btn does not fire signals, Input seems to be
|
||||
# having some trouble firigin the button up event.
|
||||
var sender = InputSender.new(Input)
|
||||
sender.set_auto_flush_input(true)
|
||||
sender.mouse_warp = false
|
||||
sender.draw_mouse = true
|
||||
|
||||
sender.mouse_left_button_down(btn.position + Vector2(10, 10)).wait(.1)
|
||||
for i in range(10):
|
||||
await sender.mouse_relative_motion(Vector2(10, 10)).wait(.1).idle
|
||||
print('-- ', btn.position, ' --')
|
||||
|
||||
assert_true(Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT), 'left button is down')
|
||||
await sender\
|
||||
.mouse_left_button_up()\
|
||||
.wait('1f')\
|
||||
.mouse_relative_motion(Vector2(1, 1))\
|
||||
.wait(.2).idle
|
||||
|
||||
assert_false(Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT), 'left button is up')
|
||||
var after_first_drag_pos = btn.position
|
||||
# drag again after mouse up which shouldn't move
|
||||
for i in range(10):
|
||||
await sender.mouse_relative_motion(Vector2(10, 10)).wait(.1).idle
|
||||
print('-- ', btn.position, ' --')
|
||||
|
||||
_print_emitted_signals(btn)
|
||||
|
||||
assert_signal_emitted(btn, 'button_down')
|
||||
assert_signal_emitted(btn, 'button_up')
|
||||
assert_ne(btn.position, Vector2(50, 50), 'has moved')
|
||||
assert_false(btn._mouse_down, 'button mouse down')
|
||||
assert_eq(btn.position, after_first_drag_pos, 'does not move after releasing button')
|
||||
|
||||
|
||||
|
||||
# 50 ->| |<- 150
|
||||
func test_clicking_things_with_input_as_receiver():
|
||||
var btn = SuperButton.new()
|
||||
watch_signals(btn)
|
||||
btn.size = Vector2(100, 100)
|
||||
btn.position = Vector2(50, 50)
|
||||
add_child_autofree(btn)
|
||||
|
||||
var sender = InputSender.new(Input)
|
||||
sender.mouse_warp = true
|
||||
|
||||
var start_pos = Vector2i(25, 75)
|
||||
for i in 15:
|
||||
var new_pos = start_pos + Vector2i(i * 10, 0)
|
||||
await sender.wait(.1)\
|
||||
.mouse_left_button_down(new_pos)\
|
||||
.hold_for(.1)\
|
||||
.wait(.1).idle
|
||||
|
||||
_print_emitted_signals(btn)
|
||||
assert_signal_emitted(btn, 'pressed')
|
||||
assert_signal_emitted(btn, 'button_down')
|
||||
assert_signal_emitted(btn, 'button_up')
|
||||
assert_signal_emitted(btn, 'gui_input')
|
||||
|
||||
|
||||
func test_clicking_two_buttons_triggers_focus_events():
|
||||
var btn = SuperButton.new()
|
||||
watch_signals(btn)
|
||||
btn.size = Vector2(100, 100)
|
||||
btn.position = Vector2(50, 50)
|
||||
add_child_autofree(btn)
|
||||
|
||||
var btn2 = SuperButton.new()
|
||||
watch_signals(btn2)
|
||||
btn2.size = Vector2(100, 100)
|
||||
btn2.position = Vector2(160, 50)
|
||||
add_child_autofree(btn2)
|
||||
|
||||
var sender = InputSender.new(Input)
|
||||
sender.mouse_warp = true
|
||||
|
||||
var start_pos = Vector2(100, 75)
|
||||
for i in 10:
|
||||
var new_pos = start_pos + Vector2(i * 10, 0)
|
||||
await sender.mouse_left_click_at(new_pos).idle
|
||||
|
||||
_print_emitted_signals(btn)
|
||||
_print_emitted_signals(btn2)
|
||||
|
||||
|
||||
|
||||
func test_clicking_things_with_button_as_receiver():
|
||||
var btn = SuperButton.new()
|
||||
watch_signals(btn)
|
||||
btn.size = Vector2(100, 100)
|
||||
btn.position = Vector2(50, 50)
|
||||
add_child_autofree(btn)
|
||||
|
||||
var sender = InputSender.new(btn)
|
||||
sender.mouse_warp = true
|
||||
|
||||
var start_pos = Vector2i(25, 75)
|
||||
for i in 15:
|
||||
var new_pos = start_pos + Vector2i(i * 10, 0)
|
||||
await sender.wait(.1)\
|
||||
.mouse_left_button_down(new_pos)\
|
||||
.hold_for(.1)\
|
||||
.wait(.1).idle
|
||||
|
||||
_print_emitted_signals(btn)
|
||||
assert_signal_not_emitted(btn, 'pressed')
|
||||
assert_signal_not_emitted(btn, 'button_down')
|
||||
assert_signal_not_emitted(btn, 'button_up')
|
||||
assert_signal_not_emitted(btn, 'gui_input')
|
||||
1
addons/gut/test/integration/test_more_input_ideas.gd.uid
Normal file
1
addons/gut/test/integration/test_more_input_ideas.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b2ppcuklb50i3
|
||||
@@ -0,0 +1,12 @@
|
||||
#A sample script for illustrating multiple scripts and what it looks like
|
||||
#when all tests pass.
|
||||
extends "res://addons/gut/test.gd"
|
||||
|
||||
func test_works():
|
||||
assert_true(true, 'This is true')
|
||||
|
||||
func test_two():
|
||||
assert_eq("two", "two", "This is also true")
|
||||
|
||||
func test_3():
|
||||
assert_ne("one", "two", "This is yet again true")
|
||||
@@ -0,0 +1 @@
|
||||
uid://cow6ssjc4kran
|
||||
12
addons/gut/test/integration/test_stub_in_before_each.gd
Normal file
12
addons/gut/test/integration/test_stub_in_before_each.gd
Normal file
@@ -0,0 +1,12 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
func before_each():
|
||||
stub(DoubleMe, 'get_value').to_return(999)
|
||||
|
||||
|
||||
func test_that_it_is_stubbed():
|
||||
var inst = double(DoubleMe).new()
|
||||
assert_eq(inst.get_value(), 999)
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://cagug263hk5yf
|
||||
71
addons/gut/test/integration/test_stubbing_accessors.gd
Normal file
71
addons/gut/test/integration/test_stubbing_accessors.gd
Normal file
@@ -0,0 +1,71 @@
|
||||
extends GutTest
|
||||
|
||||
var Stubber = load('res://addons/gut/stubber.gd')
|
||||
var Doubler = load('res://addons/gut/doubler.gd')
|
||||
var StubParams = load('res://addons/gut/stub_params.gd')
|
||||
|
||||
|
||||
class HasAccessors:
|
||||
var string_normal_accessors = 'default' :
|
||||
get: return string_normal_accessors
|
||||
set(val): string_normal_accessors = val
|
||||
|
||||
var string_accessor_method = 'default' :
|
||||
get = _get_string_accessor_method,
|
||||
set = _set_string_accessor_method
|
||||
|
||||
func _get_string_accessor_method():
|
||||
return string_accessor_method
|
||||
|
||||
func _set_string_accessor_method(val):
|
||||
string_accessor_method = val
|
||||
|
||||
func this_is_a_normal_method():
|
||||
print('you called this normal method')
|
||||
|
||||
|
||||
var doubler = null
|
||||
var stubber = null
|
||||
|
||||
|
||||
func before_each():
|
||||
doubler = Doubler.new(GutUtils.DOUBLE_STRATEGY.INCLUDE_NATIVE)
|
||||
# doubler.print_source = true
|
||||
doubler.inner_class_registry.register(self.get_script())
|
||||
stubber = GutUtils.Stubber.new()
|
||||
doubler.set_stubber(stubber)
|
||||
|
||||
|
||||
func test_can_double_scripts_with_accessors():
|
||||
var DoubleHasAccessors = doubler.double(HasAccessors)
|
||||
var inst = DoubleHasAccessors.new()
|
||||
assert_not_null(inst)
|
||||
|
||||
func test_normal_get_accessor_not_stubbed():
|
||||
var DoubleHasAccessors = doubler.double(HasAccessors)
|
||||
var dbl_ha = DoubleHasAccessors.new()
|
||||
assert_eq(dbl_ha.string_normal_accessors, 'default')
|
||||
|
||||
func test_normal_set_accessor_not_stubbed():
|
||||
var DoubleHasAccessors = doubler.double(HasAccessors)
|
||||
var dbl_ha = DoubleHasAccessors.new()
|
||||
dbl_ha.string_normal_accessors = 'foo'
|
||||
assert_eq(dbl_ha.string_normal_accessors, 'foo')
|
||||
|
||||
func test_get_accessor_method_is_stubbed_to_do_nothing():
|
||||
var dbl_ha = doubler.double(HasAccessors).new()
|
||||
assert_null(dbl_ha.string_accessor_method)
|
||||
|
||||
func test_set_accessor_method_is_stubbed_to_do_nothing():
|
||||
var dbl_ha = doubler.double(HasAccessors).new()
|
||||
var sp1 = StubParams.new(dbl_ha, '_get_string_accessor_method').to_call_super()
|
||||
stubber.add_stub(sp1)
|
||||
dbl_ha.string_accessor_method = 'bar'
|
||||
assert_eq(dbl_ha.string_accessor_method, 'default')
|
||||
|
||||
func test_partial_double_works():
|
||||
var dbl_ha = doubler.partial_double(HasAccessors).new()
|
||||
dbl_ha.string_normal_accessors = 'foo'
|
||||
dbl_ha.string_accessor_method = 'bar'
|
||||
assert_eq(dbl_ha.string_normal_accessors, 'foo')
|
||||
assert_eq(dbl_ha.string_accessor_method, 'bar')
|
||||
@@ -0,0 +1 @@
|
||||
uid://bhdwm7ifmk0at
|
||||
289
addons/gut/test/integration/test_test_and_orphans.gd
Normal file
289
addons/gut/test/integration/test_test_and_orphans.gd
Normal file
@@ -0,0 +1,289 @@
|
||||
extends GutInternalTester
|
||||
|
||||
var _gut = null
|
||||
var _base_src = """
|
||||
func make_node(node_name):
|
||||
var n = Node.new()
|
||||
n.name = node_name
|
||||
return n
|
||||
"""
|
||||
|
||||
func before_all():
|
||||
verbose = false
|
||||
|
||||
|
||||
func before_each():
|
||||
_gut = add_child_autofree(new_gut(verbose))
|
||||
var l = _gut.get_logger()
|
||||
l.set_type_enabled(l.types.orphan, verbose)
|
||||
if(!verbose):
|
||||
_gut.log_level = 0
|
||||
|
||||
|
||||
func _free_orphans():
|
||||
var ids = Node.get_orphan_node_ids()
|
||||
for id in ids:
|
||||
if(is_instance_id_valid(id)):
|
||||
var n = instance_from_id(id)
|
||||
n.free()
|
||||
|
||||
|
||||
func _run_test_script_source(src, g):
|
||||
var s = autofree(DynamicGutTest.new())
|
||||
s.add_source(_base_src)
|
||||
s.add_source(src)
|
||||
return await s.run_tests_in_gut_await(g)
|
||||
|
||||
|
||||
func assert_total_orphans_recorded(g, count):
|
||||
var oc = g.get_orphan_counter()
|
||||
var ids = oc.get_orphan_ids()
|
||||
assert_eq(ids.size(), count, "Recorded orphan count")
|
||||
|
||||
|
||||
func assert_total_fail_pass(totals, fail_count, pass_count):
|
||||
assert_eq(totals.failing, fail_count, 'Expected fail count')
|
||||
assert_eq(totals.passing, pass_count, 'Expected pass count')
|
||||
|
||||
|
||||
# --------------------------
|
||||
# Test related counts
|
||||
# --------------------------
|
||||
func test_orphans_made_in_test_cause_failure():
|
||||
var src = """
|
||||
func test_the_test():
|
||||
var n = make_node('test_the_test')
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 0)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_script_level_orphans_do_not_appear_as_test_orphans():
|
||||
var src = """
|
||||
var n = make_node('script_level')
|
||||
|
||||
func test_the_test():
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 0, 1)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_orphans_are_not_counted_twice_in_a_test():
|
||||
var src = """
|
||||
func test_the_test():
|
||||
make_node('made_an_orphan')
|
||||
assert_no_new_orphans()
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_orphans_no_orphans_then_orphans_again_in_a_test():
|
||||
var src = """
|
||||
func test_the_test():
|
||||
make_node('made_an_orphan')
|
||||
assert_no_new_orphans()
|
||||
|
||||
assert_no_new_orphans()
|
||||
|
||||
make_node('made_an_orphan')
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 2, 1)
|
||||
assert_total_orphans_recorded(_gut, 2)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
# --------------------------
|
||||
# after_all
|
||||
# --------------------------
|
||||
func test_checking_for_orphans_in_after_all_is_ok():
|
||||
var src = """
|
||||
func after_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 0, 2)
|
||||
|
||||
|
||||
func test_orphans_made_after_test_found_in_after_all():
|
||||
var src = """
|
||||
func after_all():
|
||||
await wait_frames(10)
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
make_node.call_deferred('test_the_test')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 0)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_orphans_made_in_after_all_are_found_in_after_all():
|
||||
var src = """
|
||||
func after_all():
|
||||
make_node('made_in_after_all')
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_non_asserted_orphans_are_found_in_after_all():
|
||||
var src = """
|
||||
func after_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
make_node('test_the_test')
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_asserted_orphans_are_found_in_after_all():
|
||||
var src = """
|
||||
func after_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
make_node('test_the_test')
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 2, 0)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_orphans_made_in_after_each_are_found_in_after_all():
|
||||
var src = """
|
||||
func after_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func after_each():
|
||||
make_node('test_the_test')
|
||||
|
||||
func test_the_test():
|
||||
make_node('test_the_test')
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 2)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_script_level_orphans_found_in_after_all():
|
||||
var src = """
|
||||
var n = make_node('script_level')
|
||||
|
||||
func after_all():
|
||||
assert_no_new_orphans('after_all')
|
||||
gut.get_orphan_counter().log_all()
|
||||
|
||||
func test_the_test():
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_orphans_no_orphans_then_orphans_again_in_a_test_then_after_all():
|
||||
var src = """
|
||||
func after_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
make_node('made_an_orphan')
|
||||
assert_no_new_orphans()
|
||||
|
||||
assert_no_new_orphans()
|
||||
|
||||
make_node('made_an_orphan')
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 3, 1)
|
||||
assert_total_orphans_recorded(_gut, 2)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
func test_freed_orphans_do_not_cause_failure_in_after_all():
|
||||
var src = """
|
||||
var n = null
|
||||
func after_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func after_each():
|
||||
n.free()
|
||||
|
||||
func test_the_test():
|
||||
n = make_node('made_an_orphan')
|
||||
assert_no_new_orphans()
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 0)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
# --------------------------
|
||||
# after_each
|
||||
# --------------------------
|
||||
func test_non_asserted_orphans_are_found_in_after_each():
|
||||
var src = """
|
||||
func after_each():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
make_node('test_the_test')
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
# --------------------------
|
||||
# before_all
|
||||
# --------------------------
|
||||
func test_script_level_orphans_found_in_before_all():
|
||||
var src = """
|
||||
var n = make_node('script_level')
|
||||
|
||||
func before_all():
|
||||
assert_no_new_orphans()
|
||||
|
||||
func test_the_test():
|
||||
pass_test('this is passing')
|
||||
"""
|
||||
var t = await _run_test_script_source(src, _gut)
|
||||
assert_total_fail_pass(t, 1, 1)
|
||||
assert_total_orphans_recorded(_gut, 1)
|
||||
_free_orphans()
|
||||
|
||||
|
||||
1
addons/gut/test/integration/test_test_and_orphans.gd.uid
Normal file
1
addons/gut/test/integration/test_test_and_orphans.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d3f2kj612lc7p
|
||||
3
addons/gut/test/integration/test_test_gut_error_check.gd
Normal file
3
addons/gut/test/integration/test_test_gut_error_check.gd
Normal file
@@ -0,0 +1,3 @@
|
||||
extends GutInternalTester
|
||||
|
||||
# Spot check passing conditions for tests.
|
||||
@@ -0,0 +1 @@
|
||||
uid://ddfeny352aq4n
|
||||
576
addons/gut/test/integration/test_test_stubber_doubler.gd
Normal file
576
addons/gut/test/integration/test_test_stubber_doubler.gd
Normal file
@@ -0,0 +1,576 @@
|
||||
extends GutInternalTester
|
||||
|
||||
|
||||
class OverrideToString:
|
||||
extends Node
|
||||
|
||||
func _to_string() -> String:
|
||||
return "this has been overriden"
|
||||
|
||||
func foo():
|
||||
pass
|
||||
|
||||
|
||||
func before_all():
|
||||
register_inner_classes(get_script())
|
||||
|
||||
func test_doubling_class_that_overrides_to_string_does_not_error():
|
||||
var obj = double(OverrideToString).new()
|
||||
obj.foo()
|
||||
assert_engine_error_count(0)
|
||||
|
||||
func test_error_generated_when_attempting_to_stub_blacklisted_method():
|
||||
var obj = double(OverrideToString).new()
|
||||
stub(obj._to_string).to_return('hello')
|
||||
assert_tracked_gut_error()
|
||||
|
||||
|
||||
|
||||
|
||||
class TestDoubleCreation:
|
||||
extends GutInternalTester
|
||||
const TEMP_FILES = 'user://test_doubler_temp_file'
|
||||
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
_gut._should_print_versions = false
|
||||
|
||||
_test = new_wired_test(_gut)
|
||||
|
||||
add_child_autofree(_gut)
|
||||
add_child_autofree(_test)
|
||||
|
||||
func after_each():
|
||||
_gut.get_spy().clear()
|
||||
|
||||
func test_double_returns_a_class():
|
||||
var D = _test.double(DoubleMe)
|
||||
assert_ne(autofree(D.new()), null)
|
||||
|
||||
func test_double_sets_stubber_for_doubled_class():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
assert_eq(d.__gutdbl.stubber_ref.get_ref(), _gut.get_stubber())
|
||||
|
||||
func test_basic_double_and_stub():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(DOUBLE_ME_PATH, 'get_value').to_return(10)
|
||||
assert_eq(d.get_value(), 10)
|
||||
|
||||
func test_get_set_double_strat():
|
||||
assert_accessors(_test, 'double_strategy', _test.DOUBLE_STRATEGY.SCRIPT_ONLY, _test.DOUBLE_STRATEGY.INCLUDE_NATIVE)
|
||||
|
||||
func test_when_strategy_is_full_then_supers_are_spied():
|
||||
var doubled = _test.double(DoubleMe, _test.DOUBLE_STRATEGY.INCLUDE_NATIVE).new()
|
||||
autofree(doubled)
|
||||
doubled.is_blocking_signals()
|
||||
_test.assert_called(doubled, 'is_blocking_signals')
|
||||
assert_eq(_test.get_pass_count(), 1)
|
||||
|
||||
func test_when_strategy_is_partial_then_spying_on_non_overloaded_fails():
|
||||
var doubled = _test.double(DoubleMe, _test.DOUBLE_STRATEGY.SCRIPT_ONLY).new()
|
||||
autofree(doubled)
|
||||
doubled.is_blocking_signals()
|
||||
_test.assert_not_called(doubled, 'is_blocking_signals')
|
||||
assert_eq(_test.get_fail_count(), 1)
|
||||
|
||||
func test_can_override_strategy_when_doubling_scene():
|
||||
var doubled = _test.double(DoubleMeScene, _test.DOUBLE_STRATEGY.INCLUDE_NATIVE).instantiate()
|
||||
autofree(doubled)
|
||||
doubled.is_blocking_signals()
|
||||
_test.assert_called(doubled, 'is_blocking_signals')
|
||||
assert_eq(_test.get_pass_count(), 1)
|
||||
|
||||
func test_when_strategy_is_partial_then_spying_on_non_overloaded_fails_with_scenes():
|
||||
var doubled = _test.double(DoubleMeScene, _test.DOUBLE_STRATEGY.SCRIPT_ONLY).instantiate()
|
||||
autofree(doubled)
|
||||
doubled.is_blocking_signals()
|
||||
_test.assert_not_called(doubled, 'is_blocking_signals')
|
||||
assert_eq(_test.get_fail_count(), 1)
|
||||
|
||||
func test_can_stub_inner_class_methods():
|
||||
_gut.get_doubler().inner_class_registry.register(InnerClasses)
|
||||
var d = _gut.get_doubler().double(InnerClasses.InnerA).new()
|
||||
_test.stub(InnerClasses.InnerA, 'get_a').to_return(10)
|
||||
assert_eq(d.get_a(), 10)
|
||||
|
||||
func test_can_stub_multiple_inner_classes():
|
||||
_gut.get_doubler().inner_class_registry.register(InnerClasses)
|
||||
var a = _gut.get_doubler().double(InnerClasses.InnerA).new()
|
||||
var anotherA = _gut.get_doubler().double(InnerClasses.AnotherInnerA).new()
|
||||
_test.stub(a, 'get_a').to_return(10)
|
||||
_test.stub(anotherA, 'get_a').to_return(20)
|
||||
assert_eq(a.get_a(), 10)
|
||||
assert_eq(anotherA.get_a(), 20)
|
||||
|
||||
func test_can_stub_multiple_inners_using_class_path_and_inner_names():
|
||||
_test.register_inner_classes(InnerClasses)
|
||||
|
||||
var inner_a = _gut.get_doubler().double(InnerClasses.InnerA).new()
|
||||
var another_a = _gut.get_doubler().double(InnerClasses.AnotherInnerA).new()
|
||||
_test.stub(InnerClasses.InnerA, 'get_a').to_return(10)
|
||||
assert_eq(inner_a.get_a(), 10, 'InnerA should be stubbed')
|
||||
assert_eq(another_a.get_a(), null, 'AnotherA should NOT be stubbed')
|
||||
if(is_failing()):
|
||||
gut.p(_gut.get_stubber().to_s())
|
||||
|
||||
func test_when_stub_passed_a_non_doubled_instance_it_generates_an_error():
|
||||
var n = autofree(Node.new())
|
||||
_test.stub(n, 'something').to_return(3)
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
func test_when_stub_passed_singleton_it_generates_error():
|
||||
_test.stub(Input, "is_action_just_pressed").to_return(true)
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
func test_can_stub_scenes():
|
||||
var dbl_scn = _test.double(DoubleMeScene).instantiate()
|
||||
autofree(dbl_scn)
|
||||
_test.stub(dbl_scn, 'return_hello').to_return('world')
|
||||
assert_eq(dbl_scn.return_hello(), 'world')
|
||||
|
||||
|
||||
class TestSingletonDoubling:
|
||||
extends GutInternalTester
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
_test = new_wired_test(_gut)
|
||||
|
||||
add_child_autofree(_gut)
|
||||
add_child_autofree(_test)
|
||||
|
||||
func test_double_singlton_creates_something_you_can_instantiate():
|
||||
var D = _test.double_singleton(ResourceSaver)
|
||||
var inst = D.new()
|
||||
assert_not_null(inst)
|
||||
|
||||
func test_partial_double_singlton_creates_something_you_can_instantiate():
|
||||
var D = _test.partial_double_singleton(NativeMenu)
|
||||
var inst = D.new()
|
||||
assert_not_null(inst)
|
||||
|
||||
func test_partial_double_singleton_returns_partial_double():
|
||||
var D = _test.partial_double_singleton(NativeMenu)
|
||||
var inst = D.new()
|
||||
assert_true(inst.__gutdbl_values.is_partial)
|
||||
|
||||
func test_double_singleton_errors_when_not_in_whitelist():
|
||||
var D = _test.double_singleton(GutTest)
|
||||
assert_tracked_gut_error_text(_gut, "Use double")
|
||||
assert_null(D)
|
||||
|
||||
func test_partial_double_singleton_errors_when_not_in_whitelist():
|
||||
var D = _test.partial_double_singleton(GutTest)
|
||||
assert_tracked_gut_error_text(_gut, "Use partial_double")
|
||||
assert_null(D)
|
||||
|
||||
func test_double_errors_when_class_in_singleton_whitelist():
|
||||
var D = _test.double(OS)
|
||||
assert_tracked_gut_error_text(_gut, 'Use double_singleton')
|
||||
assert_null(D)
|
||||
|
||||
func test_partial_double_errors_when_class_in_singleton_whitelist():
|
||||
var D = _test.partial_double(Time)
|
||||
assert_tracked_gut_error_text(_gut, 'Use partial_double_singleton')
|
||||
assert_null(D)
|
||||
|
||||
func test_can_stub_double_based_on_parameters():
|
||||
var dbl_time = _test.double_singleton(Time).new()
|
||||
_test.stub(dbl_time.get_time_string_from_unix_time.bind(1))\
|
||||
.to_return("one")
|
||||
_test.stub(dbl_time.get_time_string_from_unix_time.bind(2))\
|
||||
.to_return("two")
|
||||
|
||||
assert_eq(dbl_time.get_time_string_from_unix_time(1), "one")
|
||||
assert_eq(dbl_time.get_time_string_from_unix_time(2), "two")
|
||||
assert_null(dbl_time.get_time_string_from_unix_time(3), 'nonstubbed value returns null')
|
||||
|
||||
func test_do_not_have_to_specify_defaulted_vaules_for_stub_to_match():
|
||||
var dbl_input = _test.double_singleton(Input).new()
|
||||
_test.stub(dbl_input.is_action_just_pressed.bind("jump"))\
|
||||
.to_return(true)
|
||||
_test.assert_true(dbl_input.is_action_just_pressed("jump"))
|
||||
_test.assert_called(dbl_input.is_action_just_pressed.bind("jump", false))
|
||||
assert_pass(_test, 2)
|
||||
|
||||
func test_can_stub_methods_with_default_values():
|
||||
var dbl_input = _test.double_singleton(Input).new()
|
||||
_test.stub(dbl_input.is_action_just_pressed.bind("jump", false))\
|
||||
.to_return(true)
|
||||
assert_true(dbl_input.is_action_just_pressed("jump", false))
|
||||
_test.assert_called(dbl_input.is_action_just_pressed.bind("jump", false))
|
||||
assert_pass(_test)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestIgnoreMethodsWhenDoubling:
|
||||
extends GutInternalTester
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
_test = new_wired_test(_gut)
|
||||
|
||||
add_child_autofree(_gut)
|
||||
add_child_autofree(_test)
|
||||
|
||||
func test_sends_loaded_script_to_the_doubler():
|
||||
var m_doubler = double(GutUtils.Doubler).new()
|
||||
_gut._doubler = m_doubler
|
||||
_test.ignore_method_when_doubling(DoubleMe, 'two')
|
||||
assert_called(m_doubler, 'add_ignored_method', [DoubleMe, 'two'])
|
||||
|
||||
func test_sends_loaded_scene_to_the_doubler():
|
||||
var m_doubler = double(GutUtils.Doubler).new()
|
||||
_gut._doubler = m_doubler
|
||||
_test.ignore_method_when_doubling(DoubleMeScene, 'two')
|
||||
assert_called(m_doubler, 'add_ignored_method',
|
||||
[GutUtils.get_scene_script_object(DoubleMeScene), 'two'])
|
||||
|
||||
func test_when_ignoring_scene_methods_they_are_not_doubled():
|
||||
_test.ignore_method_when_doubling(DoubleMeScene, 'return_hello')
|
||||
var m_inst = _test.double(DoubleMeScene).instantiate()
|
||||
autofree(m_inst)
|
||||
m_inst.return_hello()
|
||||
# since it is ignored it should not have been caught by the stubber
|
||||
_test.assert_not_called(m_inst, 'return_hello')
|
||||
assert_eq(_test.get_fail_count(), 1)
|
||||
|
||||
func test_when_ignoring_sigleton_methods_they_do_not_exist_in_doubles():
|
||||
_test.ignore_method_when_doubling(Time, 'get_ticks_msec')
|
||||
var inst = _test.double_singleton(Time).new()
|
||||
assert_false(inst.has_method('get_ticks_msec'))
|
||||
|
||||
|
||||
class TestTestsSmartDoubleMethod:
|
||||
extends GutInternalTester
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
func before_all():
|
||||
_test = Test.new()
|
||||
_test.gut = gut
|
||||
_test.set_logger(gut.logger)
|
||||
|
||||
func after_all():
|
||||
_test.queue_free()
|
||||
|
||||
func after_each():
|
||||
gut.get_stubber().clear()
|
||||
|
||||
func test_when_passed_a_script_it_doubles_script():
|
||||
var inst = _test.double(DoubleMe).new()
|
||||
assert_eq(inst.__gutdbl.thepath, DOUBLE_ME_PATH)
|
||||
|
||||
func test_when_passed_a_scene_it_doubles_a_scene():
|
||||
var inst = _test.double(DoubleMeScene).instantiate()
|
||||
assert_eq(inst.__gutdbl.thepath, DOUBLE_ME_SCENE_PATH)
|
||||
|
||||
|
||||
func test_doulbing_inners_with_objects():
|
||||
_test.register_inner_classes(InnerClasses)
|
||||
var inst = _test.double(InnerClasses.InnerA).new()
|
||||
assert_eq(inst.__gutdbl.thepath, INNER_CLASSES_PATH, 'check path')
|
||||
assert_eq(inst.__gutdbl.subpath, 'InnerA', 'check subpath')
|
||||
|
||||
|
||||
func test_include_native_strategy_used_for_scripts():
|
||||
var inst = _test.double(DoubleMe, DOUBLE_STRATEGY.INCLUDE_NATIVE).new()
|
||||
inst.get_instance_id()
|
||||
assert_called(inst, 'get_instance_id')
|
||||
|
||||
func test_script_only_strategy_used_for_scripts():
|
||||
var inst = _test.double(DoubleMe, DOUBLE_STRATEGY.SCRIPT_ONLY).new()
|
||||
assert_does_not_have(inst.__gutdbl_values.doubled_methods, 'get_instance_id')
|
||||
|
||||
func test_include_native_strategy_used_with_scenes():
|
||||
var inst = _test.double(DoubleMeScene, DOUBLE_STRATEGY.INCLUDE_NATIVE).instantiate()
|
||||
assert_has(inst.__gutdbl_values.doubled_methods, 'get_instance_id')
|
||||
|
||||
func test_script_ony_strategy_used_with_scenes():
|
||||
var inst = _test.double(DoubleMeScene, DOUBLE_STRATEGY.SCRIPT_ONLY).instantiate()
|
||||
assert_does_not_have(inst.__gutdbl_values.doubled_methods, 'get_instance_id')
|
||||
|
||||
func test_include_native_strategy_used_with_inners():
|
||||
_test.register_inner_classes(InnerClasses)
|
||||
var inst = _test.double(InnerClasses.InnerA, DOUBLE_STRATEGY.INCLUDE_NATIVE).new()
|
||||
assert_has(inst.__gutdbl_values.doubled_methods, 'get_instance_id')
|
||||
|
||||
func test_script_only_strategy_used_with_inners():
|
||||
_test.register_inner_classes(InnerClasses)
|
||||
var inst = _test.double(InnerClasses.InnerA, DOUBLE_STRATEGY.SCRIPT_ONLY).new()
|
||||
assert_does_not_have(inst.__gutdbl_values.doubled_methods, 'get_instance_id')
|
||||
|
||||
func test_when_passing_a_class_of_a_script_it_doubles_it():
|
||||
var inst = _test.double(DoubleMe).new()
|
||||
assert_eq(inst.__gutdbl.thepath, DOUBLE_ME_PATH)
|
||||
|
||||
func test_when_passing_a_class_of_a_scene_it_doubles_it():
|
||||
var inst = _test.double(DoubleMeScene).instantiate()
|
||||
assert_eq(inst.__gutdbl.thepath, DOUBLE_ME_SCENE_PATH)
|
||||
|
||||
func test_can_double_native_classes():
|
||||
var inst = _test.double(Node2D).new()
|
||||
assert_not_null(inst)
|
||||
|
||||
func test_doubled_natives_call_super_by_default():
|
||||
var inst = _test.double(Node2D).new()
|
||||
assert_not_null(inst.get_position())
|
||||
|
||||
func test_when_an_instance_is_passed_null_is_returned_and_an_error_is_generated():
|
||||
var inst = autofree(Node2D.new())
|
||||
var d = _test.double(inst)
|
||||
assert_null(d, 'double is null')
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
|
||||
class TestPartialDoubleMethod:
|
||||
extends GutInternalTester
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
func before_all():
|
||||
_gut = new_gut(verbose)
|
||||
|
||||
_test = new_wired_test(_gut)
|
||||
|
||||
add_child(_gut)
|
||||
add_child(_test)
|
||||
|
||||
func after_each():
|
||||
_gut.get_stubber().clear()
|
||||
|
||||
func after_all():
|
||||
_gut.free()
|
||||
_test.free()
|
||||
|
||||
func test_partial_double_script():
|
||||
var inst = _test.partial_double(DoubleMe).new()
|
||||
autofree(inst)
|
||||
inst.set_value(10)
|
||||
assert_eq(inst.get_value(), 10)
|
||||
|
||||
func test_partial_double_scene():
|
||||
var inst = _test.partial_double(DoubleMeScene).instantiate()
|
||||
autofree(inst)
|
||||
assert_eq(inst.return_hello(), 'hello', 'sometimes fails, should be fixed.')
|
||||
|
||||
func test_partial_double_inner():
|
||||
_test.register_inner_classes(InnerClasses)
|
||||
var inst = _test.partial_double(InnerClasses.InnerA).new()
|
||||
assert_eq(inst.get_a(), 'a')
|
||||
|
||||
func test_double_script_not_a_partial():
|
||||
var inst = _test.double(DoubleMe).new()
|
||||
autofree(inst)
|
||||
inst.set_value(10)
|
||||
assert_eq(inst.get_value(), null)
|
||||
|
||||
func test_double_scene_not_a_partial():
|
||||
var inst = _test.double(DoubleMeScene).instantiate()
|
||||
autofree(inst)
|
||||
assert_eq(inst.return_hello(), null)
|
||||
|
||||
func test_double_inner_not_a_partial():
|
||||
_test.register_inner_classes(InnerClasses)
|
||||
var inst = _test.double(InnerClasses.InnerA).new()
|
||||
assert_eq(inst.get_a(), null)
|
||||
|
||||
func test_can_spy_on_partial_doubles():
|
||||
var pass_count = _test.get_pass_count()
|
||||
var inst = _test.partial_double(DoubleMe).new()
|
||||
autofree(inst)
|
||||
inst.set_value(10)
|
||||
_test.assert_called(inst, 'set_value')
|
||||
_test.assert_called(inst, 'set_value', [10])
|
||||
assert_eq(_test.get_pass_count(), pass_count + 2)
|
||||
|
||||
func test_can_stub_partial_doubled_native_class():
|
||||
var inst = _test.partial_double(Node2D).new()
|
||||
autofree(inst)
|
||||
_test.stub(inst, 'get_position').to_return(-1)
|
||||
assert_eq(inst.get_position(), -1)
|
||||
|
||||
func test_can_stub_partial_doubled_native_class_to_do_nothing_before_creating_double():
|
||||
_test.stub(Node2D, 'get_position').to_do_nothing()
|
||||
var inst = _test.partial_double(Node2D).new()
|
||||
autofree(inst)
|
||||
assert_eq(inst.get_position(), null)
|
||||
|
||||
func test_can_stub_partial_doubled_native_class_to_do_nothing_after_creating_double():
|
||||
var inst = _test.partial_double(Node2D).new()
|
||||
_test.stub(Node2D, 'get_position').to_do_nothing()
|
||||
autofree(inst)
|
||||
assert_eq(inst.get_position(), null)
|
||||
|
||||
func test_can_spy_on_partial_doubled_native_class():
|
||||
var pass_count = _test.get_pass_count()
|
||||
var inst = autofree(_test.partial_double(Node2D).new())
|
||||
inst.set_position(Vector2(100, 100))
|
||||
_test.assert_called(inst, 'set_position', [Vector2(100, 100)])
|
||||
assert_eq(_test.get_pass_count(), pass_count + 1, 'tests have passed')
|
||||
|
||||
func test_when_an_instance_is_passed_null_is_returned_and_an_error_is_generated():
|
||||
var inst = autofree(Node2D.new())
|
||||
var d = _test.partial_double(inst)
|
||||
assert_null(d, 'double is null')
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
func test_can_override_partial_double_stubs():
|
||||
var inst = _test.partial_double(DoubleMe).new()
|
||||
autofree(inst)
|
||||
_test.stub(DoubleMe, 'get_value').to_do_nothing()
|
||||
inst.set_value(10)
|
||||
assert_null(inst.get_value())
|
||||
|
||||
|
||||
class TestOverridingParameters:
|
||||
extends GutInternalTester
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
const INIT_PARAMETERS = 'res://test/resources/stub_test_objects/init_parameters.gd'
|
||||
const DEFAULT_PARAMS_PATH = 'res://test/resources/doubler_test_objects/double_default_parameters.gd'
|
||||
var DefaultParams = null
|
||||
|
||||
func before_all():
|
||||
var were_set = GutUtils.WarningsManager.are_warnings_enabled()
|
||||
GutUtils.WarningsManager.enable_warnings(false)
|
||||
DefaultParams = load(DEFAULT_PARAMS_PATH)
|
||||
GutUtils.WarningsManager.enable_warnings(were_set)
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
|
||||
_test = new_wired_test(_gut)
|
||||
|
||||
add_child(_gut)
|
||||
add_child(_test)
|
||||
|
||||
func after_each():
|
||||
_gut.free()
|
||||
_test.free()
|
||||
|
||||
|
||||
# -------------------
|
||||
# Default parameters and override parameter count
|
||||
func test_can_stub_default_values():
|
||||
var TestClass = load(DEFAULT_PARAMS_PATH)
|
||||
|
||||
var s = _test.stub(TestClass, 'return_passed').to_call_super()
|
||||
s.param_defaults(['1', '2'])
|
||||
|
||||
var inst = _test.double(DefaultParams).new()
|
||||
var ret_val = inst.return_passed()
|
||||
assert_eq(ret_val, '12')
|
||||
|
||||
func test_vararg_methods_get_extra_parameters_by_default():
|
||||
_test.stub(Node, 'rpc_id').to_do_nothing()
|
||||
var inst = _test.double(Node).new()
|
||||
add_child_autofree(inst)
|
||||
var ret_val = inst.rpc_id(1, 'foo', '3', '4', '5')
|
||||
pass_test('we got here')
|
||||
|
||||
func test_issue_246_rpc_id_varargs():
|
||||
var inst = _test.double(Node).new()
|
||||
_test.stub(Node, 'rpc_id').to_do_nothing()
|
||||
add_child_autofree(inst)
|
||||
inst.rpc_id(1, 'foo', '3', '4', '5')
|
||||
_test.assert_called(inst, 'rpc_id', [1, 'foo', ['3', '4', '5']])
|
||||
assert_eq(_test.get_pass_count(), 1)
|
||||
|
||||
func test_issue_246_rpc_id_varargs2():
|
||||
stub(Node, 'rpc_id').to_do_nothing()
|
||||
var inst = double(Node).new()
|
||||
add_child_autofree(inst)
|
||||
inst.rpc_id(1, 'foo', '3', '4', '5')
|
||||
assert_called(inst, 'rpc_id', [1, 'foo', ['3', '4', '5']])
|
||||
|
||||
func test_double_can_have_default_param_values_stubbed_using_class():
|
||||
var InitParams = load(INIT_PARAMETERS)
|
||||
_test.stub(InitParams, '_init').param_defaults(["override_default"])
|
||||
var inst = _test.double(InitParams).new()
|
||||
assert_eq(inst.value, 'override_default')
|
||||
|
||||
|
||||
class TestStub:
|
||||
extends GutInternalTester
|
||||
var _gut = null
|
||||
var _test = null
|
||||
|
||||
|
||||
func before_each():
|
||||
_gut = new_gut(verbose)
|
||||
|
||||
_test = new_wired_test(_gut)
|
||||
_test.ignore_method_when_doubling(DoubleMe, '_notification')
|
||||
|
||||
add_child_autofree(_gut)
|
||||
add_child_autofree(_test)
|
||||
|
||||
|
||||
func after_each():
|
||||
_gut.get_stubber().clear()
|
||||
|
||||
|
||||
func test_stub_of_valid_stuff_is_fine():
|
||||
var dbl = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(dbl, 'get_value').to_return(9)
|
||||
assert_tracked_gut_error(_test, 0)
|
||||
|
||||
func test_stub_of_double_method_generates_error_when_method_does_not_exist():
|
||||
var dbl = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(dbl, 'foo').to_do_nothing()
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
func test_can_stub_double_method_using_callable():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(d.has_one_param).to_return(5)
|
||||
assert_eq(_gut.get_stubber().get_return(d, 'has_one_param'), 5)
|
||||
|
||||
func test_errors_on_p2_when_using_callable():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(d.has_one_param, 'asdf').to_return(5)
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
func test_errors_on_p3_when_using_callable():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(d.has_one_param, null, 'asdf').to_return(5)
|
||||
assert_tracked_gut_error(_test)
|
||||
|
||||
func test_bound_parameters_are_not_spied_on():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
var callable = func(_value, p2):
|
||||
return p2
|
||||
_test.stub(d.has_one_param).to_call(callable.bind("p2"))
|
||||
d.has_one_param("value")
|
||||
_test.assert_not_called(d, "has_one_param", ["value", "p2"])
|
||||
_test.assert_called(d, "has_one_param", ["value"])
|
||||
assert_pass(_test, 2)
|
||||
|
||||
func test_setting_local_variable_in_callable():
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
var this_var = "some value"
|
||||
_test.stub(d.has_one_param).to_call(
|
||||
func(_value):
|
||||
this_var = "another value"
|
||||
return this_var)
|
||||
var result = d.has_one_param("asdf")
|
||||
_test.assert_eq(result, "another value", "Seems reasonable")
|
||||
_test.assert_ne(result, this_var, "Why would this pass?")
|
||||
_test.assert_eq(this_var, "some value", "Ohhh, well ok.")
|
||||
assert_pass(_test, 3)
|
||||
|
||||
func test_get_error_messages_when_using_callables():
|
||||
_test.ignore_method_when_doubling(DoubleMe, "has_one_param")
|
||||
var d = autofree(_test.double(DoubleMe).new())
|
||||
_test.stub(d.has_one_param).to_return(5)
|
||||
assert_tracked_gut_error(_test)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cx61yixf4sd1s
|
||||
@@ -0,0 +1,4 @@
|
||||
extends "res://addons/gut/test.gd"
|
||||
|
||||
func test_nothing():
|
||||
pass_test('do not need a test, but felt weird to not have one.')
|
||||
@@ -0,0 +1 @@
|
||||
uid://dhbs1hnc7hfqg
|
||||
31
addons/gut/test/integration/test_version_configuration.gd
Normal file
31
addons/gut/test/integration/test_version_configuration.gd
Normal file
@@ -0,0 +1,31 @@
|
||||
extends GutTest
|
||||
var UpdateDetector = GutUtils.UpdateDetector
|
||||
|
||||
var data = GutUtils.get_file_as_text('res://addons/gut/versions.json')
|
||||
var ud = null
|
||||
|
||||
func before_all():
|
||||
ud = UpdateDetector.new()
|
||||
add_child(ud)
|
||||
|
||||
|
||||
func after_all():
|
||||
ud.free()
|
||||
|
||||
|
||||
func test_local_versions_file_is_valid():
|
||||
ud.parse_file(ud.LOCAL_FILE_PATH)
|
||||
assert_eq(ud.data_issues.size(), 0, "no data issues")
|
||||
if(is_failing()):
|
||||
gut.p(str("Issues:\n", ud.data_issues))
|
||||
assert_has(ud.parsed_data.releases, GutUtils.version_numbers.gut_version,
|
||||
"current version exists")
|
||||
|
||||
|
||||
func test_parsing_remote_data():
|
||||
var error = ud.fetch_remote_file()
|
||||
if(error == OK):
|
||||
await wait_for_signal(ud.download_completed, 5)
|
||||
assert_has(ud.parsed_data, 'releases')
|
||||
else:
|
||||
fail_test("There was an error starting request")
|
||||
@@ -0,0 +1 @@
|
||||
uid://bk4enti2876q8
|
||||
Reference in New Issue
Block a user