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