2
0

events.lua 12 KB

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