diff options
Diffstat (limited to '')
-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" | ||