aboutsummaryrefslogtreecommitdiff
path: root/spec/inputs/test/metatable_spec.yue
blob: 9a2ae6aeccfb9314a7e237776638748294337ea0 (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
describe "metatable", ->
	it "should get metatable with <> syntax", ->
		obj = setmetatable {value: 42}, {__index: {extra: "data"}}
		mt = obj.<>
		assert.is_true mt ~= nil

	it "should set metatable with <>", ->
		obj = {}
		obj.<> = {__index: {value: 100}}
		assert.same obj.value, 100

	it "should access metatable with <>", ->
		obj = setmetatable {}, {__index: {value: 50}}
		result = obj.<>.__index.value
		assert.same result, 50

	it "should work with <index> metamethod", ->
		obj = setmetatable {}, {
			__index: (self, key) ->
				if key == "computed"
					return "computed_value"
		}
		assert.same obj.computed, "computed_value"

	it "should work with <newindex> metamethod", ->
		obj = setmetatable {}, {
			__newindex: (self, key, value) ->
				rawset self, "stored_" .. key, value
		}
		obj.test = 123
		assert.same obj.stored_test, 123

	it "should work with <add> metamethod", ->
		obj = setmetatable({value: 10}, {
			__add: (a, b) -> a.value + b.value
		})
		obj2 = setmetatable({value: 20}, {
			__add: (a, b) -> a.value + b.value
		})
		result = obj + obj2
		assert.same result, 30

	it "should work with <call> metamethod", ->
		obj = setmetatable {}, {
			__call: (self, x) -> x * 2
		}
		result = obj 5
		assert.same result, 10

	it "should work with <tostring> metamethod", ->
		obj = setmetatable {value: 42}, {
			__tostring: (self) -> "Value: #{self.value}"
		}
		result = tostring obj
		assert.same result, "Value: 42"

	it "should work with <eq> metamethod", ->
		obj1 = setmetatable({id: 1}, {
			__eq: (a, b) -> a.id == b.id
		})
		obj2 = setmetatable({id: 1}, {
			__eq: (a, b) -> a.id == b.id
		})
		assert.is_true obj1 == obj2

	it "should destructure metatable", ->
		obj = setmetatable {}, {
			new: -> "new result"
			update: -> "update result"
		}
		{:new, :update} = obj.<>
		assert.is_true type(new) == "function"
		assert.is_true type(update) == "function"

	it "should check if two objects have same metatable", ->
		mt = {value: 100}
		obj1 = setmetatable {}, mt
		obj2 = setmetatable {}, mt
		assert.is_true obj1.<> == obj2.<>

	it "should work with <concat> metamethod", ->
		obj = setmetatable {value: "hello"}, {
			__concat: (a, b) -> a.value .. b
		}
		result = obj .. " world"
		assert.same result, "hello world"