summaryrefslogtreecommitdiff
path: root/games/devtest/mods/unittests/async_env.lua
blob: aff1fc4d9271431c2c61202ad378119f15d67f62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
-- helper

core.register_async_dofile(core.get_modpath(core.get_current_modname()) ..
	DIR_DELIM .. "inside_async_env.lua")

local function deepequal(a, b)
	if type(a) == "function" then
		return type(b) == "function"
	elseif type(a) ~= "table" then
		return a == b
	elseif type(b) ~= "table" then
		return false
	end
	for k, v in pairs(a) do
		if not deepequal(v, b[k]) then
			return false
		end
	end
	for k, v in pairs(b) do
		if not deepequal(a[k], v) then
			return false
		end
	end
	return true
end

-- Object Passing / Serialization

local test_object = {
	name = "stairs:stair_glass",
	type = "node",
	groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1},
	description = "Glass Stair",
	sounds = {
		dig = {name = "default_glass_footstep", gain = 0.5},
		footstep = {name = "default_glass_footstep", gain = 0.3},
		dug = {name = "default_break_glass", gain = 1}
	},
	node_box = {
		fixed = {
			{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
			{-0.5, 0, 0, 0.5, 0.5, 0.5}
		},
		type = "fixed"
	},
	tiles = {
		{name = "stairs_glass_split.png", backface_culling = true},
		{name = "default_glass.png", backface_culling = true},
		{name = "stairs_glass_stairside.png^[transformFX", backface_culling = true}
	},
	on_place = function(itemstack, placer)
		return core.is_player(placer)
	end,
	sunlight_propagates = true,
	is_ground_content = false,
	light_source = 0,
}

local function test_object_passing()
	local tmp = core.serialize_roundtrip(test_object)
	assert(deepequal(test_object, tmp))

	-- Circular key, should error
	tmp = {"foo", "bar"}
	tmp[tmp] = true
	assert(not pcall(core.serialize_roundtrip, tmp))

	-- Circular value, should error
	tmp = {"foo"}
	tmp[2] = tmp
	assert(not pcall(core.serialize_roundtrip, tmp))
end
unittests.register("test_object_passing", test_object_passing)

local function test_userdata_passing(_, pos)
	-- basic userdata passing
	local obj = table.copy(test_object.tiles[1])
	obj.test = ItemStack("default:cobble 99")
	local tmp = core.serialize_roundtrip(obj)
	assert(type(tmp.test) == "userdata")
	assert(obj.test:to_string() == tmp.test:to_string())

	-- object can't be passed, should error
	obj = core.raycast(pos, pos)
	assert(not pcall(core.serialize_roundtrip, obj))

	-- VManip
	local vm = core.get_voxel_manip(pos, pos)
	local expect = vm:get_node_at(pos)
	local vm2 = core.serialize_roundtrip(vm)
	assert(deepequal(vm2:get_node_at(pos), expect))
end
unittests.register("test_userdata_passing", test_userdata_passing, {map=true})

-- Asynchronous jobs

local function test_handle_async(cb)
	-- Basic test including mod name tracking and unittests.async_test()
	-- which is defined inside_async_env.lua
	local func = function(x)
		return core.get_last_run_mod(), _VERSION, unittests[x]()
	end
	local expect = {core.get_last_run_mod(), _VERSION, true}

	core.handle_async(func, function(...)
		if not deepequal(expect, {...}) then
			cb("Values did not equal")
		end
		if core.get_last_run_mod() ~= expect[1] then
			cb("Mod name not tracked correctly")
		end

		-- Test passing of nil arguments and return values
		core.handle_async(function(a, b)
			return a, b
		end, function(a, b)
			if b ~= 123 then
				cb("Argument went missing")
			end
			cb()
		end, nil, 123)
	end, "async_test")
end
unittests.register("test_handle_async", test_handle_async, {async=true})

local function test_userdata_passing2(cb, _, pos)
	-- VManip: check transfer into other env
	local vm = core.get_voxel_manip(pos, pos)
	local expect = vm:get_node_at(pos)

	core.handle_async(function(vm_, pos_)
		return vm_:get_node_at(pos_)
	end, function(ret)
		if not deepequal(expect, ret) then
			cb("Node data mismatch (one-way)")
		end

		-- VManip: test a roundtrip
		core.handle_async(function(vm_)
			return vm_
		end, function(vm2)
			if not deepequal(expect, vm2:get_node_at(pos)) then
				cb("Node data mismatch (roundtrip)")
			end
			cb()
		end, vm)
	end, vm, pos)
end
unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})