aboutsummaryrefslogtreecommitdiff
path: root/unit_tests/scripts/linda/send_receive_tables.lua
blob: 0e1569ad5ccb78c854fee59ee4000704840f63ff (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
local lanes = require "lanes"
local dt = lanes.require "deep_userdata_example"

local l = lanes.linda()

-- =================================================================================================
-- send a table with subtables, both as keys and values, making sure the structure is preserved
-- =================================================================================================

if true then
	local t1 = {["name"] = "t1"}
	local t2 = {["name"] = "t2"}

	local t3 = {
		["name"] = "t3",
		["t1"] = t1,
		[t1] = t2, -- table t1 as key, table t2 as value
		["t2"] = t2,
		[t2] = t1 -- table t2 as key, table t1 as value
	}

	-- add recursivity for good measure
	t3["t3"] = t3
	t3[t3] = t3
	t1["t3"] = t3
	t2["t3"] = t3

	l:send("data", t3)
	local k, t = l:receive("data")
	assert(k == "data" and type(t) == "table" and t.name == "t3")
	-- when keys are strings
	assert(t["t3"] == t)
	assert(type(t["t1"]) == "table")
	assert(t["t1"].name == "t1")
	assert(type(t["t2"]) == "table")
	assert(t["t2"].name == "t2")
	assert(t["t1"].t3 == t)
	assert(t["t2"].t3 == t)
	-- when keys are tables
	assert(t[t.t1] == t.t2)
	assert(t[t.t1]["t3"] == t)
	assert(t[t.t2] == t.t1)
	assert(t[t.t2]["t3"] == t)
	assert(t[t.t3] == t.t3)
end

-- =================================================================================================
-- send a table with deep userdata keys and values
-- =================================================================================================

if true then
	local fixture = assert(require "fixture")
	local u = assert(fixture.newuserdata())
	assert(type(u) == "userdata")

	-- send a table where full userdata is used as key
	-- should fail because the userdata is not deep
	local s, r = pcall(l.send, l, "data", {["k"] = u})
	assert(s == false and type(r) == "string", "got " .. r)

	-- trying again with full userdata
	local d1 = dt.new_deep()
	assert(type(d1) == "userdata")
	local d2 = dt.new_deep()
	assert(type(d2) == "userdata")

	local t4 =
	{
		[d1] = d2,
		[d2] = d1
	}

	l:send("data", t4)
	local k, t = l:receive("data")
	assert(k == "data" and type(t) == "table")
	-- we should have 2 userdata entries in the table
	local count = 0
	for k, v in pairs(t) do
		assert(type(k) == "userdata")
		assert(type(v) == "userdata")
		count = count + 1
	end
	assert(count == 2, "got " .. count)
	-- all userdata identities should be preserved
	assert(type(t[d1]) == "userdata")
	assert(type(t[d2]) == "userdata")
	assert(t[d1] == d2)
	assert(t[d2] == d1)
	assert(t[d1] == t4[d1])
	assert(t[d2] == t4[d2])
end

-- =================================================================================================
-- send a table with clonable userdata keys and values
-- =================================================================================================

if true then
	local c1 = dt.new_clonable()
	c1:set(1)
	assert(type(c1) == "userdata")
	local c2 = dt.new_clonable()
	c2:set(2)
	assert(type(c2) == "userdata")

	l:send("data", c1)
	local k, c = l:receive("data")
	assert(k == "data" and type(c) == "userdata" and c:get() == 1, "got " .. tostring(c))

	local t5 =
	{
		[c1] = c2,
		[c2] = c1
	}

	l:send("data", t5)
	local k, t = l:receive("data")
	assert(k == "data" and type(t) == "table")
	-- all userdata identities should NOT be preserved, because the cloned userdatas in t are not the originals that were stored in t5
	assert(type(t[c1]) == "nil")
	assert(type(t[c2]) == "nil")
	-- but we should still have 2 userdata entries in the table
	local count = 0
	for k, v in pairs(t) do
		assert(type(k) == "userdata")
		assert(type(v) == "userdata")
		count = count + 1
	end
	assert(count == 2, "got " .. count)
	-- and c1-as-key should be identical to c1-as-value (same for c2)
	-- of course I can't be sure that enumerating the table will start with key c1, but that's not important
	local c1_as_key, c2_as_value = next(t)
	assert(type(c1_as_key) == "userdata" and type(c2_as_value) == "userdata" and c1_as_key:get() ~= c2_as_value:get())
	local c2_as_key, c1_as_value = next(t, c1_as_key)
	assert(type(c2_as_key) == "userdata" and type(c1_as_value) == "userdata" and c2_as_key:get() ~= c1_as_value:get())
	assert(c1_as_key == c1_as_value)
	assert(c2_as_key == c2_as_value)
end