extends GdUnitTestSuite func test_equals_string(): var a := "" var b := "" var c := "abc" var d := "abC" assert_bool(GdObjects.equals("", "")).is_true() assert_bool(GdObjects.equals(a, "")).is_true() assert_bool(GdObjects.equals("", a)).is_true() assert_bool(GdObjects.equals(a, a)).is_true() assert_bool(GdObjects.equals(a, b)).is_true() assert_bool(GdObjects.equals(b, a)).is_true() assert_bool(GdObjects.equals(c, c)).is_true() assert_bool(GdObjects.equals(c, String(c))).is_true() assert_bool(GdObjects.equals(a, null)).is_false() assert_bool(GdObjects.equals(null, a)).is_false() assert_bool(GdObjects.equals("", c)).is_false() assert_bool(GdObjects.equals(c, "")).is_false() assert_bool(GdObjects.equals(c, d)).is_false() assert_bool(GdObjects.equals(d, c)).is_false() # against diverent type assert_bool(GdObjects.equals(d, Array())).is_false() assert_bool(GdObjects.equals(d, Dictionary())).is_false() assert_bool(GdObjects.equals(d, Vector2.ONE)).is_false() assert_bool(GdObjects.equals(d, Vector3.ONE)).is_false() func test_equals_stringname(): assert_bool(GdObjects.equals("", &"")).is_true() assert_bool(GdObjects.equals("abc", &"abc")).is_true() assert_bool(GdObjects.equals("abc", &"abC")).is_false() func test_equals_array(): var a := [] var b := [] var c := Array() var d := [1,2,3,4,5] var e := [1,2,3,4,5] var x := [1,2,3,6,4,5] assert_bool(GdObjects.equals(a, a)).is_true() assert_bool(GdObjects.equals(a, b)).is_true() assert_bool(GdObjects.equals(b, a)).is_true() assert_bool(GdObjects.equals(a, c)).is_true() assert_bool(GdObjects.equals(c, b)).is_true() assert_bool(GdObjects.equals(d, d)).is_true() assert_bool(GdObjects.equals(d, e)).is_true() assert_bool(GdObjects.equals(e, d)).is_true() assert_bool(GdObjects.equals(a, null)).is_false() assert_bool(GdObjects.equals(null, a)).is_false() assert_bool(GdObjects.equals(a, d)).is_false() assert_bool(GdObjects.equals(d, a)).is_false() assert_bool(GdObjects.equals(d, x)).is_false() assert_bool(GdObjects.equals(x, d)).is_false() # against diverent type assert_bool(GdObjects.equals(a, "")).is_false() assert_bool(GdObjects.equals(a, Dictionary())).is_false() assert_bool(GdObjects.equals(a, Vector2.ONE)).is_false() assert_bool(GdObjects.equals(a, Vector3.ONE)).is_false() func test_equals_dictionary(): var a := {} var b := {} var c := {"a":"foo"} var d := {"a":"foo"} var e1 := {"a":"foo", "b":"bar"} var e2 := {"b":"bar", "a":"foo"} assert_bool(GdObjects.equals(a, a)).is_true() assert_bool(GdObjects.equals(a, b)).is_true() assert_bool(GdObjects.equals(b, a)).is_true() assert_bool(GdObjects.equals(c, c)).is_true() assert_bool(GdObjects.equals(c, d)).is_true() assert_bool(GdObjects.equals(e1, e2)).is_true() assert_bool(GdObjects.equals(e2, e1)).is_true() assert_bool(GdObjects.equals(a, null)).is_false() assert_bool(GdObjects.equals(null, a)).is_false() assert_bool(GdObjects.equals(a, c)).is_false() assert_bool(GdObjects.equals(c, a)).is_false() assert_bool(GdObjects.equals(a, e1)).is_false() assert_bool(GdObjects.equals(e1, a)).is_false() assert_bool(GdObjects.equals(c, e1)).is_false() assert_bool(GdObjects.equals(e1, c)).is_false() class TestClass extends Resource: enum { A, B } var _a:int var _b:String var _c:Array func _init(a:int = 0,b:String = "",c:Array = []): _a = a _b = b _c = c func test_equals_class(): var a := TestClass.new() var b := TestClass.new() var c := TestClass.new(1, "foo", ["bar", "xxx"]) var d := TestClass.new(1, "foo", ["bar", "xxx"]) var x := TestClass.new(1, "foo", ["bar", "xsxx"]) assert_bool(GdObjects.equals(a, a)).is_true() assert_bool(GdObjects.equals(a, b)).is_true() assert_bool(GdObjects.equals(b, a)).is_true() assert_bool(GdObjects.equals(c, d)).is_true() assert_bool(GdObjects.equals(d, c)).is_true() assert_bool(GdObjects.equals(a, null)).is_false() assert_bool(GdObjects.equals(null, a)).is_false() assert_bool(GdObjects.equals(a, c)).is_false() assert_bool(GdObjects.equals(c, a)).is_false() assert_bool(GdObjects.equals(d, x)).is_false() assert_bool(GdObjects.equals(x, d)).is_false() func test_equals_with_stack_deep(): # more extended version var x2 := TestClass.new(1, "foo", [TestClass.new(22, "foo"), TestClass.new(22, "foo")]) var x3 := TestClass.new(1, "foo", [TestClass.new(22, "foo"), TestClass.new(23, "foo")]) assert_bool(GdObjects.equals(x2, x3)).is_false() func test_equals_Node_with_deep_check(): var nodeA = auto_free(Node.new()) var nodeB = auto_free(Node.new()) # compares by default with deep parameter ckeck assert_bool(GdObjects.equals(nodeA, nodeA)).is_true() assert_bool(GdObjects.equals(nodeB, nodeB)).is_true() assert_bool(GdObjects.equals(nodeA, nodeB)).is_true() assert_bool(GdObjects.equals(nodeB, nodeA)).is_true() # compares by object reference assert_bool(GdObjects.equals(nodeA, nodeA, false, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)).is_true() assert_bool(GdObjects.equals(nodeB, nodeB, false, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)).is_true() assert_bool(GdObjects.equals(nodeA, nodeB, false, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)).is_false() assert_bool(GdObjects.equals(nodeB, nodeA, false, GdObjects.COMPARE_MODE.OBJECT_REFERENCE)).is_false() func test_is_primitive_type(): assert_bool(GdObjects.is_primitive_type(false)).is_true() assert_bool(GdObjects.is_primitive_type(true)).is_true() assert_bool(GdObjects.is_primitive_type(0)).is_true() assert_bool(GdObjects.is_primitive_type(0.1)).is_true() assert_bool(GdObjects.is_primitive_type("")).is_true() assert_bool(GdObjects.is_primitive_type(Vector2.ONE)).is_false() class TestClassForIsType: var x func test_is_type(): # check build-in types assert_bool(GdObjects.is_type(1)).is_false() assert_bool(GdObjects.is_type(1.3)).is_false() assert_bool(GdObjects.is_type(true)).is_false() assert_bool(GdObjects.is_type(false)).is_false() assert_bool(GdObjects.is_type([])).is_false() assert_bool(GdObjects.is_type("abc")).is_false() assert_bool(GdObjects.is_type(null)).is_false() # an object type assert_bool(GdObjects.is_type(Node)).is_true() # an reference type assert_bool(GdObjects.is_type(AStar3D)).is_true() # an script type assert_bool(GdObjects.is_type(GDScript)).is_true() # an custom type assert_bool(GdObjects.is_type(TestClassForIsType)).is_true() # checked inner class type assert_bool(GdObjects.is_type(CustomClass.InnerClassA)).is_true() assert_bool(GdObjects.is_type(CustomClass.InnerClassC)).is_true() # for instances must allways endup with false assert_bool(GdObjects.is_type(auto_free(Node.new()))).is_false() assert_bool(GdObjects.is_type(AStar3D.new())).is_false() assert_bool(GdObjects.is_type(Dictionary())).is_false() assert_bool(GdObjects.is_type(PackedColorArray())).is_false() assert_bool(GdObjects.is_type(GDScript.new())).is_false() assert_bool(GdObjects.is_type(TestClassForIsType.new())).is_false() assert_bool(GdObjects.is_type(auto_free(CustomClass.InnerClassC.new()))).is_false() func test_is_singleton() -> void: for singleton_name in Engine.get_singleton_list(): var singleton = Engine.get_singleton(singleton_name) assert_bool(GdObjects.is_singleton(singleton)) \ .override_failure_message("Expect to a singleton: '%s' Instance: %s, Class: %s" % [singleton_name, singleton, singleton.get_class()]) \ .is_true() # false tests assert_bool(GdObjects.is_singleton(10)).is_false() assert_bool(GdObjects.is_singleton(true)).is_false() assert_bool(GdObjects.is_singleton(Node)).is_false() assert_bool(GdObjects.is_singleton(auto_free(Node.new()))).is_false() func _is_instance(value) -> bool: return GdObjects.is_instance(auto_free(value)) func test_is_instance_true(): assert_bool(_is_instance(RefCounted.new())).is_true() assert_bool(_is_instance(Node.new())).is_true() assert_bool(_is_instance(AStar3D.new())).is_true() assert_bool(_is_instance(PackedScene.new())).is_true() assert_bool(_is_instance(GDScript.new())).is_true() assert_bool(_is_instance(Person.new())).is_true() assert_bool(_is_instance(CustomClass.new())).is_true() assert_bool(_is_instance(CustomNodeTestClass.new())).is_true() assert_bool(_is_instance(TestClassForIsType.new())).is_true() assert_bool(_is_instance(CustomClass.InnerClassC.new())).is_true() func test_is_instance_false(): assert_bool(_is_instance(RefCounted)).is_false() assert_bool(_is_instance(Node)).is_false() assert_bool(_is_instance(AStar3D)).is_false() assert_bool(_is_instance(PackedScene)).is_false() assert_bool(_is_instance(GDScript)).is_false() assert_bool(_is_instance(Dictionary())).is_false() assert_bool(_is_instance(PackedColorArray())).is_false() assert_bool(_is_instance(Person)).is_false() assert_bool(_is_instance(CustomClass)).is_false() assert_bool(_is_instance(CustomNodeTestClass)).is_false() assert_bool(_is_instance(TestClassForIsType)).is_false() assert_bool(_is_instance(CustomClass.InnerClassC)).is_false() # shorter helper func to extract class name and using auto_free func extract_class_name(value) -> GdUnitResult: return GdObjects.extract_class_name(auto_free(value)) func test_get_class_name_from_class_path(): # extract class name by resoure path assert_result(extract_class_name("res://addons/gdUnit4/test/resources/core/Person.gd"))\ .is_success().is_value("Person") assert_result(extract_class_name("res://addons/gdUnit4/test/resources/core/CustomClass.gd"))\ .is_success().is_value("CustomClass") assert_result(extract_class_name("res://addons/gdUnit4/test/mocker/resources/CustomNodeTestClass.gd"))\ .is_success().is_value("CustomNodeTestClass") assert_result(extract_class_name("res://addons/gdUnit4/test/mocker/resources/CustomResourceTestClass.gd"))\ .is_success().is_value("CustomResourceTestClass") assert_result(extract_class_name("res://addons/gdUnit4/test/mocker/resources/OverridenGetClassTestClass.gd"))\ .is_success().is_value("OverridenGetClassTestClass") func test_get_class_name_from_snake_case_class_path(): assert_result(extract_class_name("res://addons/gdUnit4/test/core/resources/naming_conventions/snake_case_with_class_name.gd"))\ .is_success().is_value("SnakeCaseWithClassName") # without class_name assert_result(extract_class_name("res://addons/gdUnit4/test/core/resources/naming_conventions/snake_case_without_class_name.gd"))\ .is_success().is_value("SnakeCaseWithoutClassName") func test_get_class_name_from_pascal_case_class_path(): assert_result(extract_class_name("res://addons/gdUnit4/test/core/resources/naming_conventions/PascalCaseWithClassName.gd"))\ .is_success().is_value("PascalCaseWithClassName") # without class_name assert_result(extract_class_name("res://addons/gdUnit4/test/core/resources/naming_conventions/PascalCaseWithoutClassName.gd"))\ .is_success().is_value("PascalCaseWithoutClassName") func test_get_class_name_from_type(): assert_result(extract_class_name(Animation)).is_success().is_value("Animation") assert_result(extract_class_name(GDScript)).is_success().is_value("GDScript") assert_result(extract_class_name(Camera3D)).is_success().is_value("Camera3D") assert_result(extract_class_name(Node)).is_success().is_value("Node") assert_result(extract_class_name(Tree)).is_success().is_value("Tree") # extract class name from custom classes assert_result(extract_class_name(Person)).is_success().is_value("Person") assert_result(extract_class_name(CustomClass)).is_success().is_value("CustomClass") assert_result(extract_class_name(CustomNodeTestClass)).is_success().is_value("CustomNodeTestClass") assert_result(extract_class_name(CustomResourceTestClass)).is_success().is_value("CustomResourceTestClass") assert_result(extract_class_name(OverridenGetClassTestClass)).is_success().is_value("OverridenGetClassTestClass") assert_result(extract_class_name(AdvancedTestClass)).is_success().is_value("AdvancedTestClass") func test_get_class_name_from_inner_class(): assert_result(extract_class_name(CustomClass))\ .is_success().is_value("CustomClass") assert_result(extract_class_name(CustomClass.InnerClassA))\ .is_success().is_value("CustomClass.InnerClassA") assert_result(extract_class_name(CustomClass.InnerClassB))\ .is_success().is_value("CustomClass.InnerClassB") assert_result(extract_class_name(CustomClass.InnerClassC))\ .is_success().is_value("CustomClass.InnerClassC") assert_result(extract_class_name(CustomClass.InnerClassD))\ .is_success().is_value("CustomClass.InnerClassD") assert_result(extract_class_name(AdvancedTestClass.SoundData))\ .is_success().is_value("AdvancedTestClass.SoundData") assert_result(extract_class_name(AdvancedTestClass.AtmosphereData))\ .is_success().is_value("AdvancedTestClass.AtmosphereData") assert_result(extract_class_name(AdvancedTestClass.Area4D))\ .is_success().is_value("AdvancedTestClass.Area4D") func test_extract_class_name_from_instance(): assert_result(extract_class_name(Camera3D.new())).is_equal("Camera3D") assert_result(extract_class_name(GDScript.new())).is_equal("GDScript") assert_result(extract_class_name(Node.new())).is_equal("Node") # extract class name from custom classes assert_result(extract_class_name(Person.new())).is_equal("Person") assert_result(extract_class_name(ClassWithNameA.new())).is_equal("ClassWithNameA") assert_result(extract_class_name(ClassWithNameB.new())).is_equal("ClassWithNameB") var classWithoutNameA = load("res://addons/gdUnit4/test/mocker/resources/ClassWithoutNameA.gd") assert_result(extract_class_name(classWithoutNameA.new())).is_equal("ClassWithoutNameA") assert_result(extract_class_name(CustomNodeTestClass.new())).is_equal("CustomNodeTestClass") assert_result(extract_class_name(CustomResourceTestClass.new())).is_equal("CustomResourceTestClass") assert_result(extract_class_name(OverridenGetClassTestClass.new())).is_equal("OverridenGetClassTestClass") assert_result(extract_class_name(AdvancedTestClass.new())).is_equal("AdvancedTestClass") # extract inner class name assert_result(extract_class_name(AdvancedTestClass.SoundData.new())).is_equal("AdvancedTestClass.SoundData") assert_result(extract_class_name(AdvancedTestClass.AtmosphereData.new())).is_equal("AdvancedTestClass.AtmosphereData") assert_result(extract_class_name(AdvancedTestClass.Area4D.new(0))).is_equal("AdvancedTestClass.Area4D") assert_result(extract_class_name(CustomClass.InnerClassC.new())).is_equal("CustomClass.InnerClassC") # verify enigne class names are not converted by configured naming convention @warning_ignore("unused_parameter") func test_extract_class_name_from_class_path(fuzzer=GodotClassNameFuzzer.new(true, true), fuzzer_iterations = 100) -> void: var clazz_name :String = fuzzer.next_value() assert_str(GdObjects.extract_class_name_from_class_path(PackedStringArray([clazz_name]))).is_equal(clazz_name) @warning_ignore("unused_parameter") func test_extract_class_name_godot_classes(fuzzer=GodotClassNameFuzzer.new(true, true), fuzzer_iterations = 100): var extract_class_name_ := fuzzer.next_value() as String var instance :Variant = ClassDB.instantiate(extract_class_name_) assert_result(extract_class_name(instance)).is_equal(extract_class_name_) func test_extract_class_path_by_clazz(): # engine classes has no class path assert_array(GdObjects.extract_class_path(Animation)).is_empty() assert_array(GdObjects.extract_class_path(GDScript)).is_empty() assert_array(GdObjects.extract_class_path(Camera3D)).is_empty() assert_array(GdObjects.extract_class_path(Tree)).is_empty() assert_array(GdObjects.extract_class_path(Node)).is_empty() # script classes assert_array(GdObjects.extract_class_path(Person))\ .contains_exactly(["res://addons/gdUnit4/test/resources/core/Person.gd"]) assert_array(GdObjects.extract_class_path(CustomClass))\ .contains_exactly(["res://addons/gdUnit4/test/resources/core/CustomClass.gd"]) assert_array(GdObjects.extract_class_path(CustomNodeTestClass))\ .contains_exactly(["res://addons/gdUnit4/test/mocker/resources/CustomNodeTestClass.gd"]) assert_array(GdObjects.extract_class_path(CustomResourceTestClass))\ .contains_exactly(["res://addons/gdUnit4/test/mocker/resources/CustomResourceTestClass.gd"]) assert_array(GdObjects.extract_class_path(OverridenGetClassTestClass))\ .contains_exactly(["res://addons/gdUnit4/test/mocker/resources/OverridenGetClassTestClass.gd"]) # script inner classes assert_array(GdObjects.extract_class_path(CustomClass.InnerClassA))\ .contains_exactly(["res://addons/gdUnit4/test/resources/core/CustomClass.gd", "InnerClassA"]) assert_array(GdObjects.extract_class_path(CustomClass.InnerClassB))\ .contains_exactly(["res://addons/gdUnit4/test/resources/core/CustomClass.gd", "InnerClassB"]) assert_array(GdObjects.extract_class_path(CustomClass.InnerClassC))\ .contains_exactly(["res://addons/gdUnit4/test/resources/core/CustomClass.gd", "InnerClassC"]) assert_array(GdObjects.extract_class_path(AdvancedTestClass.SoundData))\ .contains_exactly(["res://addons/gdUnit4/test/mocker/resources/AdvancedTestClass.gd", "SoundData"]) assert_array(GdObjects.extract_class_path(AdvancedTestClass.AtmosphereData))\ .contains_exactly(["res://addons/gdUnit4/test/mocker/resources/AdvancedTestClass.gd", "AtmosphereData"]) assert_array(GdObjects.extract_class_path(AdvancedTestClass.Area4D))\ .contains_exactly(["res://addons/gdUnit4/test/mocker/resources/AdvancedTestClass.gd", "Area4D"]) # inner inner class assert_array(GdObjects.extract_class_path(CustomClass.InnerClassD.InnerInnerClassA))\ .contains_exactly(["res://addons/gdUnit4/test/resources/core/CustomClass.gd", "InnerClassD", "InnerInnerClassA"]) #func __test_can_instantiate(): # assert_bool(GdObjects.can_instantiate(GDScript)).is_true() # assert_bool(GdObjects.can_instantiate(Node)).is_true() # assert_bool(GdObjects.can_instantiate(Tree)).is_true() # assert_bool(GdObjects.can_instantiate(Camera3D)).is_true() # assert_bool(GdObjects.can_instantiate(Person)).is_true() # assert_bool(GdObjects.can_instantiate(CustomClass.InnerClassA)).is_true() # assert_bool(GdObjects.can_instantiate(TreeItem)).is_true() # # creates a test instance by given class name or resource path # instances created with auto free func create_instance(clazz): var result := GdObjects.create_instance(clazz) if result.is_success(): return auto_free(result.value()) return null func test_create_instance_by_class_name(): # instance of engine classes assert_object(create_instance(Node))\ .is_not_null()\ .is_instanceof(Node) assert_object(create_instance(Camera3D))\ .is_not_null()\ .is_instanceof(Camera3D) # instance of custom classes assert_object(create_instance(Person))\ .is_not_null()\ .is_instanceof(Person) # instance of inner classes assert_object(create_instance(CustomClass.InnerClassA))\ .is_not_null()\ .is_instanceof(CustomClass.InnerClassA) func test_extract_class_name_on_null_value(): # we can't extract class name from a null value assert_result(GdObjects.extract_class_name(null))\ .is_error()\ .contains_message("Can't extract class name form a null value.") func test_is_public_script_class() -> void: # snake case format class names assert_bool(GdObjects.is_public_script_class("ScriptWithClassName")).is_true() assert_bool(GdObjects.is_public_script_class("script_without_class_name")).is_false() assert_bool(GdObjects.is_public_script_class("CustomClass")).is_true() # inner classes not listed as public classes assert_bool(GdObjects.is_public_script_class("CustomClass.InnerClassA")).is_false() func test_is_instance_scene() -> void: # checked none scene objects assert_bool(GdObjects.is_instance_scene(RefCounted.new())).is_false() assert_bool(GdObjects.is_instance_scene(CustomClass.new())).is_false() assert_bool(GdObjects.is_instance_scene(auto_free(Control.new()))).is_false() # now check checked a loaded scene var resource = load("res://addons/gdUnit4/test/mocker/resources/scenes/TestScene.tscn") assert_bool(GdObjects.is_instance_scene(resource)).is_false() # checked a instance of a scene assert_bool(GdObjects.is_instance_scene(auto_free(resource.instantiate()))).is_true() func test_is_scene_resource_path() -> void: assert_bool(GdObjects.is_scene_resource_path(RefCounted.new())).is_false() assert_bool(GdObjects.is_scene_resource_path(CustomClass.new())).is_false() assert_bool(GdObjects.is_scene_resource_path(auto_free(Control.new()))).is_false() # check checked a loaded scene var resource = load("res://addons/gdUnit4/test/mocker/resources/scenes/TestScene.tscn") assert_bool(GdObjects.is_scene_resource_path(resource)).is_false() # checked resource path assert_bool(GdObjects.is_scene_resource_path("res://addons/gdUnit4/test/mocker/resources/scenes/TestScene.tscn")).is_true() func test_extract_class_functions() -> void: var functions := GdObjects.extract_class_functions("Resource", [""]) for f in functions: if f["name"] == "get_path": assert_str(GdFunctionDescriptor.extract_from(f)._to_string()).is_equal("[Line:-1] func get_path() -> String:") functions = GdObjects.extract_class_functions("CustomResourceTestClass", ["res://addons/gdUnit4/test/mocker/resources/CustomResourceTestClass.gd"]) for f in functions: if f["name"] == "get_path": assert_str(GdFunctionDescriptor.extract_from(f)._to_string()).is_equal("[Line:-1] func get_path() -> String:") func test_all_types() -> void: var expected_types :Array[int] = [] for type_index in TYPE_MAX: expected_types.append(type_index) expected_types.append(GdObjects.TYPE_VOID) expected_types.append(GdObjects.TYPE_VARARG) expected_types.append(GdObjects.TYPE_FUNC) expected_types.append(GdObjects.TYPE_FUZZER) expected_types.append(GdObjects.TYPE_VARIANT) assert_array(GdObjects.all_types()).contains_exactly_in_any_order(expected_types) func test_to_camel_case() -> void: assert_str(GdObjects.to_camel_case("MyClassName")).is_equal("myClassName") assert_str(GdObjects.to_camel_case("my_class_name")).is_equal("myClassName") assert_str(GdObjects.to_camel_case("myClassName")).is_equal("myClassName") func test_to_pascal_case() -> void: assert_str(GdObjects.to_pascal_case("MyClassName")).is_equal("MyClassName") assert_str(GdObjects.to_pascal_case("my_class_name")).is_equal("MyClassName") assert_str(GdObjects.to_pascal_case("myClassName")).is_equal("MyClassName") func test_to_snake_case() -> void: assert_str(GdObjects.to_snake_case("MyClassName")).is_equal("my_class_name") assert_str(GdObjects.to_snake_case("my_class_name")).is_equal("my_class_name") assert_str(GdObjects.to_snake_case("myClassName")).is_equal("my_class_name") func test_is_snake_case() -> void: assert_bool(GdObjects.is_snake_case("my_class_name")).is_true() assert_bool(GdObjects.is_snake_case("myclassname")).is_true() assert_bool(GdObjects.is_snake_case("MyClassName")).is_false() assert_bool(GdObjects.is_snake_case("my_class_nameTest")).is_false()