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