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