github.com/bitxmesh/gopher-lua@v0.0.0-20190327085718-93c344ef97a4/_lua5.1-tests/events.lua (about) 1 print('testing metatables') 2 3 X = 20; B = 30 4 5 setfenv(1, setmetatable({}, {__index=_G})) 6 7 collectgarbage() 8 9 X = X+10 10 assert(X == 30 and _G.X == 20) 11 B = false 12 assert(B == false) 13 B = nil 14 assert(B == 30) 15 16 assert(getmetatable{} == nil) 17 assert(getmetatable(4) == nil) 18 assert(getmetatable(nil) == nil) 19 a={}; setmetatable(a, {__metatable = "xuxu", 20 __tostring=function(x) return x.name end}) 21 assert(getmetatable(a) == "xuxu") 22 assert(tostring(a) == nil) 23 -- cannot change a protected metatable 24 assert(pcall(setmetatable, a, {}) == false) 25 a.name = "gororoba" 26 assert(tostring(a) == "gororoba") 27 28 local a, t = {10,20,30; x="10", y="20"}, {} 29 assert(setmetatable(a,t) == a) 30 assert(getmetatable(a) == t) 31 assert(setmetatable(a,nil) == a) 32 assert(getmetatable(a) == nil) 33 assert(setmetatable(a,t) == a) 34 35 36 function f (t, i, e) 37 assert(not e) 38 local p = rawget(t, "parent") 39 return (p and p[i]+3), "dummy return" 40 end 41 42 t.__index = f 43 44 a.parent = {z=25, x=12, [4] = 24} 45 assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") 46 47 collectgarbage() 48 49 a = setmetatable({}, t) 50 function f(t, i, v) rawset(t, i, v-3) end 51 t.__newindex = f 52 a[1] = 30; a.x = "101"; a[5] = 200 53 assert(a[1] == 27 and a.x == 98 and a[5] == 197) 54 55 56 local c = {} 57 a = setmetatable({}, t) 58 t.__newindex = c 59 a[1] = 10; a[2] = 20; a[3] = 90 60 assert(c[1] == 10 and c[2] == 20 and c[3] == 90) 61 62 63 do 64 local a; 65 a = setmetatable({}, {__index = setmetatable({}, 66 {__index = setmetatable({}, 67 {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) 68 a[0] = 20 69 for i=0,10 do 70 assert(a[i*3] == 20 + i*4) 71 end 72 end 73 74 75 do -- newindex 76 local foi 77 local a = {} 78 for i=1,10 do a[i] = 0; a['a'..i] = 0; end 79 setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) 80 foi = false; a[1]=0; assert(not foi) 81 foi = false; a['a1']=0; assert(not foi) 82 foi = false; a['a11']=0; assert(foi) 83 foi = false; a[11]=0; assert(foi) 84 foi = false; a[1]=nil; assert(not foi) 85 foi = false; a[1]=nil; assert(foi) 86 end 87 88 89 function f (t, ...) return t, {...} end 90 t.__call = f 91 92 do 93 local x,y = a(unpack{'a', 1}) 94 assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) 95 x,y = a() 96 assert(x==a and y[1]==nil) 97 end 98 99 100 local b = setmetatable({}, t) 101 setmetatable(b,t) 102 103 function f(op) 104 return function (...) cap = {[0] = op, ...} ; return (...) end 105 end 106 t.__add = f("add") 107 t.__sub = f("sub") 108 t.__mul = f("mul") 109 t.__div = f("div") 110 t.__mod = f("mod") 111 t.__unm = f("unm") 112 t.__pow = f("pow") 113 114 assert(b+5 == b) 115 assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) 116 assert(b+'5' == b) 117 assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) 118 assert(5+b == 5) 119 assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) 120 assert('5'+b == '5') 121 assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) 122 b=b-3; assert(getmetatable(b) == t) 123 assert(5-a == 5) 124 assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) 125 assert('5'-a == '5') 126 assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) 127 assert(a*a == a) 128 assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) 129 assert(a/0 == a) 130 assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) 131 assert(a%2 == a) 132 assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) 133 assert(-a == a) 134 assert(cap[0] == "unm" and cap[1] == a) 135 assert(a^4 == a) 136 assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) 137 assert(a^'4' == a) 138 assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) 139 assert(4^a == 4) 140 assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) 141 assert('4'^a == '4') 142 assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) 143 144 145 t = {} 146 t.__lt = function (a,b,c) 147 collectgarbage() 148 assert(c == nil) 149 if type(a) == 'table' then a = a.x end 150 if type(b) == 'table' then b = b.x end 151 return a<b, "dummy" 152 end 153 154 function Op(x) return setmetatable({x=x}, t) end 155 156 local function test () 157 assert(not(Op(1)<Op(1)) and (Op(1)<Op(2)) and not(Op(2)<Op(1))) 158 assert(not(Op('a')<Op('a')) and (Op('a')<Op('b')) and not(Op('b')<Op('a'))) 159 assert((Op(1)<=Op(1)) and (Op(1)<=Op(2)) and not(Op(2)<=Op(1))) 160 assert((Op('a')<=Op('a')) and (Op('a')<=Op('b')) and not(Op('b')<=Op('a'))) 161 assert(not(Op(1)>Op(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) 162 assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) 163 assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) 164 assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) 165 end 166 167 test() 168 169 t.__le = function (a,b,c) 170 assert(c == nil) 171 if type(a) == 'table' then a = a.x end 172 if type(b) == 'table' then b = b.x end 173 return a<=b, "dummy" 174 end 175 176 test() -- retest comparisons, now using both `lt' and `le' 177 178 179 -- test `partial order' 180 181 local function Set(x) 182 local y = {} 183 for _,k in pairs(x) do y[k] = 1 end 184 return setmetatable(y, t) 185 end 186 187 t.__lt = function (a,b) 188 for k in pairs(a) do 189 if not b[k] then return false end 190 b[k] = nil 191 end 192 return next(b) ~= nil 193 end 194 195 t.__le = nil 196 197 assert(Set{1,2,3} < Set{1,2,3,4}) 198 assert(not(Set{1,2,3,4} < Set{1,2,3,4})) 199 assert((Set{1,2,3,4} <= Set{1,2,3,4})) 200 assert((Set{1,2,3,4} >= Set{1,2,3,4})) 201 assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) 202 203 t.__le = function (a,b) 204 for k in pairs(a) do 205 if not b[k] then return false end 206 end 207 return true 208 end 209 210 assert(not (Set{1,3} <= Set{3,5})) -- now its OK! 211 assert(not(Set{1,3} <= Set{3,5})) 212 assert(not(Set{1,3} >= Set{3,5})) 213 214 t.__eq = function (a,b) 215 for k in pairs(a) do 216 if not b[k] then return false end 217 b[k] = nil 218 end 219 return next(b) == nil 220 end 221 222 local s = Set{1,3,5} 223 assert(s == Set{3,5,1}) 224 assert(not rawequal(s, Set{3,5,1})) 225 assert(rawequal(s, s)) 226 assert(Set{1,3,5,1} == Set{3,5,1}) 227 assert(Set{1,3,5} ~= Set{3,5,1,6}) 228 t[Set{1,3,5}] = 1 229 assert(t[Set{1,3,5}] == nil) -- `__eq' is not valid for table accesses 230 231 232 t.__concat = function (a,b,c) 233 assert(c == nil) 234 if type(a) == 'table' then a = a.val end 235 if type(b) == 'table' then b = b.val end 236 if A then return a..b 237 else 238 return setmetatable({val=a..b}, t) 239 end 240 end 241 242 c = {val="c"}; setmetatable(c, t) 243 d = {val="d"}; setmetatable(d, t) 244 245 A = true 246 assert(c..d == 'cd') 247 assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") 248 249 A = false 250 x = c..d 251 assert(getmetatable(x) == t and x.val == 'cd') 252 x = 0 .."a".."b"..c..d.."e".."f".."g" 253 assert(x.val == "0abcdefg") 254 255 256 -- test comparison compatibilities 257 local t1, t2, c, d 258 t1 = {}; c = {}; setmetatable(c, t1) 259 d = {} 260 t1.__eq = function () return true end 261 t1.__lt = function () return true end 262 assert(c ~= d and not pcall(function () return c < d end)) 263 setmetatable(d, t1) 264 assert(c == d and c < d and not(d <= c)) 265 t2 = {} 266 t2.__eq = t1.__eq 267 t2.__lt = t1.__lt 268 setmetatable(d, t2) 269 assert(c == d and c < d and not(d <= c)) 270 271 272 273 -- test for several levels of calls 274 local i 275 local tt = { 276 __call = function (t, ...) 277 i = i+1 278 if t.f then return t.f(...) 279 else return {...} 280 end 281 end 282 } 283 284 local a = setmetatable({}, tt) 285 local b = setmetatable({f=a}, tt) 286 local c = setmetatable({f=b}, tt) 287 288 i = 0 289 x = c(3,4,5) 290 assert(i == 3 and x[1] == 3 and x[3] == 5) 291 292 293 assert(_G.X == 20) 294 assert(_G == getfenv(0)) 295 296 print'+' 297 298 local _g = _G 299 setfenv(1, setmetatable({}, {__index=function (_,k) return _g[k] end})) 300 301 --[[ 302 -- testing proxies 303 assert(getmetatable(newproxy()) == nil) 304 assert(getmetatable(newproxy(false)) == nil) 305 306 local u = newproxy(true) 307 308 getmetatable(u).__newindex = function (u,k,v) 309 getmetatable(u)[k] = v 310 end 311 312 getmetatable(u).__index = function (u,k) 313 return getmetatable(u)[k] 314 end 315 316 for i=1,10 do u[i] = i end 317 for i=1,10 do assert(u[i] == i) end 318 319 local k = newproxy(u) 320 assert(getmetatable(k) == getmetatable(u)) 321 322 323 a = {} 324 rawset(a, "x", 1, 2, 3) 325 assert(a.x == 1 and rawget(a, "x", 3) == 1) 326 327 print '+' 328 --]] 329 330 -- testing metatables for basic types 331 mt = {} 332 debug.setmetatable(10, mt) 333 assert(getmetatable(-2) == mt) 334 mt.__index = function (a,b) return a+b end 335 assert((10)[3] == 13) 336 assert((10)["3"] == 13) 337 debug.setmetatable(23, nil) 338 assert(getmetatable(-2) == nil) 339 340 debug.setmetatable(true, mt) 341 assert(getmetatable(false) == mt) 342 mt.__index = function (a,b) return a or b end 343 assert((true)[false] == true) 344 assert((false)[false] == false) 345 debug.setmetatable(false, nil) 346 assert(getmetatable(true) == nil) 347 348 debug.setmetatable(nil, mt) 349 assert(getmetatable(nil) == mt) 350 mt.__add = function (a,b) return (a or 0) + (b or 0) end 351 assert(10 + nil == 10) 352 assert(nil + 23 == 23) 353 assert(nil + nil == 0) 354 debug.setmetatable(nil, nil) 355 assert(getmetatable(nil) == nil) 356 357 debug.setmetatable(nil, {}) 358 359 360 print 'OK' 361 362 return 12