diff options
Diffstat (limited to 'testes/events.lua')
-rw-r--r-- | testes/events.lua | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/testes/events.lua b/testes/events.lua new file mode 100644 index 00000000..9136f99c --- /dev/null +++ b/testes/events.lua | |||
@@ -0,0 +1,456 @@ | |||
1 | -- $Id: events.lua,v 1.45 2016/12/21 19:23:02 roberto Exp $ | ||
2 | -- See Copyright Notice in file all.lua | ||
3 | |||
4 | print('testing metatables') | ||
5 | |||
6 | local debug = require'debug' | ||
7 | |||
8 | X = 20; B = 30 | ||
9 | |||
10 | _ENV = setmetatable({}, {__index=_G}) | ||
11 | |||
12 | collectgarbage() | ||
13 | |||
14 | X = X+10 | ||
15 | assert(X == 30 and _G.X == 20) | ||
16 | B = false | ||
17 | assert(B == false) | ||
18 | B = nil | ||
19 | assert(B == 30) | ||
20 | |||
21 | assert(getmetatable{} == nil) | ||
22 | assert(getmetatable(4) == nil) | ||
23 | assert(getmetatable(nil) == nil) | ||
24 | a={name = "NAME"}; setmetatable(a, {__metatable = "xuxu", | ||
25 | __tostring=function(x) return x.name end}) | ||
26 | assert(getmetatable(a) == "xuxu") | ||
27 | assert(tostring(a) == "NAME") | ||
28 | -- cannot change a protected metatable | ||
29 | assert(pcall(setmetatable, a, {}) == false) | ||
30 | a.name = "gororoba" | ||
31 | assert(tostring(a) == "gororoba") | ||
32 | |||
33 | local a, t = {10,20,30; x="10", y="20"}, {} | ||
34 | assert(setmetatable(a,t) == a) | ||
35 | assert(getmetatable(a) == t) | ||
36 | assert(setmetatable(a,nil) == a) | ||
37 | assert(getmetatable(a) == nil) | ||
38 | assert(setmetatable(a,t) == a) | ||
39 | |||
40 | |||
41 | function f (t, i, e) | ||
42 | assert(not e) | ||
43 | local p = rawget(t, "parent") | ||
44 | return (p and p[i]+3), "dummy return" | ||
45 | end | ||
46 | |||
47 | t.__index = f | ||
48 | |||
49 | a.parent = {z=25, x=12, [4] = 24} | ||
50 | assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") | ||
51 | |||
52 | collectgarbage() | ||
53 | |||
54 | a = setmetatable({}, t) | ||
55 | function f(t, i, v) rawset(t, i, v-3) end | ||
56 | setmetatable(t, t) -- causes a bug in 5.1 ! | ||
57 | t.__newindex = f | ||
58 | a[1] = 30; a.x = "101"; a[5] = 200 | ||
59 | assert(a[1] == 27 and a.x == 98 and a[5] == 197) | ||
60 | |||
61 | do -- bug in Lua 5.3.2 | ||
62 | local mt = {} | ||
63 | mt.__newindex = mt | ||
64 | local t = setmetatable({}, mt) | ||
65 | t[1] = 10 -- will segfault on some machines | ||
66 | assert(mt[1] == 10) | ||
67 | end | ||
68 | |||
69 | |||
70 | local c = {} | ||
71 | a = setmetatable({}, t) | ||
72 | t.__newindex = c | ||
73 | a[1] = 10; a[2] = 20; a[3] = 90 | ||
74 | assert(c[1] == 10 and c[2] == 20 and c[3] == 90) | ||
75 | |||
76 | |||
77 | do | ||
78 | local a; | ||
79 | a = setmetatable({}, {__index = setmetatable({}, | ||
80 | {__index = setmetatable({}, | ||
81 | {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) | ||
82 | a[0] = 20 | ||
83 | for i=0,10 do | ||
84 | assert(a[i*3] == 20 + i*4) | ||
85 | end | ||
86 | end | ||
87 | |||
88 | |||
89 | do -- newindex | ||
90 | local foi | ||
91 | local a = {} | ||
92 | for i=1,10 do a[i] = 0; a['a'..i] = 0; end | ||
93 | setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) | ||
94 | foi = false; a[1]=0; assert(not foi) | ||
95 | foi = false; a['a1']=0; assert(not foi) | ||
96 | foi = false; a['a11']=0; assert(foi) | ||
97 | foi = false; a[11]=0; assert(foi) | ||
98 | foi = false; a[1]=nil; assert(not foi) | ||
99 | foi = false; a[1]=nil; assert(foi) | ||
100 | end | ||
101 | |||
102 | |||
103 | setmetatable(t, nil) | ||
104 | function f (t, ...) return t, {...} end | ||
105 | t.__call = f | ||
106 | |||
107 | do | ||
108 | local x,y = a(table.unpack{'a', 1}) | ||
109 | assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) | ||
110 | x,y = a() | ||
111 | assert(x==a and y[1]==nil) | ||
112 | end | ||
113 | |||
114 | |||
115 | local b = setmetatable({}, t) | ||
116 | setmetatable(b,t) | ||
117 | |||
118 | function f(op) | ||
119 | return function (...) cap = {[0] = op, ...} ; return (...) end | ||
120 | end | ||
121 | t.__add = f("add") | ||
122 | t.__sub = f("sub") | ||
123 | t.__mul = f("mul") | ||
124 | t.__div = f("div") | ||
125 | t.__idiv = f("idiv") | ||
126 | t.__mod = f("mod") | ||
127 | t.__unm = f("unm") | ||
128 | t.__pow = f("pow") | ||
129 | t.__len = f("len") | ||
130 | t.__band = f("band") | ||
131 | t.__bor = f("bor") | ||
132 | t.__bxor = f("bxor") | ||
133 | t.__shl = f("shl") | ||
134 | t.__shr = f("shr") | ||
135 | t.__bnot = f("bnot") | ||
136 | |||
137 | assert(b+5 == b) | ||
138 | assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) | ||
139 | assert(b+'5' == b) | ||
140 | assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) | ||
141 | assert(5+b == 5) | ||
142 | assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) | ||
143 | assert('5'+b == '5') | ||
144 | assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) | ||
145 | b=b-3; assert(getmetatable(b) == t) | ||
146 | assert(5-a == 5) | ||
147 | assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) | ||
148 | assert('5'-a == '5') | ||
149 | assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) | ||
150 | assert(a*a == a) | ||
151 | assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) | ||
152 | assert(a/0 == a) | ||
153 | assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) | ||
154 | assert(a%2 == a) | ||
155 | assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) | ||
156 | assert(a // (1/0) == a) | ||
157 | assert(cap[0] == "idiv" and cap[1] == a and cap[2] == 1/0 and cap[3]==nil) | ||
158 | assert(a & "hi" == a) | ||
159 | assert(cap[0] == "band" and cap[1] == a and cap[2] == "hi" and cap[3]==nil) | ||
160 | assert(a | "hi" == a) | ||
161 | assert(cap[0] == "bor" and cap[1] == a and cap[2] == "hi" and cap[3]==nil) | ||
162 | assert("hi" ~ a == "hi") | ||
163 | assert(cap[0] == "bxor" and cap[1] == "hi" and cap[2] == a and cap[3]==nil) | ||
164 | assert(-a == a) | ||
165 | assert(cap[0] == "unm" and cap[1] == a) | ||
166 | assert(a^4 == a) | ||
167 | assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) | ||
168 | assert(a^'4' == a) | ||
169 | assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) | ||
170 | assert(4^a == 4) | ||
171 | assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) | ||
172 | assert('4'^a == '4') | ||
173 | assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) | ||
174 | assert(#a == a) | ||
175 | assert(cap[0] == "len" and cap[1] == a) | ||
176 | assert(~a == a) | ||
177 | assert(cap[0] == "bnot" and cap[1] == a) | ||
178 | assert(a << 3 == a) | ||
179 | assert(cap[0] == "shl" and cap[1] == a and cap[2] == 3) | ||
180 | assert(1.5 >> a == 1.5) | ||
181 | assert(cap[0] == "shr" and cap[1] == 1.5 and cap[2] == a) | ||
182 | |||
183 | |||
184 | -- test for rawlen | ||
185 | t = setmetatable({1,2,3}, {__len = function () return 10 end}) | ||
186 | assert(#t == 10 and rawlen(t) == 3) | ||
187 | assert(rawlen"abc" == 3) | ||
188 | assert(not pcall(rawlen, io.stdin)) | ||
189 | assert(not pcall(rawlen, 34)) | ||
190 | assert(not pcall(rawlen)) | ||
191 | |||
192 | -- rawlen for long strings | ||
193 | assert(rawlen(string.rep('a', 1000)) == 1000) | ||
194 | |||
195 | |||
196 | t = {} | ||
197 | t.__lt = function (a,b,c) | ||
198 | collectgarbage() | ||
199 | assert(c == nil) | ||
200 | if type(a) == 'table' then a = a.x end | ||
201 | if type(b) == 'table' then b = b.x end | ||
202 | return a<b, "dummy" | ||
203 | end | ||
204 | |||
205 | function Op(x) return setmetatable({x=x}, t) end | ||
206 | |||
207 | local function test () | ||
208 | assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1))) | ||
209 | assert(not(1 < Op(1)) and (Op(1) < 2) and not(2 < Op(1))) | ||
210 | assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) | ||
211 | assert(not('a' < Op('a')) and (Op('a') < 'b') and not(Op('b') < Op('a'))) | ||
212 | assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1))) | ||
213 | assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a'))) | ||
214 | assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) | ||
215 | assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) | ||
216 | assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) | ||
217 | assert((1 >= Op(1)) and not(1 >= Op(2)) and (Op(2) >= 1)) | ||
218 | assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) | ||
219 | assert(('a' >= Op('a')) and not(Op('a') >= 'b') and (Op('b') >= Op('a'))) | ||
220 | end | ||
221 | |||
222 | test() | ||
223 | |||
224 | t.__le = function (a,b,c) | ||
225 | assert(c == nil) | ||
226 | if type(a) == 'table' then a = a.x end | ||
227 | if type(b) == 'table' then b = b.x end | ||
228 | return a<=b, "dummy" | ||
229 | end | ||
230 | |||
231 | test() -- retest comparisons, now using both `lt' and `le' | ||
232 | |||
233 | |||
234 | -- test `partial order' | ||
235 | |||
236 | local function rawSet(x) | ||
237 | local y = {} | ||
238 | for _,k in pairs(x) do y[k] = 1 end | ||
239 | return y | ||
240 | end | ||
241 | |||
242 | local function Set(x) | ||
243 | return setmetatable(rawSet(x), t) | ||
244 | end | ||
245 | |||
246 | t.__lt = function (a,b) | ||
247 | for k in pairs(a) do | ||
248 | if not b[k] then return false end | ||
249 | b[k] = nil | ||
250 | end | ||
251 | return next(b) ~= nil | ||
252 | end | ||
253 | |||
254 | t.__le = nil | ||
255 | |||
256 | assert(Set{1,2,3} < Set{1,2,3,4}) | ||
257 | assert(not(Set{1,2,3,4} < Set{1,2,3,4})) | ||
258 | assert((Set{1,2,3,4} <= Set{1,2,3,4})) | ||
259 | assert((Set{1,2,3,4} >= Set{1,2,3,4})) | ||
260 | assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) | ||
261 | |||
262 | t.__le = function (a,b) | ||
263 | for k in pairs(a) do | ||
264 | if not b[k] then return false end | ||
265 | end | ||
266 | return true | ||
267 | end | ||
268 | |||
269 | assert(not (Set{1,3} <= Set{3,5})) -- now its OK! | ||
270 | assert(not(Set{1,3} <= Set{3,5})) | ||
271 | assert(not(Set{1,3} >= Set{3,5})) | ||
272 | |||
273 | t.__eq = function (a,b) | ||
274 | for k in pairs(a) do | ||
275 | if not b[k] then return false end | ||
276 | b[k] = nil | ||
277 | end | ||
278 | return next(b) == nil | ||
279 | end | ||
280 | |||
281 | local s = Set{1,3,5} | ||
282 | assert(s == Set{3,5,1}) | ||
283 | assert(not rawequal(s, Set{3,5,1})) | ||
284 | assert(rawequal(s, s)) | ||
285 | assert(Set{1,3,5,1} == rawSet{3,5,1}) | ||
286 | assert(rawSet{1,3,5,1} == Set{3,5,1}) | ||
287 | assert(Set{1,3,5} ~= Set{3,5,1,6}) | ||
288 | |||
289 | -- '__eq' is not used for table accesses | ||
290 | t[Set{1,3,5}] = 1 | ||
291 | assert(t[Set{1,3,5}] == nil) | ||
292 | |||
293 | |||
294 | if not T then | ||
295 | (Message or print)('\n >>> testC not active: skipping tests for \z | ||
296 | userdata equality <<<\n') | ||
297 | else | ||
298 | local u1 = T.newuserdata(0) | ||
299 | local u2 = T.newuserdata(0) | ||
300 | local u3 = T.newuserdata(0) | ||
301 | assert(u1 ~= u2 and u1 ~= u3) | ||
302 | debug.setuservalue(u1, 1); | ||
303 | debug.setuservalue(u2, 2); | ||
304 | debug.setuservalue(u3, 1); | ||
305 | debug.setmetatable(u1, {__eq = function (a, b) | ||
306 | return debug.getuservalue(a) == debug.getuservalue(b) | ||
307 | end}) | ||
308 | debug.setmetatable(u2, {__eq = function (a, b) | ||
309 | return true | ||
310 | end}) | ||
311 | assert(u1 == u3 and u3 == u1 and u1 ~= u2) | ||
312 | assert(u2 == u1 and u2 == u3 and u3 == u2) | ||
313 | assert(u2 ~= {}) -- different types cannot be equal | ||
314 | end | ||
315 | |||
316 | |||
317 | t.__concat = function (a,b,c) | ||
318 | assert(c == nil) | ||
319 | if type(a) == 'table' then a = a.val end | ||
320 | if type(b) == 'table' then b = b.val end | ||
321 | if A then return a..b | ||
322 | else | ||
323 | return setmetatable({val=a..b}, t) | ||
324 | end | ||
325 | end | ||
326 | |||
327 | c = {val="c"}; setmetatable(c, t) | ||
328 | d = {val="d"}; setmetatable(d, t) | ||
329 | |||
330 | A = true | ||
331 | assert(c..d == 'cd') | ||
332 | assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") | ||
333 | |||
334 | A = false | ||
335 | assert((c..d..c..d).val == 'cdcd') | ||
336 | x = c..d | ||
337 | assert(getmetatable(x) == t and x.val == 'cd') | ||
338 | x = 0 .."a".."b"..c..d.."e".."f".."g" | ||
339 | assert(x.val == "0abcdefg") | ||
340 | |||
341 | |||
342 | -- concat metamethod x numbers (bug in 5.1.1) | ||
343 | c = {} | ||
344 | local x | ||
345 | setmetatable(c, {__concat = function (a,b) | ||
346 | assert(type(a) == "number" and b == c or type(b) == "number" and a == c) | ||
347 | return c | ||
348 | end}) | ||
349 | assert(c..5 == c and 5 .. c == c) | ||
350 | assert(4 .. c .. 5 == c and 4 .. 5 .. 6 .. 7 .. c == c) | ||
351 | |||
352 | |||
353 | -- test comparison compatibilities | ||
354 | local t1, t2, c, d | ||
355 | t1 = {}; c = {}; setmetatable(c, t1) | ||
356 | d = {} | ||
357 | t1.__eq = function () return true end | ||
358 | t1.__lt = function () return true end | ||
359 | setmetatable(d, t1) | ||
360 | assert(c == d and c < d and not(d <= c)) | ||
361 | t2 = {} | ||
362 | t2.__eq = t1.__eq | ||
363 | t2.__lt = t1.__lt | ||
364 | setmetatable(d, t2) | ||
365 | assert(c == d and c < d and not(d <= c)) | ||
366 | |||
367 | |||
368 | |||
369 | -- test for several levels of calls | ||
370 | local i | ||
371 | local tt = { | ||
372 | __call = function (t, ...) | ||
373 | i = i+1 | ||
374 | if t.f then return t.f(...) | ||
375 | else return {...} | ||
376 | end | ||
377 | end | ||
378 | } | ||
379 | |||
380 | local a = setmetatable({}, tt) | ||
381 | local b = setmetatable({f=a}, tt) | ||
382 | local c = setmetatable({f=b}, tt) | ||
383 | |||
384 | i = 0 | ||
385 | x = c(3,4,5) | ||
386 | assert(i == 3 and x[1] == 3 and x[3] == 5) | ||
387 | |||
388 | |||
389 | assert(_G.X == 20) | ||
390 | |||
391 | print'+' | ||
392 | |||
393 | local _g = _G | ||
394 | _ENV = setmetatable({}, {__index=function (_,k) return _g[k] end}) | ||
395 | |||
396 | |||
397 | a = {} | ||
398 | rawset(a, "x", 1, 2, 3) | ||
399 | assert(a.x == 1 and rawget(a, "x", 3) == 1) | ||
400 | |||
401 | print '+' | ||
402 | |||
403 | -- testing metatables for basic types | ||
404 | mt = {__index = function (a,b) return a+b end, | ||
405 | __len = function (x) return math.floor(x) end} | ||
406 | debug.setmetatable(10, mt) | ||
407 | assert(getmetatable(-2) == mt) | ||
408 | assert((10)[3] == 13) | ||
409 | assert((10)["3"] == 13) | ||
410 | assert(#3.45 == 3) | ||
411 | debug.setmetatable(23, nil) | ||
412 | assert(getmetatable(-2) == nil) | ||
413 | |||
414 | debug.setmetatable(true, mt) | ||
415 | assert(getmetatable(false) == mt) | ||
416 | mt.__index = function (a,b) return a or b end | ||
417 | assert((true)[false] == true) | ||
418 | assert((false)[false] == false) | ||
419 | debug.setmetatable(false, nil) | ||
420 | assert(getmetatable(true) == nil) | ||
421 | |||
422 | debug.setmetatable(nil, mt) | ||
423 | assert(getmetatable(nil) == mt) | ||
424 | mt.__add = function (a,b) return (a or 0) + (b or 0) end | ||
425 | assert(10 + nil == 10) | ||
426 | assert(nil + 23 == 23) | ||
427 | assert(nil + nil == 0) | ||
428 | debug.setmetatable(nil, nil) | ||
429 | assert(getmetatable(nil) == nil) | ||
430 | |||
431 | debug.setmetatable(nil, {}) | ||
432 | |||
433 | |||
434 | -- loops in delegation | ||
435 | a = {}; setmetatable(a, a); a.__index = a; a.__newindex = a | ||
436 | assert(not pcall(function (a,b) return a[b] end, a, 10)) | ||
437 | assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true)) | ||
438 | |||
439 | -- bug in 5.1 | ||
440 | T, K, V = nil | ||
441 | grandparent = {} | ||
442 | grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end | ||
443 | |||
444 | parent = {} | ||
445 | parent.__newindex = parent | ||
446 | setmetatable(parent, grandparent) | ||
447 | |||
448 | child = setmetatable({}, parent) | ||
449 | child.foo = 10 --> CRASH (on some machines) | ||
450 | assert(T == parent and K == "foo" and V == 10) | ||
451 | |||
452 | print 'OK' | ||
453 | |||
454 | return 12 | ||
455 | |||
456 | |||