]> git.lizzy.rs Git - dragonfireclient.git/blob - games/devtest/mods/unittests/async_env.lua
Support packing arbitrary graphs (#12289)
[dragonfireclient.git] / games / devtest / mods / unittests / async_env.lua
1 -- helper
2
3 core.register_async_dofile(core.get_modpath(core.get_current_modname()) ..
4         DIR_DELIM .. "inside_async_env.lua")
5
6 local function deepequal(a, b)
7         if type(a) == "function" then
8                 return type(b) == "function"
9         elseif type(a) ~= "table" then
10                 return a == b
11         elseif type(b) ~= "table" then
12                 return false
13         end
14         for k, v in pairs(a) do
15                 if not deepequal(v, b[k]) then
16                         return false
17                 end
18         end
19         for k, v in pairs(b) do
20                 if not deepequal(a[k], v) then
21                         return false
22                 end
23         end
24         return true
25 end
26
27 -- Object Passing / Serialization
28
29 local test_object = {
30         name = "stairs:stair_glass",
31         type = "node",
32         groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1},
33         description = "Glass Stair",
34         sounds = {
35                 dig = {name = "default_glass_footstep", gain = 0.5},
36                 footstep = {name = "default_glass_footstep", gain = 0.3},
37                 dug = {name = "default_break_glass", gain = 1}
38         },
39         node_box = {
40                 fixed = {
41                         {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
42                         {-0.5, 0, 0, 0.5, 0.5, 0.5}
43                 },
44                 type = "fixed"
45         },
46         tiles = {
47                 {name = "stairs_glass_split.png", backface_culling = true},
48                 {name = "default_glass.png", backface_culling = true},
49                 {name = "stairs_glass_stairside.png^[transformFX", backface_culling = true}
50         },
51         on_place = function(itemstack, placer)
52                 return core.is_player(placer)
53         end,
54         sunlight_propagates = true,
55         is_ground_content = false,
56         light_source = 0,
57 }
58
59 local function test_object_passing()
60         local tmp = core.serialize_roundtrip(test_object)
61         assert(deepequal(test_object, tmp))
62
63         local circular_key = {"foo", "bar"}
64         circular_key[circular_key] = true
65         tmp = core.serialize_roundtrip(circular_key)
66         assert(tmp[1] == "foo")
67         assert(tmp[2] == "bar")
68         assert(tmp[tmp] == true)
69
70         local circular_value = {"foo"}
71         circular_value[2] = circular_value
72         tmp = core.serialize_roundtrip(circular_value)
73         assert(tmp[1] == "foo")
74         assert(tmp[2] == tmp)
75
76         -- Two-segment cycle
77         local cycle_seg_1, cycle_seg_2 = {}, {}
78         cycle_seg_1[1] = cycle_seg_2
79         cycle_seg_2[1] = cycle_seg_1
80         tmp = core.serialize_roundtrip(cycle_seg_1)
81         assert(tmp[1][1] == tmp)
82
83         -- Duplicated value without a cycle
84         local acyclic_dup_holder = {}
85         tmp = ItemStack("")
86         acyclic_dup_holder[tmp] = tmp
87         tmp = core.serialize_roundtrip(acyclic_dup_holder)
88         for k, v in pairs(tmp) do
89                 assert(rawequal(k, v))
90         end
91 end
92 unittests.register("test_object_passing", test_object_passing)
93
94 local function test_userdata_passing(_, pos)
95         -- basic userdata passing
96         local obj = table.copy(test_object.tiles[1])
97         obj.test = ItemStack("default:cobble 99")
98         local tmp = core.serialize_roundtrip(obj)
99         assert(type(tmp.test) == "userdata")
100         assert(obj.test:to_string() == tmp.test:to_string())
101
102         -- object can't be passed, should error
103         obj = core.raycast(pos, pos)
104         assert(not pcall(core.serialize_roundtrip, obj))
105
106         -- VManip
107         local vm = core.get_voxel_manip(pos, pos)
108         local expect = vm:get_node_at(pos)
109         local vm2 = core.serialize_roundtrip(vm)
110         assert(deepequal(vm2:get_node_at(pos), expect))
111 end
112 unittests.register("test_userdata_passing", test_userdata_passing, {map=true})
113
114 -- Asynchronous jobs
115
116 local function test_handle_async(cb)
117         -- Basic test including mod name tracking and unittests.async_test()
118         -- which is defined inside_async_env.lua
119         local func = function(x)
120                 return core.get_last_run_mod(), _VERSION, unittests[x]()
121         end
122         local expect = {core.get_last_run_mod(), _VERSION, true}
123
124         core.handle_async(func, function(...)
125                 if not deepequal(expect, {...}) then
126                         cb("Values did not equal")
127                 end
128                 if core.get_last_run_mod() ~= expect[1] then
129                         cb("Mod name not tracked correctly")
130                 end
131
132                 -- Test passing of nil arguments and return values
133                 core.handle_async(function(a, b)
134                         return a, b
135                 end, function(a, b)
136                         if b ~= 123 then
137                                 cb("Argument went missing")
138                         end
139                         cb()
140                 end, nil, 123)
141         end, "async_test")
142 end
143 unittests.register("test_handle_async", test_handle_async, {async=true})
144
145 local function test_userdata_passing2(cb, _, pos)
146         -- VManip: check transfer into other env
147         local vm = core.get_voxel_manip(pos, pos)
148         local expect = vm:get_node_at(pos)
149
150         core.handle_async(function(vm_, pos_)
151                 return vm_:get_node_at(pos_)
152         end, function(ret)
153                 if not deepequal(expect, ret) then
154                         cb("Node data mismatch (one-way)")
155                 end
156
157                 -- VManip: test a roundtrip
158                 core.handle_async(function(vm_)
159                         return vm_
160                 end, function(vm2)
161                         if not deepequal(expect, vm2:get_node_at(pos)) then
162                                 cb("Node data mismatch (roundtrip)")
163                         end
164                         cb()
165                 end, vm)
166         end, vm, pos)
167 end
168 unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})