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/nextvar.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/nextvar.lua')
| -rw-r--r-- | testes/nextvar.lua | 669 |
1 files changed, 669 insertions, 0 deletions
diff --git a/testes/nextvar.lua b/testes/nextvar.lua new file mode 100644 index 00000000..3ac3acd9 --- /dev/null +++ b/testes/nextvar.lua | |||
| @@ -0,0 +1,669 @@ | |||
| 1 | -- $Id: nextvar.lua,v 1.85 2018/06/19 12:24:19 roberto Exp $ | ||
| 2 | -- See Copyright Notice in file all.lua | ||
| 3 | |||
| 4 | print('testing tables, next, and for') | ||
| 5 | |||
| 6 | local function checkerror (msg, f, ...) | ||
| 7 | local s, err = pcall(f, ...) | ||
| 8 | assert(not s and string.find(err, msg)) | ||
| 9 | end | ||
| 10 | |||
| 11 | |||
| 12 | local a = {} | ||
| 13 | |||
| 14 | -- make sure table has lots of space in hash part | ||
| 15 | for i=1,100 do a[i.."+"] = true end | ||
| 16 | for i=1,100 do a[i.."+"] = undef end | ||
| 17 | -- fill hash part with numeric indices testing size operator | ||
| 18 | for i=1,100 do | ||
| 19 | a[i] = true | ||
| 20 | assert(#a == i) | ||
| 21 | end | ||
| 22 | |||
| 23 | -- testing ipairs | ||
| 24 | local x = 0 | ||
| 25 | for k,v in ipairs{10,20,30;x=12} do | ||
| 26 | x = x + 1 | ||
| 27 | assert(k == x and v == x * 10) | ||
| 28 | end | ||
| 29 | |||
| 30 | for _ in ipairs{x=12, y=24} do assert(nil) end | ||
| 31 | |||
| 32 | -- test for 'false' x ipair | ||
| 33 | x = false | ||
| 34 | local i = 0 | ||
| 35 | for k,v in ipairs{true,false,true,false} do | ||
| 36 | i = i + 1 | ||
| 37 | x = not x | ||
| 38 | assert(x == v) | ||
| 39 | end | ||
| 40 | assert(i == 4) | ||
| 41 | |||
| 42 | -- iterator function is always the same | ||
| 43 | assert(type(ipairs{}) == 'function' and ipairs{} == ipairs{}) | ||
| 44 | |||
| 45 | |||
| 46 | if not T then | ||
| 47 | (Message or print) | ||
| 48 | ('\n >>> testC not active: skipping tests for table sizes <<<\n') | ||
| 49 | else --[ | ||
| 50 | -- testing table sizes | ||
| 51 | |||
| 52 | local function log2 (x) return math.log(x, 2) end | ||
| 53 | |||
| 54 | local function mp2 (n) -- minimum power of 2 >= n | ||
| 55 | local mp = 2^math.ceil(log2(n)) | ||
| 56 | assert(n == 0 or (mp/2 < n and n <= mp)) | ||
| 57 | return mp | ||
| 58 | end | ||
| 59 | |||
| 60 | local function fb (n) | ||
| 61 | local r, nn = T.int2fb(n) | ||
| 62 | assert(r < 256) | ||
| 63 | return nn | ||
| 64 | end | ||
| 65 | |||
| 66 | -- test fb function | ||
| 67 | for a = 1, 10000 do -- all numbers up to 10^4 | ||
| 68 | local n = fb(a) | ||
| 69 | assert(a <= n and n <= a*1.125) | ||
| 70 | end | ||
| 71 | local a = 1024 -- plus a few up to 2 ^30 | ||
| 72 | local lim = 2^30 | ||
| 73 | while a < lim do | ||
| 74 | local n = fb(a) | ||
| 75 | assert(a <= n and n <= a*1.125) | ||
| 76 | a = math.ceil(a*1.3) | ||
| 77 | end | ||
| 78 | |||
| 79 | |||
| 80 | local function check (t, na, nh) | ||
| 81 | local a, h = T.querytab(t) | ||
| 82 | if a ~= na or h ~= nh then | ||
| 83 | print(na, nh, a, h) | ||
| 84 | assert(nil) | ||
| 85 | end | ||
| 86 | end | ||
| 87 | |||
| 88 | |||
| 89 | -- testing C library sizes | ||
| 90 | do | ||
| 91 | local s = 0 | ||
| 92 | for _ in pairs(math) do s = s + 1 end | ||
| 93 | check(math, 0, mp2(s)) | ||
| 94 | end | ||
| 95 | |||
| 96 | |||
| 97 | -- testing constructor sizes | ||
| 98 | local lim = 40 | ||
| 99 | local s = 'return {' | ||
| 100 | for i=1,lim do | ||
| 101 | s = s..i..',' | ||
| 102 | local s = s | ||
| 103 | for k=0,lim do | ||
| 104 | local t = load(s..'}', '')() | ||
| 105 | assert(#t == i) | ||
| 106 | check(t, fb(i), mp2(k)) | ||
| 107 | s = string.format('%sa%d=%d,', s, k, k) | ||
| 108 | end | ||
| 109 | end | ||
| 110 | |||
| 111 | |||
| 112 | -- tests with unknown number of elements | ||
| 113 | local a = {} | ||
| 114 | for i=1,lim do a[i] = i end -- build auxiliary table | ||
| 115 | for k=0,lim do | ||
| 116 | local a = {table.unpack(a,1,k)} | ||
| 117 | assert(#a == k) | ||
| 118 | check(a, k, 0) | ||
| 119 | a = {1,2,3,table.unpack(a,1,k)} | ||
| 120 | check(a, k+3, 0) | ||
| 121 | assert(#a == k + 3) | ||
| 122 | end | ||
| 123 | |||
| 124 | |||
| 125 | -- testing tables dynamically built | ||
| 126 | local lim = 130 | ||
| 127 | local a = {}; a[2] = 1; check(a, 0, 1) | ||
| 128 | a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) | ||
| 129 | a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) | ||
| 130 | a = {} | ||
| 131 | for i = 1,lim do | ||
| 132 | a[i] = 1 | ||
| 133 | assert(#a == i) | ||
| 134 | check(a, mp2(i), 0) | ||
| 135 | end | ||
| 136 | |||
| 137 | a = {} | ||
| 138 | for i = 1,lim do | ||
| 139 | a['a'..i] = 1 | ||
| 140 | assert(#a == 0) | ||
| 141 | check(a, 0, mp2(i)) | ||
| 142 | end | ||
| 143 | |||
| 144 | a = {} | ||
| 145 | for i=1,16 do a[i] = i end | ||
| 146 | check(a, 16, 0) | ||
| 147 | do | ||
| 148 | for i=1,11 do a[i] = undef end | ||
| 149 | for i=30,50 do a[i] = true; a[i] = undef end -- force a rehash (?) | ||
| 150 | check(a, 0, 8) -- 5 elements in the table | ||
| 151 | a[10] = 1 | ||
| 152 | for i=30,50 do a[i] = true; a[i] = undef end -- force a rehash (?) | ||
| 153 | check(a, 0, 8) -- only 6 elements in the table | ||
| 154 | for i=1,14 do a[i] = true; a[i] = undef end | ||
| 155 | for i=18,50 do a[i] = true; a[i] = undef end -- force a rehash (?) | ||
| 156 | check(a, 0, 4) -- only 2 elements ([15] and [16]) | ||
| 157 | end | ||
| 158 | |||
| 159 | -- reverse filling | ||
| 160 | for i=1,lim do | ||
| 161 | local a = {} | ||
| 162 | for i=i,1,-1 do a[i] = i end -- fill in reverse | ||
| 163 | check(a, mp2(i), 0) | ||
| 164 | end | ||
| 165 | |||
| 166 | -- size tests for vararg | ||
| 167 | lim = 35 | ||
| 168 | function foo (n, ...) | ||
| 169 | local arg = {...} | ||
| 170 | check(arg, n, 0) | ||
| 171 | assert(select('#', ...) == n) | ||
| 172 | arg[n+1] = true | ||
| 173 | check(arg, mp2(n+1), 0) | ||
| 174 | arg.x = true | ||
| 175 | check(arg, mp2(n+1), 1) | ||
| 176 | end | ||
| 177 | local a = {} | ||
| 178 | for i=1,lim do a[i] = true; foo(i, table.unpack(a)) end | ||
| 179 | |||
| 180 | |||
| 181 | -- Table length with limit smaller than maximum value at array | ||
| 182 | local a = {} | ||
| 183 | for i = 1,64 do a[i] = true end -- make its array size 64 | ||
| 184 | for i = 1,64 do a[i] = nil end -- erase all elements | ||
| 185 | assert(T.querytab(a) == 64) -- array part has 64 elements | ||
| 186 | a[32] = true; a[48] = true; -- binary search will find these ones | ||
| 187 | a[51] = true -- binary search will miss this one | ||
| 188 | assert(#a == 48) -- this will set the limit | ||
| 189 | assert(select(4, T.querytab(a)) == 48) -- this is the limit now | ||
| 190 | a[50] = true -- this will set a new limit | ||
| 191 | assert(select(4, T.querytab(a)) == 50) -- this is the limit now | ||
| 192 | -- but the size is larger (and still inside the array part) | ||
| 193 | assert(#a == 51) | ||
| 194 | |||
| 195 | end --] | ||
| 196 | |||
| 197 | |||
| 198 | -- test size operation on tables with nils | ||
| 199 | assert(#{} == 0) | ||
| 200 | assert(#{nil} == 0) | ||
| 201 | assert(#{nil, nil} == 0) | ||
| 202 | assert(#{nil, nil, nil} == 0) | ||
| 203 | assert(#{nil, nil, nil, nil} == 0) | ||
| 204 | assert(#{1, 2, 3, nil, nil} == 3) | ||
| 205 | print'+' | ||
| 206 | |||
| 207 | |||
| 208 | local nofind = {} | ||
| 209 | |||
| 210 | a,b,c = 1,2,3 | ||
| 211 | a,b,c = nil | ||
| 212 | |||
| 213 | |||
| 214 | -- next uses always the same iteraction function | ||
| 215 | assert(next{} == next{}) | ||
| 216 | |||
| 217 | local function find (name) | ||
| 218 | local n,v | ||
| 219 | while 1 do | ||
| 220 | n,v = next(_G, n) | ||
| 221 | if not n then return nofind end | ||
| 222 | assert(_G[n] ~= undef) | ||
| 223 | if n == name then return v end | ||
| 224 | end | ||
| 225 | end | ||
| 226 | |||
| 227 | local function find1 (name) | ||
| 228 | for n,v in pairs(_G) do | ||
| 229 | if n==name then return v end | ||
| 230 | end | ||
| 231 | return nil -- not found | ||
| 232 | end | ||
| 233 | |||
| 234 | |||
| 235 | assert(print==find("print") and print == find1("print")) | ||
| 236 | assert(_G["print"]==find("print")) | ||
| 237 | assert(assert==find1("assert")) | ||
| 238 | assert(nofind==find("return")) | ||
| 239 | assert(not find1("return")) | ||
| 240 | _G["ret" .. "urn"] = undef | ||
| 241 | assert(nofind==find("return")) | ||
| 242 | _G["xxx"] = 1 | ||
| 243 | assert(xxx==find("xxx")) | ||
| 244 | |||
| 245 | -- invalid key to 'next' | ||
| 246 | checkerror("invalid key", next, {10,20}, 3) | ||
| 247 | |||
| 248 | -- both 'pairs' and 'ipairs' need an argument | ||
| 249 | checkerror("bad argument", pairs) | ||
| 250 | checkerror("bad argument", ipairs) | ||
| 251 | |||
| 252 | print('+') | ||
| 253 | |||
| 254 | a = {} | ||
| 255 | for i=0,10000 do | ||
| 256 | if math.fmod(i,10) ~= 0 then | ||
| 257 | a['x'..i] = i | ||
| 258 | end | ||
| 259 | end | ||
| 260 | |||
| 261 | n = {n=0} | ||
| 262 | for i,v in pairs(a) do | ||
| 263 | n.n = n.n+1 | ||
| 264 | assert(i and v and a[i] == v) | ||
| 265 | end | ||
| 266 | assert(n.n == 9000) | ||
| 267 | a = nil | ||
| 268 | |||
| 269 | do -- clear global table | ||
| 270 | local a = {} | ||
| 271 | for n,v in pairs(_G) do a[n]=v end | ||
| 272 | for n,v in pairs(a) do | ||
| 273 | if not package.loaded[n] and type(v) ~= "function" and | ||
| 274 | not string.find(n, "^[%u_]") then | ||
| 275 | _G[n] = undef | ||
| 276 | end | ||
| 277 | collectgarbage() | ||
| 278 | end | ||
| 279 | end | ||
| 280 | |||
| 281 | |||
| 282 | -- | ||
| 283 | |||
| 284 | local function checknext (a) | ||
| 285 | local b = {} | ||
| 286 | do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end | ||
| 287 | for k,v in pairs(b) do assert(a[k] == v) end | ||
| 288 | for k,v in pairs(a) do assert(b[k] == v) end | ||
| 289 | end | ||
| 290 | |||
| 291 | checknext{1,x=1,y=2,z=3} | ||
| 292 | checknext{1,2,x=1,y=2,z=3} | ||
| 293 | checknext{1,2,3,x=1,y=2,z=3} | ||
| 294 | checknext{1,2,3,4,x=1,y=2,z=3} | ||
| 295 | checknext{1,2,3,4,5,x=1,y=2,z=3} | ||
| 296 | |||
| 297 | assert(#{} == 0) | ||
| 298 | assert(#{[-1] = 2} == 0) | ||
| 299 | for i=0,40 do | ||
| 300 | local a = {} | ||
| 301 | for j=1,i do a[j]=j end | ||
| 302 | assert(#a == i) | ||
| 303 | end | ||
| 304 | |||
| 305 | -- 'maxn' is now deprecated, but it is easily defined in Lua | ||
| 306 | function table.maxn (t) | ||
| 307 | local max = 0 | ||
| 308 | for k in pairs(t) do | ||
| 309 | max = (type(k) == 'number') and math.max(max, k) or max | ||
| 310 | end | ||
| 311 | return max | ||
| 312 | end | ||
| 313 | |||
| 314 | assert(table.maxn{} == 0) | ||
| 315 | assert(table.maxn{["1000"] = true} == 0) | ||
| 316 | assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) | ||
| 317 | assert(table.maxn{[1000] = true} == 1000) | ||
| 318 | assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) | ||
| 319 | |||
| 320 | table.maxn = nil | ||
| 321 | |||
| 322 | -- int overflow | ||
| 323 | a = {} | ||
| 324 | for i=0,50 do a[2^i] = true end | ||
| 325 | assert(a[#a]) | ||
| 326 | |||
| 327 | print('+') | ||
| 328 | |||
| 329 | |||
| 330 | do -- testing 'next' with all kinds of keys | ||
| 331 | local a = { | ||
| 332 | [1] = 1, -- integer | ||
| 333 | [1.1] = 2, -- float | ||
| 334 | ['x'] = 3, -- short string | ||
| 335 | [string.rep('x', 1000)] = 4, -- long string | ||
| 336 | [print] = 5, -- C function | ||
| 337 | [checkerror] = 6, -- Lua function | ||
| 338 | [coroutine.running()] = 7, -- thread | ||
| 339 | [true] = 8, -- boolean | ||
| 340 | [io.stdin] = 9, -- userdata | ||
| 341 | [{}] = 10, -- table | ||
| 342 | } | ||
| 343 | local b = {}; for i = 1, 10 do b[i] = true end | ||
| 344 | for k, v in pairs(a) do | ||
| 345 | assert(b[v]); b[v] = undef | ||
| 346 | end | ||
| 347 | assert(next(b) == nil) -- 'b' now is empty | ||
| 348 | end | ||
| 349 | |||
| 350 | |||
| 351 | -- erasing values | ||
| 352 | local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, | ||
| 353 | [100.3] = 4, [4] = 5} | ||
| 354 | |||
| 355 | local n = 0 | ||
| 356 | for k, v in pairs( t ) do | ||
| 357 | n = n+1 | ||
| 358 | assert(t[k] == v) | ||
| 359 | t[k] = undef | ||
| 360 | collectgarbage() | ||
| 361 | assert(t[k] == undef) | ||
| 362 | end | ||
| 363 | assert(n == 5) | ||
| 364 | |||
| 365 | |||
| 366 | local function test (a) | ||
| 367 | assert(not pcall(table.insert, a, 2, 20)); | ||
| 368 | table.insert(a, 10); table.insert(a, 2, 20); | ||
| 369 | table.insert(a, 1, -1); table.insert(a, 40); | ||
| 370 | table.insert(a, #a+1, 50) | ||
| 371 | table.insert(a, 2, -2) | ||
| 372 | assert(a[2] ~= undef) | ||
| 373 | assert(a["2"] == undef) | ||
| 374 | assert(not pcall(table.insert, a, 0, 20)); | ||
| 375 | assert(not pcall(table.insert, a, #a + 2, 20)); | ||
| 376 | assert(table.remove(a,1) == -1) | ||
| 377 | assert(table.remove(a,1) == -2) | ||
| 378 | assert(table.remove(a,1) == 10) | ||
| 379 | assert(table.remove(a,1) == 20) | ||
| 380 | assert(table.remove(a,1) == 40) | ||
| 381 | assert(table.remove(a,1) == 50) | ||
| 382 | assert(table.remove(a,1) == nil) | ||
| 383 | assert(table.remove(a) == nil) | ||
| 384 | assert(table.remove(a, #a) == nil) | ||
| 385 | end | ||
| 386 | |||
| 387 | a = {n=0, [-7] = "ban"} | ||
| 388 | test(a) | ||
| 389 | assert(a.n == 0 and a[-7] == "ban") | ||
| 390 | |||
| 391 | a = {[-7] = "ban"}; | ||
| 392 | test(a) | ||
| 393 | assert(a.n == nil and #a == 0 and a[-7] == "ban") | ||
| 394 | |||
| 395 | a = {[-1] = "ban"} | ||
| 396 | test(a) | ||
| 397 | assert(#a == 0 and table.remove(a) == nil and a[-1] == "ban") | ||
| 398 | |||
| 399 | a = {[0] = "ban"} | ||
| 400 | assert(#a == 0 and table.remove(a) == "ban" and a[0] == undef) | ||
| 401 | |||
| 402 | table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) | ||
| 403 | assert(table.remove(a) == 10) | ||
| 404 | assert(table.remove(a) == 20) | ||
| 405 | assert(table.remove(a) == -1) | ||
| 406 | assert(table.remove(a) == nil) | ||
| 407 | |||
| 408 | a = {'c', 'd'} | ||
| 409 | table.insert(a, 3, 'a') | ||
| 410 | table.insert(a, 'b') | ||
| 411 | assert(table.remove(a, 1) == 'c') | ||
| 412 | assert(table.remove(a, 1) == 'd') | ||
| 413 | assert(table.remove(a, 1) == 'a') | ||
| 414 | assert(table.remove(a, 1) == 'b') | ||
| 415 | assert(table.remove(a, 1) == nil) | ||
| 416 | assert(#a == 0 and a.n == nil) | ||
| 417 | |||
| 418 | a = {10,20,30,40} | ||
| 419 | assert(table.remove(a, #a + 1) == nil) | ||
| 420 | assert(not pcall(table.remove, a, 0)) | ||
| 421 | assert(a[#a] == 40) | ||
| 422 | assert(table.remove(a, #a) == 40) | ||
| 423 | assert(a[#a] == 30) | ||
| 424 | assert(table.remove(a, 2) == 20) | ||
| 425 | assert(a[#a] == 30 and #a == 2) | ||
| 426 | |||
| 427 | do -- testing table library with metamethods | ||
| 428 | local function test (proxy, t) | ||
| 429 | for i = 1, 10 do | ||
| 430 | table.insert(proxy, 1, i) | ||
| 431 | end | ||
| 432 | assert(#proxy == 10 and #t == 10 and proxy[1] ~= undef) | ||
| 433 | for i = 1, 10 do | ||
| 434 | assert(t[i] == 11 - i) | ||
| 435 | end | ||
| 436 | table.sort(proxy) | ||
| 437 | for i = 1, 10 do | ||
| 438 | assert(t[i] == i and proxy[i] == i) | ||
| 439 | end | ||
| 440 | assert(table.concat(proxy, ",") == "1,2,3,4,5,6,7,8,9,10") | ||
| 441 | for i = 1, 8 do | ||
| 442 | assert(table.remove(proxy, 1) == i) | ||
| 443 | end | ||
| 444 | assert(#proxy == 2 and #t == 2) | ||
| 445 | local a, b, c = table.unpack(proxy) | ||
| 446 | assert(a == 9 and b == 10 and c == nil) | ||
| 447 | end | ||
| 448 | |||
| 449 | -- all virtual | ||
| 450 | local t = {} | ||
| 451 | local proxy = setmetatable({}, { | ||
| 452 | __len = function () return #t end, | ||
| 453 | __index = t, | ||
| 454 | __newindex = t, | ||
| 455 | }) | ||
| 456 | test(proxy, t) | ||
| 457 | |||
| 458 | -- only __newindex | ||
| 459 | local count = 0 | ||
| 460 | t = setmetatable({}, { | ||
| 461 | __newindex = function (t,k,v) count = count + 1; rawset(t,k,v) end}) | ||
| 462 | test(t, t) | ||
| 463 | assert(count == 10) -- after first 10, all other sets are not new | ||
| 464 | |||
| 465 | -- no __newindex | ||
| 466 | t = setmetatable({}, { | ||
| 467 | __index = function (_,k) return k + 1 end, | ||
| 468 | __len = function (_) return 5 end}) | ||
| 469 | assert(table.concat(t, ";") == "2;3;4;5;6") | ||
| 470 | |||
| 471 | end | ||
| 472 | |||
| 473 | |||
| 474 | if not T then | ||
| 475 | (Message or print) | ||
| 476 | ('\n >>> testC not active: skipping tests for table library on non-tables <<<\n') | ||
| 477 | else --[ | ||
| 478 | local debug = require'debug' | ||
| 479 | local tab = {10, 20, 30} | ||
| 480 | local mt = {} | ||
| 481 | local u = T.newuserdata(0) | ||
| 482 | checkerror("table expected", table.insert, u, 40) | ||
| 483 | checkerror("table expected", table.remove, u) | ||
| 484 | debug.setmetatable(u, mt) | ||
| 485 | checkerror("table expected", table.insert, u, 40) | ||
| 486 | checkerror("table expected", table.remove, u) | ||
| 487 | mt.__index = tab | ||
| 488 | checkerror("table expected", table.insert, u, 40) | ||
| 489 | checkerror("table expected", table.remove, u) | ||
| 490 | mt.__newindex = tab | ||
| 491 | checkerror("table expected", table.insert, u, 40) | ||
| 492 | checkerror("table expected", table.remove, u) | ||
| 493 | mt.__len = function () return #tab end | ||
| 494 | table.insert(u, 40) | ||
| 495 | assert(#u == 4 and #tab == 4 and u[4] == 40 and tab[4] == 40) | ||
| 496 | assert(table.remove(u) == 40) | ||
| 497 | table.insert(u, 1, 50) | ||
| 498 | assert(#u == 4 and #tab == 4 and u[4] == 30 and tab[1] == 50) | ||
| 499 | |||
| 500 | mt.__newindex = nil | ||
| 501 | mt.__len = nil | ||
| 502 | local tab2 = {} | ||
| 503 | local u2 = T.newuserdata(0) | ||
| 504 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) | ||
| 505 | table.move(u, 1, 4, 1, u2) | ||
| 506 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) | ||
| 507 | |||
| 508 | end -- ] | ||
| 509 | |||
| 510 | print('+') | ||
| 511 | |||
| 512 | a = {} | ||
| 513 | for i=1,1000 do | ||
| 514 | a[i] = i; a[i - 1] = undef | ||
| 515 | end | ||
| 516 | assert(next(a,nil) == 1000 and next(a,1000) == nil) | ||
| 517 | |||
| 518 | assert(next({}) == nil) | ||
| 519 | assert(next({}, nil) == nil) | ||
| 520 | |||
| 521 | for a,b in pairs{} do error"not here" end | ||
| 522 | for i=1,0 do error'not here' end | ||
| 523 | for i=0,1,-1 do error'not here' end | ||
| 524 | a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) | ||
| 525 | a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) | ||
| 526 | |||
| 527 | do | ||
| 528 | print("testing floats in numeric for") | ||
| 529 | local a | ||
| 530 | -- integer count | ||
| 531 | a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) | ||
| 532 | a = 0; for i=10000, 1e4, -1 do a=a+1 end; assert(a==1) | ||
| 533 | a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) | ||
| 534 | a = 0; for i=9999, 1e4, -1 do a=a+1 end; assert(a==0) | ||
| 535 | a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) | ||
| 536 | |||
| 537 | -- float count | ||
| 538 | a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) | ||
| 539 | a = 0; for i=1.0, 1, 1 do a=a+1 end; assert(a==1) | ||
| 540 | a = 0; for i=-1.5, -1.5, 1 do a=a+1 end; assert(a==1) | ||
| 541 | a = 0; for i=1e6, 1e6, -1 do a=a+1 end; assert(a==1) | ||
| 542 | a = 0; for i=1.0, 0.99999, 1 do a=a+1 end; assert(a==0) | ||
| 543 | a = 0; for i=99999, 1e5, -1.0 do a=a+1 end; assert(a==0) | ||
| 544 | a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1) | ||
| 545 | end | ||
| 546 | |||
| 547 | -- conversion | ||
| 548 | a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) | ||
| 549 | |||
| 550 | do -- checking types | ||
| 551 | local c | ||
| 552 | local function checkfloat (i) | ||
| 553 | assert(math.type(i) == "float") | ||
| 554 | c = c + 1 | ||
| 555 | end | ||
| 556 | |||
| 557 | c = 0; for i = 1.0, 10 do checkfloat(i) end | ||
| 558 | assert(c == 10) | ||
| 559 | |||
| 560 | c = 0; for i = -1, -10, -1.0 do checkfloat(i) end | ||
| 561 | assert(c == 10) | ||
| 562 | |||
| 563 | local function checkint (i) | ||
| 564 | assert(math.type(i) == "integer") | ||
| 565 | c = c + 1 | ||
| 566 | end | ||
| 567 | |||
| 568 | local m = math.maxinteger | ||
| 569 | c = 0; for i = m, m - 10, -1 do checkint(i) end | ||
| 570 | assert(c == 11) | ||
| 571 | |||
| 572 | c = 0; for i = 1, 10.9 do checkint(i) end | ||
| 573 | assert(c == 10) | ||
| 574 | |||
| 575 | c = 0; for i = 10, 0.001, -1 do checkint(i) end | ||
| 576 | assert(c == 10) | ||
| 577 | |||
| 578 | c = 0; for i = 1, "10.8" do checkint(i) end | ||
| 579 | assert(c == 10) | ||
| 580 | |||
| 581 | c = 0; for i = 9, "3.4", -1 do checkint(i) end | ||
| 582 | assert(c == 6) | ||
| 583 | |||
| 584 | c = 0; for i = 0, " -3.4 ", -1 do checkint(i) end | ||
| 585 | assert(c == 4) | ||
| 586 | |||
| 587 | c = 0; for i = 100, "96.3", -2 do checkint(i) end | ||
| 588 | assert(c == 2) | ||
| 589 | |||
| 590 | c = 0; for i = 1, math.huge do if i > 10 then break end; checkint(i) end | ||
| 591 | assert(c == 10) | ||
| 592 | |||
| 593 | c = 0; for i = -1, -math.huge, -1 do | ||
| 594 | if i < -10 then break end; checkint(i) | ||
| 595 | end | ||
| 596 | assert(c == 10) | ||
| 597 | |||
| 598 | |||
| 599 | for i = math.mininteger, -10e100 do assert(false) end | ||
| 600 | for i = math.maxinteger, 10e100, -1 do assert(false) end | ||
| 601 | |||
| 602 | end | ||
| 603 | |||
| 604 | collectgarbage() | ||
| 605 | |||
| 606 | |||
| 607 | -- testing generic 'for' | ||
| 608 | |||
| 609 | local function f (n, p) | ||
| 610 | local t = {}; for i=1,p do t[i] = i*10 end | ||
| 611 | return function (_,n) | ||
| 612 | if n > 0 then | ||
| 613 | n = n-1 | ||
| 614 | return n, table.unpack(t) | ||
| 615 | end | ||
| 616 | end, nil, n | ||
| 617 | end | ||
| 618 | |||
| 619 | local x = 0 | ||
| 620 | for n,a,b,c,d in f(5,3) do | ||
| 621 | x = x+1 | ||
| 622 | assert(a == 10 and b == 20 and c == 30 and d == nil) | ||
| 623 | end | ||
| 624 | assert(x == 5) | ||
| 625 | |||
| 626 | |||
| 627 | |||
| 628 | -- testing __pairs and __ipairs metamethod | ||
| 629 | a = {} | ||
| 630 | do | ||
| 631 | local x,y,z = pairs(a) | ||
| 632 | assert(type(x) == 'function' and y == a and z == nil) | ||
| 633 | end | ||
| 634 | |||
| 635 | local function foo (e,i) | ||
| 636 | assert(e == a) | ||
| 637 | if i <= 10 then return i+1, i+2 end | ||
| 638 | end | ||
| 639 | |||
| 640 | local function foo1 (e,i) | ||
| 641 | i = i + 1 | ||
| 642 | assert(e == a) | ||
| 643 | if i <= e.n then return i,a[i] end | ||
| 644 | end | ||
| 645 | |||
| 646 | setmetatable(a, {__pairs = function (x) return foo, x, 0 end}) | ||
| 647 | |||
| 648 | local i = 0 | ||
| 649 | for k,v in pairs(a) do | ||
| 650 | i = i + 1 | ||
| 651 | assert(k == i and v == k+1) | ||
| 652 | end | ||
| 653 | |||
| 654 | a.n = 5 | ||
| 655 | a[3] = 30 | ||
| 656 | |||
| 657 | -- testing ipairs with metamethods | ||
| 658 | a = {n=10} | ||
| 659 | setmetatable(a, { __index = function (t,k) | ||
| 660 | if k <= t.n then return k * 10 end | ||
| 661 | end}) | ||
| 662 | i = 0 | ||
| 663 | for k,v in ipairs(a) do | ||
| 664 | i = i + 1 | ||
| 665 | assert(k == i and v == i * 10) | ||
| 666 | end | ||
| 667 | assert(i == a.n) | ||
| 668 | |||
| 669 | print"OK" | ||
