381 lines
13 KiB
GDScript3
381 lines
13 KiB
GDScript3
|
|
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)
|