aboutsummaryrefslogtreecommitdiff
path: root/spec/outputs/test/metatable_spec.lua
blob: 4d2a8866fe1f5f1432c9222bde141a2fb6280917 (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
return describe("metatable", function()
	it("should get metatable with <> syntax", function()
		local obj = setmetatable({
			value = 42
		}, {
			__index = {
				extra = "data"
			}
		})
		local mt = getmetatable(obj)
		return assert.is_true(mt ~= nil)
	end)
	it("should set metatable with <>", function()
		local obj = { }
		setmetatable(obj, {
			__index = {
				value = 100
			}
		})
		return assert.same(obj.value, 100)
	end)
	it("should access metatable with <>", function()
		local obj = setmetatable({ }, {
			__index = {
				value = 50
			}
		})
		local result = getmetatable(obj).__index.value
		return assert.same(result, 50)
	end)
	it("should work with <index> metamethod", function()
		local obj = setmetatable({ }, {
			__index = function(self, key)
				if key == "computed" then
					return "computed_value"
				end
			end
		})
		return assert.same(obj.computed, "computed_value")
	end)
	it("should work with <newindex> metamethod", function()
		local obj = setmetatable({ }, {
			__newindex = function(self, key, value)
				return rawset(self, "stored_" .. key, value)
			end
		})
		obj.test = 123
		return assert.same(obj.stored_test, 123)
	end)
	it("should work with <add> metamethod", function()
		local obj = setmetatable({
			value = 10
		}, {
			__add = function(a, b)
				return a.value + b.value
			end
		})
		local obj2 = setmetatable({
			value = 20
		}, {
			__add = function(a, b)
				return a.value + b.value
			end
		})
		local result = obj + obj2
		return assert.same(result, 30)
	end)
	it("should work with <call> metamethod", function()
		local obj = setmetatable({ }, {
			__call = function(self, x)
				return x * 2
			end
		})
		local result = obj(5)
		return assert.same(result, 10)
	end)
	it("should work with <tostring> metamethod", function()
		local obj = setmetatable({
			value = 42
		}, {
			__tostring = function(self)
				return "Value: " .. tostring(self.value)
			end
		})
		local result = tostring(obj)
		return assert.same(result, "Value: 42")
	end)
	it("should work with <eq> metamethod", function()
		local obj1 = setmetatable({
			id = 1
		}, {
			__eq = function(a, b)
				return a.id == b.id
			end
		})
		local obj2 = setmetatable({
			id = 1
		}, {
			__eq = function(a, b)
				return a.id == b.id
			end
		})
		return assert.is_true(obj1 == obj2)
	end)
	it("should destructure metatable", function()
		local obj = setmetatable({ }, {
			new = function()
				return "new result"
			end,
			update = function()
				return "update result"
			end
		})
		local new, update
		do
			local _obj_0 = getmetatable(obj)
			new, update = _obj_0.new, _obj_0.update
		end
		assert.is_true(type(new) == "function")
		return assert.is_true(type(update) == "function")
	end)
	it("should check if two objects have same metatable", function()
		local mt = {
			value = 100
		}
		local obj1 = setmetatable({ }, mt)
		local obj2 = setmetatable({ }, mt)
		return assert.is_true(getmetatable(obj1) == getmetatable(obj2))
	end)
	return it("should work with <concat> metamethod", function()
		local obj = setmetatable({
			value = "hello"
		}, {
			__concat = function(a, b)
				return a.value .. b
			end
		})
		local result = obj .. " world"
		return assert.same(result, "hello world")
	end)
end)