Skip to content

Commit

Permalink
Fix issue #503 (#507)
Browse files Browse the repository at this point in the history
* fix #503, GUT now finds script property wherever it is on root node
* readme and comment corrections
  • Loading branch information
bitwes authored Jul 15, 2023
1 parent cb13a6f commit 770c404
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .gutconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"should_maximize": false,
"should_exit": true,
"ignore_pause": true,
"log_level": 1,
"log_level": 3,
"double_strategy": "INCLUDE_NATIVE",
"inner_class": "",
"disable_colors": false,
Expand Down
5 changes: 3 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).


# 9.1.0
# 9.1.0 (requires Godot 4.1)
* GUT generated errors now cause tests to fail (not engine errors, just things GUT thinks are bad). You can disable this through the CLI, .gutconfig, or the panel.
* Changes to Double Strategy and Double/Partial Double creation to fix #482.
* See [Double-Strategy](https://bitwes.github.io/GutWiki/Godot4/Double-Strategy.html) in the wiki for more information.
Expand All @@ -13,8 +13,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
* If you have an invalid Double Strategy set via command line or gutconfig, the default will be used. So if you are explicity setting it to the old `INCLUDE_SUPER`, it will use `SCRIPT_ONLY`.
* You can now set the default double strategy in the GutPanel in the Editor.
* Added `GutControl` to aid in running tests in a deployed game. Instructions and sample code can be found [in the wiki](https://bitwes.github.io/GutWiki/Godot4/Running-On-Devices.html).
* __Issue i485__ GUT prints a warning and ignores scripts that do not extend `GutTest`.
* __Issue 485__ GUT prints a warning and ignores scripts that do not extend `GutTest`.
* A lot of internal reworkings to simplify logging and info about test statuses. The summary changed and the final line printed by GUT is now the highest severity status of the run (i.e. failed > pending/risky > passed).
* __Issue 503__ Fixed issue where GUT would not find script object when doubling PackedScenes.


# 9.0.1
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Gut 9.0.0 (Godot 4.0)
# Gut 9.1.0 (Godot 4.1)
GUT (Godot Unit Test) is a unit testing framework for the [Godot Engine](https://godotengine.org/). It allows you to write tests for your gdscript in gdscript.

Version 9.0.0 is for Godot 4.0
Versions below 9.0.0 (currently 7.4.2) are for Godot 3.x
GUT versions 9.x are for Godot 4.x
GUT versions below 9.0.0 (currently 7.4.2) are for Godot 3.x

__NOTE__ The wiki for this version has moved to https://bitwes.github.io/GutWiki/Godot4/. It has not been fully updated yet. The Wiki source is now [located in the `godot_4` branch](https://github.com/bitwes/Gut/tree/godot_4/wiki) and Pull Requests are encouraged. See Wiki section in [GODOT_4_README.md](https://github.com/bitwes/Gut/blob/godot_4/GODOT_4_README.md) for details.

Expand Down
2 changes: 1 addition & 1 deletion addons/gut/doubler.gd
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func _double_scene_and_script(scene, strategy, partial):
var to_return = PackedSceneDouble.new()
to_return.load_scene(scene.get_path())

var script_obj = _utils.get_scene_script_object(scene)
var script_obj = GutUtils.get_scene_script_object(scene)
if(script_obj != null):
var script_dbl = null
if(partial):
Expand Down
8 changes: 4 additions & 4 deletions addons/gut/gui/GutSceneTheme.tres

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion addons/gut/test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,7 @@ func ignore_method_when_doubling(thing, method_name):

var r = thing
if(thing is PackedScene):
r = _utils.get_scene_script_object(thing)
r = GutUtils.get_scene_script_object(thing)

gut.get_doubler().add_ignored_method(r, method_name)

Expand Down
46 changes: 26 additions & 20 deletions addons/gut/utils.gd
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,31 @@ static func print_properties(props, thing, print_all_meta=false):
if(print_all_meta):
print(' ', props[i])



# ------------------------------------------------------------------------------
# Gets the value of the node_property 'script' from a PackedScene's root node.
# This does not assume the location of the root node in the PackedScene's node
# list. This also does not assume the index of the 'script' node property in
# a nodes's property list.
# ------------------------------------------------------------------------------
static func get_scene_script_object(scene):
var state = scene.get_state()
var to_return = null
var root_node_path = NodePath(".")
var node_idx = 0

while(node_idx < state.get_node_count() and to_return == null):
if(state.get_node_path(node_idx) == root_node_path):
for i in range(state.get_node_property_count(node_idx)):
if(state.get_node_property_name(node_idx, i) == 'script'):
to_return = state.get_node_property_value(node_idx, i)

node_idx += 1

return to_return


# ##############################################################################
# Start Class
# ##############################################################################
Expand Down Expand Up @@ -194,7 +219,7 @@ var GutScene = load('res://addons/gut/GutScene.tscn')
# Source of truth for the GUT version
var version = '9.0.1'
# The required Godot version as an array.
var req_godot = [4, 0, 0]
var req_godot = [4, 1, 0]

# These methods all call super implicitly. Stubbing them to call super causes
# super to be called twice.
Expand Down Expand Up @@ -524,24 +549,5 @@ func create_script_from_source(source, override_path=null):
return DynamicScript


func get_scene_script_object(scene):
var state = scene.get_state()
var to_return = null
var root_node_path = NodePath(".")
var node_idx = 0

while(node_idx < state.get_node_count() and to_return == null):
# Assumes that the first node we encounter that has a root node path, one
# property, and that property is named 'script' is the GDScript for the
# scene. This could be flawed.
if(state.get_node_path(node_idx) == root_node_path and state.get_node_property_count(node_idx) == 1):
if(state.get_node_property_name(node_idx, 0) == 'script'):
to_return = state.get_node_property_value(node_idx, 0)

node_idx += 1

return to_return


func get_display_size():
return get_viewport().get_visible_rect()
14 changes: 1 addition & 13 deletions scratch/get_info.gd
Original file line number Diff line number Diff line change
Expand Up @@ -376,19 +376,7 @@ func print_scene_info(scene):


func get_scene_script_object(scene):
var state = scene.get_state()
var to_return = null
var root_node_path = NodePath(".")
var node_idx = 0

while(node_idx < state.get_node_count() and to_return == null):
if(state.get_node_path(node_idx) == root_node_path and state.get_node_property_count(node_idx) == 1):
if(state.get_node_property_name(node_idx, 0) == 'script'):
to_return = state.get_node_property_value(node_idx, 0)

node_idx += 1

return to_return
return GutUtils.get_scene_script_object(scene)



Expand Down
7 changes: 6 additions & 1 deletion test/integration/test_test_stubber_doubler.gd
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class TestBasics:
gr.test.stub(Input, "is_action_just_pressed").to_return(true)
assert_eq(gr.test.get_logger().get_errors().size(), 1)

func test_can_stub_scenes():
var dbl_scn = gr.test.double(DoubleMeScene).instantiate()
gr.test.stub(dbl_scn, 'return_hello').to_return('world')
assert_eq(dbl_scn.return_hello(), 'world')




Expand Down Expand Up @@ -126,7 +131,7 @@ class TestIgnoreMethodsWhenDoubling:
_test_gut._doubler = m_doubler
_test.ignore_method_when_doubling(DoubleMeScene, 'two')
assert_called(m_doubler, 'add_ignored_method',
[_utils.get_scene_script_object(DoubleMeScene), 'two'])
[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')
Expand Down
79 changes: 78 additions & 1 deletion test/unit/test_utils.gd
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func test_is_instance_false_for_classes():

func test_is_instance_true_for_new():
var utils = autofree(Utils.new())
var n = Node.new()
var n = autofree(Node.new())
assert_true(utils.is_instance(n))

func test_is_instance_false_for_instanced_things():
Expand Down Expand Up @@ -83,6 +83,83 @@ func test_is_inner_class_false_for_non_objs():




class TestGetSceneScript:
extends 'res://addons/gut/test.gd'

class MockSceneState:
# ------------------------------
# Tools for faking out SceneState functionality
# ------------------------------
var nodes = []

func add_node(path):
var to_add = {
node_path = NodePath(path),
props = []
}
nodes.append(to_add)
return nodes.size() -1

func add_node_prop(index, name, value):
nodes[index].props.append({name = name, value = value})

# ------------------------------
# Mocked SceneState methods
# ------------------------------
func get_node_count():
return nodes.size()

func get_node_path(index):
return nodes[index].node_path

func get_node_property_name(index, prop_index):
return nodes[index].props[prop_index].name

func get_node_property_value(index, prop_index):
return nodes[index].props[prop_index].value

func get_node_property_count(index):
return nodes[index].props.size()


class MockScene:
var state = MockSceneState.new()
func get_state():
return state


func test_gets_scene_script_when_script_is_first_property():
var mock_scene = MockScene.new()
mock_scene.state.add_node('.')
mock_scene.state.add_node_prop(0, 'script', 'foo')
var result = GutUtils.get_scene_script_object(mock_scene)
assert_eq(result, 'foo')

func test_gets_scene_script_when_script_is_second_property():
var mock_scene = MockScene.new()
mock_scene.state.add_node('.')
mock_scene.state.add_node_prop(0, 'something', 'else')
mock_scene.state.add_node_prop(0, 'script', 'foo')
var result = GutUtils.get_scene_script_object(mock_scene)
assert_eq(result, 'foo')

func test_gets_scene_script_when_root_node_is_not_first_node():
var mock_scene = MockScene.new()
mock_scene.state.add_node('/some/path')

mock_scene.state.add_node('.')
mock_scene.state.add_node_prop(1, 'something', 'else')
mock_scene.state.add_node_prop(1, 'script', 'foo')

var result = GutUtils.get_scene_script_object(mock_scene)
assert_eq(result, 'foo')






class TestVersionCheck:
extends 'res://addons/gut/test.gd'

Expand Down

0 comments on commit 770c404

Please sign in to comment.