Open neth392 opened 2 months ago
This seems out of scope for compare_deep
, even though it feels very similar. If you have a dictionary or array of of things to compare then maybe GUT could get a compare_deep_custom
that would allow you to specify a Callable
to compare two elements.
If you only have two objects you want to compare you might be able to use compare_deep
with the results of inst_to_dict
. I'm not sure if inst_to_dict
handles sub-objects but it shouldn't be too difficult to add that. You can also use get_property_list
and get
to go through each property.
If I'm misunderstanding the request, add some sample code.
That's a good point. I didn't think of trying inst_to_dict
, maybe it could've worked. A compare_deep_custom(callable)
could work but it'd have to account for properties that are other objects and so on, and be able to isolate at what level there was an issue, say if "MyObject.other_object_property.another_object_property" didn't match.
I wrote some functions to use in a GutTest (link below) where I needed to compare objects & arrays/dictionaries possibly containing objects, so that'd be a good sample of why I needed it. The initial code I had written didn't really isolate what failed the comparison so that's why I recursively return a string, and concatenate it back up that recursive chain until it's printed as 1 string containing all the info I need to see what failed. May be something to consider if it's decided to implement this
https://github.com/neth392/godot-improved-json/blob/main/tests/test_custom_objects.gd#L160
There are problems with this implementation but if anyone wants a quick and dirty approach:
USE WITH CAUTION!!!! (I haven't tested)
func deep(v1, v2):
var result = null
if(GutUtils.are_datatypes_same(v1, v2)):
if(typeof(v1) in [TYPE_ARRAY, TYPE_DICTIONARY]):
result = GutUtils.DiffTool.new(v1, v2, GutUtils.DIFF.DEEP)
elif (
typeof(v1) == TYPE_OBJECT and
typeof(v2) == TYPE_OBJECT and
v1.get_class() == v2.get_class()
):
if v1.has_method('equal'):
result = simple(v1.equal(v2), true)
else:
for property in v1.get_property_list():
if property.usage != PROPERTY_USAGE_SCRIPT_VARIABLE:
continue
result = deep(v1[property.name], v2[property.name])
else:
result = simple(v1, v2)
else:
result = simple(v1, v2)
return result
Maybe it'd be best to first check for an .equal
function on the object, and if it's not found, perform the following. So, they can override this default behavior that is somewhat arbitrary.
Also, I haven't tested this too deeply. So, I don't know how well the recursiveness works.
EDIT:
I cleaned up the code a bit and added the .equal
part.
Versions
What versions of Godot do you want to use this feature in? Latest
The Feature
I am writing tests for a serialization library. The tests involve comparing original object instances to their deserialized counterparts. Godot's == does not work with this as the objects are two different instances, but I need to test to see if their property values match. If compare_deep supported objects this would be great, as right now I have to write some really hacky code to make these tests work & be verbose enough to isolate which properties do not match. Recursive support would be needed too as objects can have properties whose values are other objects