Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ concurrency:


jobs:
unit-test:
generate_test:
name: "Generation Testing"
runs-on: 'ubuntu-22.04'
timeout-minutes: 10 # The overall timeout
Expand All @@ -38,4 +38,3 @@ jobs:
res://testing/generation
timeout: 5
publish-report: false

40 changes: 40 additions & 0 deletions .github/workflows/nodes_testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: GHA

on:
pull_request:
paths-ignore:
- '**.yml'
- '**.md'
workflow_dispatch:


concurrency:
group: ${{ github.workflow }}|${{ github.ref_name }}
cancel-in-progress: true


jobs:
warning_check:
name: "Node Testing"
runs-on: 'ubuntu-22.04'
timeout-minutes: 10 # The overall timeout
permissions:
actions: write
checks: write
contents: write
pull-requests: write
statuses: write

steps:
# checkout your repository
- uses: actions/checkout@v4
with:
lfs: true
# run tests by using the gdUnit4-action with Godot version 4.2.1 and the latest GdUnit4 release
- uses: MikeSchulze/gdUnit4-action@v1.1.6
with:
godot-version: '4.4.1'
paths: |
res://testing/graph_nodes
timeout: 5
publish-report: false
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ scenes/test/*

# Editor-specific ignores
.vscode/*

GdUnitRunner.cfg
1 change: 0 additions & 1 deletion addons/gdUnit4/GdUnitRunner.cfg

This file was deleted.

1 change: 1 addition & 0 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enabled=PackedStringArray("res://addons/gaea/plugin.cfg", "res://addons/gdUnit4/
[gdunit4]

settings/test/test_lookup_folder="testing"
ui/toolbar/run_overall=true

[importer_defaults]

Expand Down
1 change: 0 additions & 1 deletion testing/generation/generate_test.gd
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
class_name GenerateTest
extends GdUnitTestSuite


Expand Down
129 changes: 129 additions & 0 deletions testing/graph_nodes/general/root_nodes_testing.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
extends GdUnitTestSuite


const NODES_PATH := "res://addons/gaea/graph/graph_nodes/root/"

var nodes_in_root: Array[GaeaNodeResource]




func _get_nodes_in_folder(folder_path: String) -> Array[GaeaNodeResource]:
var dir := DirAccess.open(folder_path)
var array: Array[GaeaNodeResource] = []

dir.list_dir_begin()
var file_name := dir.get_next()
while file_name != "":
if not dir.current_is_dir() and not file_name.ends_with(".gd"):
file_name = dir.get_next()
continue

var file_path = folder_path + file_name
if dir.current_is_dir():
array.append_array(_get_nodes_in_folder(file_path + "/"))

if file_name.ends_with(".gd"):
var script := load(file_path)
assert_bool(script.can_instantiate())\
.override_failure_message("Script at [b]%s[/b] couldn't compile." % _get_node_path(script))\
.is_true()

assert_bool(script.is_tool())\
.override_failure_message("Script at [b]%s[/b] isn't a tool script." % _get_node_path(script))\
.is_true()

if script is GDScript and script.is_tool():
var is_valid_node_resource := false
var base_script: GDScript = script
while is_instance_valid(base_script):
base_script = base_script.get_base_script()
if base_script == GaeaNodeResource:
is_valid_node_resource = true
break
if is_valid_node_resource:
var resource: GaeaNodeResource = script.new()
if resource.is_available():
for item in resource.get_tree_items():
array.append(item)
file_name = dir.get_next()

return array


func _get_node_path(object: Object) -> String:
if object is Script:
return object.resource_path.trim_prefix(NODES_PATH)
return object.get_script().resource_path.trim_prefix(NODES_PATH)


## Tests that all nodes' scripts can be instantiated and are tool.
## Also populates the [member nodes_in_root] array.
func test_script_compilation() -> void:
nodes_in_root = _get_nodes_in_folder(NODES_PATH)


## Tests that no `GaeaNodeResource`s in the root push the `_get_arguments_list` warning.
func test_is_arguments_list_overriden() -> void:
for node in nodes_in_root:
await assert_failure_await(func(): assert_error(node.get_arguments_list)\
.is_push_warning(("_get_arguments_list wasn't overridden in %s, node will have no arguments." % node.get_script().resource_path))
)

## Tests that no `GaeaNodeResource`s in the root are unnamed.
func test_for_untitled() -> void:
for node in nodes_in_root:
await assert_str(node.get_title())\
.override_failure_message("Node at [b]%s[/b] is unnamed" % _get_node_path(node))\
.is_not_equal("Unnamed").is_not_equal("")

## Tests that all nodes have outputs.
func test_has_outputs() -> void:
for node in nodes_in_root:
assert_array(node.get_output_ports_list())\
.override_failure_message("Node at [b]%s[/b] has no outputs." % _get_node_path(node))\
.is_not_empty()


## Tests that no `GaeaNodeResource`s in the root have an invalid or null type.
func test_null_type() -> void:
for node in nodes_in_root:
await assert_int(node.get_type())\
.override_failure_message("Type of node at [b]%s[/b] is not a valid type." % _get_node_path(node))\
.is_in(GaeaValue.Type.values())\
.override_failure_message("Type of node at [b]%s[/b] is null." % _get_node_path(node))\
.is_not_equal(GaeaValue.Type.NULL)
for argument in node.get_arguments_list():
await assert_int(node.get_argument_type(argument))\
.override_failure_message("Type of argument [b]%s[/b] is invalid." % argument)\
.append_failure_message("Node at [b]%s[/b]." % _get_node_path(node))\
.is_in(GaeaValue.Type.values())\
.override_failure_message("Type of argument [b]%s[/b] is null." % argument)\
.append_failure_message("Node at [b]%s[/b]." % _get_node_path(node))\
.is_not_equal(GaeaValue.Type.NULL)
for output in node.get_output_ports_list():
await assert_int(node.get_output_port_type(output))\
.override_failure_message("Type of output [b]%s[/b] is invalid." % output)\
.append_failure_message("Node at [b]%s[/b]." % _get_node_path(node))\
.is_in(GaeaValue.Type.values())\
.override_failure_message("Type of output [b]%s[/b] is null." % output)\
.append_failure_message("Node at [b]%s[/b]." % _get_node_path(node))\
.is_not_equal(GaeaValue.Type.NULL)


## Check that all nodes have descriptions.
func test_has_description() -> void:
for node in nodes_in_root:
await assert_str(node.get_description())\
.override_failure_message("Description of node at [b]%s[/b] is empty." % _get_node_path(node))\
.is_not_empty()


## Check that all nodes have a valid scene.
func test_node_scene() -> void:
for node in nodes_in_root:
await assert_object(node.get_scene())\
.override_failure_message("_get_scene at [b]%s[/b] returns null." % _get_node_path(node))\
.is_not_null()\
.override_failure_message("_get_scene at [b]%s[/b] isn't a PackedScene." % _get_node_path(node))\
.is_instanceof(PackedScene)
1 change: 1 addition & 0 deletions testing/graph_nodes/general/root_nodes_testing.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://irnmsmbitacb
Loading