Skip to content

Commit

Permalink
chore(simulate): apply PR #409 to godot_4 branch (#499)
Browse files Browse the repository at this point in the history
  • Loading branch information
coffeebeats authored Jul 15, 2023
1 parent 770c404 commit 01d233f
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 44 deletions.
32 changes: 25 additions & 7 deletions addons/gut/gut_to_move.gd
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,34 @@ func file_touch(path):
FileAccess.open(path, FileAccess.WRITE)

# ------------------------------------------------------------------------------
# Call _process or _fixed_process, if they exist, on obj and all it's children
# and their children and so and so forth. Delta will be passed through to all
# the _process or _fixed_process methods.
# Simulate a number of frames by calling '_process' and '_physics_process' (if
# the methods exist) on an object and all of its descendents. The specified frame
# time, 'delta', will be passed to each simulated call.
#
# NOTE: Objects can disable their processing methods using 'set_process(false)' and
# 'set_physics_process(false)'. This is reflected in the 'Object' methods
# 'is_processing()' and 'is_physics_processing()', respectively. To make 'simulate'
# respect this status, for example if you are testing an object which toggles
# processing, pass 'check_is_processing' as 'true'.
# ------------------------------------------------------------------------------
func simulate(obj, times, delta):
func simulate(obj, times, delta, check_is_processing: bool = false):
for _i in range(times):
if(obj.has_method("_process")):
if (
obj.has_method("_process")
and (
not check_is_processing
or obj.is_processing()
)
):
obj._process(delta)
if(obj.has_method("_physics_process")):
if(
obj.has_method("_physics_process")
and (
not check_is_processing
or obj.is_physics_processing()
)
):
obj._physics_process(delta)

for kid in obj.get_children():
simulate(kid, 1, delta)
simulate(kid, 1, delta, check_is_processing)
4 changes: 2 additions & 2 deletions addons/gut/test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1358,8 +1358,8 @@ func stub(thing, p2, p3=null):
# ------------------------------------------------------------------------------
# convenience wrapper.
# ------------------------------------------------------------------------------
func simulate(obj, times, delta):
gut.simulate(obj, times, delta)
func simulate(obj, times, delta, check_is_processing: bool = false):
gut.simulate(obj, times, delta, check_is_processing)

# ------------------------------------------------------------------------------
# Replace the node at base_node.get_node(path) with with_this. All references
Expand Down
201 changes: 166 additions & 35 deletions test/unit/test_gut.gd
Original file line number Diff line number Diff line change
Expand Up @@ -89,58 +89,189 @@ class TestSimulate:
func before_each():
_test_gut = autofree(new_gut())

class HasProcessMethod:
class WithoutProcess:
extends Node
var process_called_count = 0

class WithProcess:
extends Node
var call_count = 0
var delta_sum = 0.0

func _process(delta):
process_called_count += 1
call_count += 1
delta_sum += delta

class HasPhysicsProcessMethod:
class WithoutPhysicsProcess:
extends Node

class WithPhysicsProcess:
extends Node
var physics_process_called_count = 0
var call_count = 0
var delta_sum = 0.0

func _physics_process(delta):
physics_process_called_count += 1
call_count += 1
delta_sum += delta

func test_simulate_calls_process():
var obj = autofree(HasProcessMethod.new())
_test_gut.simulate(obj, 10, .1)
assert_eq(obj.process_called_count, 10, "_process should have been called 10 times")
# using just the numbers didn't work, nor using float. str worked for some reason and
# i'm not sure why.
assert_eq(str(obj.delta_sum), str(1), "The delta value should have been passed in and summed")

func test_simulate_calls_process_on_child_objects():
var parent = autofree(HasProcessMethod.new())
var child = autofree(HasProcessMethod.new())
parent.add_child(child)
_test_gut.simulate(parent, 10, .1)
assert_eq(child.process_called_count, 10, "_process should have been called on the child object too")

func test_simulate_calls_process_if_object_has_method():
var with_method = autofree(WithProcess.new())
_test_gut.simulate(with_method, 5, 0.2)
assert_eq(with_method.call_count, 5, '_process should have been called 5 times')
assert_eq(with_method.delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_does_not_error_when_object_does_not_have_process():
var without_method = autofree(WithoutProcess.new())
_test_gut.simulate(without_method, 5, 0.2)
pass_test('We got here')

func test_simulate_calls_process_on_child_objects_of_child_objects():
var objs = []
for i in range(5):
objs.append(autofree(HasProcessMethod.new()))
objs.append(autofree(WithProcess.new()))
if(i > 0):
objs[i - 1].add_child(objs[i])
_test_gut.simulate(objs[0], 5, 0.2)

_test_gut.simulate(objs[0], 10, .1)

for i in range(objs.size()):
assert_eq(objs[i].process_called_count, 10, "_process should have been called on object # " + str(i))

func test_simulate_calls_physics_process():
var obj = autofree(HasPhysicsProcessMethod.new())
_test_gut.simulate(obj, 10, .1)
assert_eq(obj.physics_process_called_count, 10, "_process should have been called 10 times")
# using just the numbers didn't work, nor using float. str worked for some reason and
# i'm not sure why.
assert_eq(str(obj.delta_sum), str(1), "The delta value should have been passed in and summed")
assert_eq(objs[i].call_count, 5, '_process should have been called on object # ' + str(i))
assert_eq(objs[i].delta_sum, 1, 'The delta value should have been summed on object # ' + str(i))

func test_simulate_checks_process_on_all_nodes():
var objs = [
autofree(WithProcess.new()),
autofree(WithoutProcess.new()),
autofree(WithProcess.new()),
autofree(WithoutProcess.new()),
]
for i in range(1, 4):
objs[i - 1].add_child(objs[i])

_test_gut.simulate(objs[0], 5, 0.2)

assert_eq(objs[0].call_count, 5, '_process should have been called 5 times')
assert_eq(objs[0].delta_sum, 1.0, 'The delta value should have been passed in and summed')
assert_eq(objs[2].call_count, 5, '_process should have been called 5 times')
assert_eq(objs[2].delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_calls_process_if_object_is_processing_and_check_is_true():
var with_processing = autofree(WithProcess.new())
with_processing.set_process(true)
_test_gut.simulate(with_processing, 5, 0.2, true) # check_is_processing=false
assert_eq(with_processing.call_count, 5, '_process should have been called 5 times')
assert_eq(with_processing.delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_does_not_call_process_if_object_is_not_processing_and_check_is_true():
var without_processing = autofree(WithProcess.new())
without_processing.set_process(false)
_test_gut.simulate(without_processing, 5, 0.2, true) # check_is_processing=true
assert_eq(without_processing.call_count, 0, '_process should not have been called')

func test_simulate_does_not_error_if_object_is_processing_but_has_no_method():
var with_processing_but_without_method = autofree(WithoutProcess.new())
with_processing_but_without_method.set_process(true)
_test_gut.simulate(with_processing_but_without_method, 5, 0.2, true) # check_is_processing=true
pass_test('We got here')

func test_simulate_calls_process_on_descendents_if_objects_are_processing():
var objs = [
autofree(WithProcess.new()),
autofree(WithoutProcess.new()),
autofree(WithProcess.new()),
autofree(WithoutProcess.new()),
]
for i in range(1, 4):
objs[i - 1].add_child(objs[i])

objs[0].set_process(false)
objs[1].set_process(false)
objs[2].set_process(true)
objs[3].set_process(true)

_test_gut.simulate(objs[0], 5, 0.2, true) # check_is_processing=true

assert_eq(objs[0].call_count, 0, '_process should not have been called')
assert_eq(objs[2].call_count, 5, '_process should have been called 5 times')
assert_eq(objs[2].delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_calls_physics_process_if_object_has_method():
var with_method = autofree(WithPhysicsProcess.new())
_test_gut.simulate(with_method, 5, 0.2)
assert_eq(with_method.call_count, 5, '_physics_process should have been called 5 times')
assert_eq(with_method.delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_does_not_error_when_object_does_not_have_physics_process():
var without_method = autofree(WithoutPhysicsProcess.new())
_test_gut.simulate(without_method, 5, 0.2)
pass_test('We got here')

func test_simulate_calls_physics_process_on_child_objects_of_child_objects():
var objs = []
for i in range(5):
objs.append(autofree(WithPhysicsProcess.new()))
if(i > 0):
objs[i - 1].add_child(objs[i])
_test_gut.simulate(objs[0], 5, 0.2)

for i in range(objs.size()):
assert_eq(objs[i].call_count, 5, '_physics_process should have been called on object # ' + str(i))
assert_eq(objs[i].delta_sum, 1, 'The delta value should have been summed on object # ' + str(i))

func test_simulate_calls_physics_process_on_descendents_if_objects_have_method():
var objs = [
autofree(WithPhysicsProcess.new()),
autofree(WithoutPhysicsProcess.new()),
autofree(WithPhysicsProcess.new()),
autofree(WithoutPhysicsProcess.new()),
]
for i in range(1, 4):
objs[i - 1].add_child(objs[i])

_test_gut.simulate(objs[0], 5, 0.2)

assert_eq(objs[0].call_count, 5, '_physics_process should have been called 5 times')
assert_eq(objs[0].delta_sum, 1.0, 'The delta value should have been passed in and summed')
assert_eq(objs[2].call_count, 5, '_physics_process should have been called 5 times')
assert_eq(objs[2].delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_calls_physics_process_if_object_is_processing_and_check_is_true():
var with_processing = autofree(WithPhysicsProcess.new())
with_processing.set_physics_process(true)
_test_gut.simulate(with_processing, 5, 0.2, true) # check_is_processing=false
assert_eq(with_processing.call_count, 5, '_physics_process should have been called 5 times')
assert_eq(with_processing.delta_sum, 1.0, 'The delta value should have been passed in and summed')

func test_simulate_does_not_call_physics_process_if_object_is_not_processing_and_check_is_true():
var without_processing = autofree(WithPhysicsProcess.new())
without_processing.set_physics_process(false)
_test_gut.simulate(without_processing, 5, 0.2, true) # check_is_processing=true
assert_eq(without_processing.call_count, 0, '_physics_process should not have been called')

func test_simulate_does_not_error_if_object_is_physics_processing_but_has_no_method():
var with_processing_but_without_method = autofree(WithoutPhysicsProcess.new())
with_processing_but_without_method.set_physics_process(true)
_test_gut.simulate(with_processing_but_without_method, 5, 0.2, true) # check_is_processing=true
pass_test('We got here')

func test_simulate_calls_physics_process_on_descendents_if_objects_are_processing():
var objs = [
autofree(WithPhysicsProcess.new()),
autofree(WithoutPhysicsProcess.new()),
autofree(WithPhysicsProcess.new()),
autofree(WithoutPhysicsProcess.new()),
]
for i in range(1, 4):
objs[i - 1].add_child(objs[i])

objs[0].set_physics_process(false)
objs[1].set_physics_process(false)
objs[2].set_physics_process(true)
objs[3].set_physics_process(true)

_test_gut.simulate(objs[0], 5, 0.2, true) # check_is_processing=true

assert_eq(objs[0].call_count, 0, '_physics_process should not have been called')
assert_eq(objs[2].call_count, 5, '_physics_process should have been called 5 times')
assert_eq(objs[2].delta_sum, 1.0, 'The delta value should have been passed in and summed')



Expand Down

0 comments on commit 01d233f

Please sign in to comment.