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