diff options
Diffstat (limited to 'testes/nextvar.lua')
-rw-r--r-- | testes/nextvar.lua | 631 |
1 files changed, 631 insertions, 0 deletions
diff --git a/testes/nextvar.lua b/testes/nextvar.lua new file mode 100644 index 00000000..ce7312e3 --- /dev/null +++ b/testes/nextvar.lua | |||
@@ -0,0 +1,631 @@ | |||
1 | -- $Id: nextvar.lua,v 1.79 2016/11/07 13:11:28 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.."+"] = nil 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] = nil end | ||
149 | for i=30,50 do a[i] = nil end -- force a rehash (?) | ||
150 | check(a, 0, 8) -- only 5 elements in the table | ||
151 | a[10] = 1 | ||
152 | for i=30,50 do a[i] = nil end -- force a rehash (?) | ||
153 | check(a, 0, 8) -- only 6 elements in the table | ||
154 | for i=1,14 do a[i] = nil end | ||
155 | for i=18,50 do a[i] = nil 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 | end --] | ||
181 | |||
182 | |||
183 | -- test size operation on empty tables | ||
184 | assert(#{} == 0) | ||
185 | assert(#{nil} == 0) | ||
186 | assert(#{nil, nil} == 0) | ||
187 | assert(#{nil, nil, nil} == 0) | ||
188 | assert(#{nil, nil, nil, nil} == 0) | ||
189 | print'+' | ||
190 | |||
191 | |||
192 | local nofind = {} | ||
193 | |||
194 | a,b,c = 1,2,3 | ||
195 | a,b,c = nil | ||
196 | |||
197 | |||
198 | -- next uses always the same iteraction function | ||
199 | assert(next{} == next{}) | ||
200 | |||
201 | local function find (name) | ||
202 | local n,v | ||
203 | while 1 do | ||
204 | n,v = next(_G, n) | ||
205 | if not n then return nofind end | ||
206 | assert(v ~= nil) | ||
207 | if n == name then return v end | ||
208 | end | ||
209 | end | ||
210 | |||
211 | local function find1 (name) | ||
212 | for n,v in pairs(_G) do | ||
213 | if n==name then return v end | ||
214 | end | ||
215 | return nil -- not found | ||
216 | end | ||
217 | |||
218 | |||
219 | assert(print==find("print") and print == find1("print")) | ||
220 | assert(_G["print"]==find("print")) | ||
221 | assert(assert==find1("assert")) | ||
222 | assert(nofind==find("return")) | ||
223 | assert(not find1("return")) | ||
224 | _G["ret" .. "urn"] = nil | ||
225 | assert(nofind==find("return")) | ||
226 | _G["xxx"] = 1 | ||
227 | assert(xxx==find("xxx")) | ||
228 | |||
229 | -- invalid key to 'next' | ||
230 | checkerror("invalid key", next, {10,20}, 3) | ||
231 | |||
232 | -- both 'pairs' and 'ipairs' need an argument | ||
233 | checkerror("bad argument", pairs) | ||
234 | checkerror("bad argument", ipairs) | ||
235 | |||
236 | print('+') | ||
237 | |||
238 | a = {} | ||
239 | for i=0,10000 do | ||
240 | if math.fmod(i,10) ~= 0 then | ||
241 | a['x'..i] = i | ||
242 | end | ||
243 | end | ||
244 | |||
245 | n = {n=0} | ||
246 | for i,v in pairs(a) do | ||
247 | n.n = n.n+1 | ||
248 | assert(i and v and a[i] == v) | ||
249 | end | ||
250 | assert(n.n == 9000) | ||
251 | a = nil | ||
252 | |||
253 | do -- clear global table | ||
254 | local a = {} | ||
255 | for n,v in pairs(_G) do a[n]=v end | ||
256 | for n,v in pairs(a) do | ||
257 | if not package.loaded[n] and type(v) ~= "function" and | ||
258 | not string.find(n, "^[%u_]") then | ||
259 | _G[n] = nil | ||
260 | end | ||
261 | collectgarbage() | ||
262 | end | ||
263 | end | ||
264 | |||
265 | |||
266 | -- | ||
267 | |||
268 | local function checknext (a) | ||
269 | local b = {} | ||
270 | do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end | ||
271 | for k,v in pairs(b) do assert(a[k] == v) end | ||
272 | for k,v in pairs(a) do assert(b[k] == v) end | ||
273 | end | ||
274 | |||
275 | checknext{1,x=1,y=2,z=3} | ||
276 | checknext{1,2,x=1,y=2,z=3} | ||
277 | checknext{1,2,3,x=1,y=2,z=3} | ||
278 | checknext{1,2,3,4,x=1,y=2,z=3} | ||
279 | checknext{1,2,3,4,5,x=1,y=2,z=3} | ||
280 | |||
281 | assert(#{} == 0) | ||
282 | assert(#{[-1] = 2} == 0) | ||
283 | assert(#{1,2,3,nil,nil} == 3) | ||
284 | for i=0,40 do | ||
285 | local a = {} | ||
286 | for j=1,i do a[j]=j end | ||
287 | assert(#a == i) | ||
288 | end | ||
289 | |||
290 | -- 'maxn' is now deprecated, but it is easily defined in Lua | ||
291 | function table.maxn (t) | ||
292 | local max = 0 | ||
293 | for k in pairs(t) do | ||
294 | max = (type(k) == 'number') and math.max(max, k) or max | ||
295 | end | ||
296 | return max | ||
297 | end | ||
298 | |||
299 | assert(table.maxn{} == 0) | ||
300 | assert(table.maxn{["1000"] = true} == 0) | ||
301 | assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) | ||
302 | assert(table.maxn{[1000] = true} == 1000) | ||
303 | assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) | ||
304 | |||
305 | table.maxn = nil | ||
306 | |||
307 | -- int overflow | ||
308 | a = {} | ||
309 | for i=0,50 do a[2^i] = true end | ||
310 | assert(a[#a]) | ||
311 | |||
312 | print('+') | ||
313 | |||
314 | |||
315 | -- erasing values | ||
316 | local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, | ||
317 | [100.3] = 4, [4] = 5} | ||
318 | |||
319 | local n = 0 | ||
320 | for k, v in pairs( t ) do | ||
321 | n = n+1 | ||
322 | assert(t[k] == v) | ||
323 | t[k] = nil | ||
324 | collectgarbage() | ||
325 | assert(t[k] == nil) | ||
326 | end | ||
327 | assert(n == 5) | ||
328 | |||
329 | |||
330 | local function test (a) | ||
331 | assert(not pcall(table.insert, a, 2, 20)); | ||
332 | table.insert(a, 10); table.insert(a, 2, 20); | ||
333 | table.insert(a, 1, -1); table.insert(a, 40); | ||
334 | table.insert(a, #a+1, 50) | ||
335 | table.insert(a, 2, -2) | ||
336 | assert(not pcall(table.insert, a, 0, 20)); | ||
337 | assert(not pcall(table.insert, a, #a + 2, 20)); | ||
338 | assert(table.remove(a,1) == -1) | ||
339 | assert(table.remove(a,1) == -2) | ||
340 | assert(table.remove(a,1) == 10) | ||
341 | assert(table.remove(a,1) == 20) | ||
342 | assert(table.remove(a,1) == 40) | ||
343 | assert(table.remove(a,1) == 50) | ||
344 | assert(table.remove(a,1) == nil) | ||
345 | assert(table.remove(a) == nil) | ||
346 | assert(table.remove(a, #a) == nil) | ||
347 | end | ||
348 | |||
349 | a = {n=0, [-7] = "ban"} | ||
350 | test(a) | ||
351 | assert(a.n == 0 and a[-7] == "ban") | ||
352 | |||
353 | a = {[-7] = "ban"}; | ||
354 | test(a) | ||
355 | assert(a.n == nil and #a == 0 and a[-7] == "ban") | ||
356 | |||
357 | a = {[-1] = "ban"} | ||
358 | test(a) | ||
359 | assert(#a == 0 and table.remove(a) == nil and a[-1] == "ban") | ||
360 | |||
361 | a = {[0] = "ban"} | ||
362 | assert(#a == 0 and table.remove(a) == "ban" and a[0] == nil) | ||
363 | |||
364 | table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) | ||
365 | assert(table.remove(a) == 10) | ||
366 | assert(table.remove(a) == 20) | ||
367 | assert(table.remove(a) == -1) | ||
368 | assert(table.remove(a) == nil) | ||
369 | |||
370 | a = {'c', 'd'} | ||
371 | table.insert(a, 3, 'a') | ||
372 | table.insert(a, 'b') | ||
373 | assert(table.remove(a, 1) == 'c') | ||
374 | assert(table.remove(a, 1) == 'd') | ||
375 | assert(table.remove(a, 1) == 'a') | ||
376 | assert(table.remove(a, 1) == 'b') | ||
377 | assert(table.remove(a, 1) == nil) | ||
378 | assert(#a == 0 and a.n == nil) | ||
379 | |||
380 | a = {10,20,30,40} | ||
381 | assert(table.remove(a, #a + 1) == nil) | ||
382 | assert(not pcall(table.remove, a, 0)) | ||
383 | assert(a[#a] == 40) | ||
384 | assert(table.remove(a, #a) == 40) | ||
385 | assert(a[#a] == 30) | ||
386 | assert(table.remove(a, 2) == 20) | ||
387 | assert(a[#a] == 30 and #a == 2) | ||
388 | |||
389 | do -- testing table library with metamethods | ||
390 | local function test (proxy, t) | ||
391 | for i = 1, 10 do | ||
392 | table.insert(proxy, 1, i) | ||
393 | end | ||
394 | assert(#proxy == 10 and #t == 10) | ||
395 | for i = 1, 10 do | ||
396 | assert(t[i] == 11 - i) | ||
397 | end | ||
398 | table.sort(proxy) | ||
399 | for i = 1, 10 do | ||
400 | assert(t[i] == i and proxy[i] == i) | ||
401 | end | ||
402 | assert(table.concat(proxy, ",") == "1,2,3,4,5,6,7,8,9,10") | ||
403 | for i = 1, 8 do | ||
404 | assert(table.remove(proxy, 1) == i) | ||
405 | end | ||
406 | assert(#proxy == 2 and #t == 2) | ||
407 | local a, b, c = table.unpack(proxy) | ||
408 | assert(a == 9 and b == 10 and c == nil) | ||
409 | end | ||
410 | |||
411 | -- all virtual | ||
412 | local t = {} | ||
413 | local proxy = setmetatable({}, { | ||
414 | __len = function () return #t end, | ||
415 | __index = t, | ||
416 | __newindex = t, | ||
417 | }) | ||
418 | test(proxy, t) | ||
419 | |||
420 | -- only __newindex | ||
421 | local count = 0 | ||
422 | t = setmetatable({}, { | ||
423 | __newindex = function (t,k,v) count = count + 1; rawset(t,k,v) end}) | ||
424 | test(t, t) | ||
425 | assert(count == 10) -- after first 10, all other sets are not new | ||
426 | |||
427 | -- no __newindex | ||
428 | t = setmetatable({}, { | ||
429 | __index = function (_,k) return k + 1 end, | ||
430 | __len = function (_) return 5 end}) | ||
431 | assert(table.concat(t, ";") == "2;3;4;5;6") | ||
432 | |||
433 | end | ||
434 | |||
435 | |||
436 | if not T then | ||
437 | (Message or print) | ||
438 | ('\n >>> testC not active: skipping tests for table library on non-tables <<<\n') | ||
439 | else --[ | ||
440 | local debug = require'debug' | ||
441 | local tab = {10, 20, 30} | ||
442 | local mt = {} | ||
443 | local u = T.newuserdata(0) | ||
444 | checkerror("table expected", table.insert, u, 40) | ||
445 | checkerror("table expected", table.remove, u) | ||
446 | debug.setmetatable(u, mt) | ||
447 | checkerror("table expected", table.insert, u, 40) | ||
448 | checkerror("table expected", table.remove, u) | ||
449 | mt.__index = tab | ||
450 | checkerror("table expected", table.insert, u, 40) | ||
451 | checkerror("table expected", table.remove, u) | ||
452 | mt.__newindex = tab | ||
453 | checkerror("table expected", table.insert, u, 40) | ||
454 | checkerror("table expected", table.remove, u) | ||
455 | mt.__len = function () return #tab end | ||
456 | table.insert(u, 40) | ||
457 | assert(#u == 4 and #tab == 4 and u[4] == 40 and tab[4] == 40) | ||
458 | assert(table.remove(u) == 40) | ||
459 | table.insert(u, 1, 50) | ||
460 | assert(#u == 4 and #tab == 4 and u[4] == 30 and tab[1] == 50) | ||
461 | |||
462 | mt.__newindex = nil | ||
463 | mt.__len = nil | ||
464 | local tab2 = {} | ||
465 | local u2 = T.newuserdata(0) | ||
466 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) | ||
467 | table.move(u, 1, 4, 1, u2) | ||
468 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) | ||
469 | |||
470 | end -- ] | ||
471 | |||
472 | print('+') | ||
473 | |||
474 | a = {} | ||
475 | for i=1,1000 do | ||
476 | a[i] = i; a[i-1] = nil | ||
477 | end | ||
478 | assert(next(a,nil) == 1000 and next(a,1000) == nil) | ||
479 | |||
480 | assert(next({}) == nil) | ||
481 | assert(next({}, nil) == nil) | ||
482 | |||
483 | for a,b in pairs{} do error"not here" end | ||
484 | for i=1,0 do error'not here' end | ||
485 | for i=0,1,-1 do error'not here' end | ||
486 | a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) | ||
487 | a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) | ||
488 | |||
489 | do | ||
490 | print("testing floats in numeric for") | ||
491 | local a | ||
492 | -- integer count | ||
493 | a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) | ||
494 | a = 0; for i=10000, 1e4, -1 do a=a+1 end; assert(a==1) | ||
495 | a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) | ||
496 | a = 0; for i=9999, 1e4, -1 do a=a+1 end; assert(a==0) | ||
497 | a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) | ||
498 | |||
499 | -- float count | ||
500 | a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) | ||
501 | a = 0; for i=1.0, 1, 1 do a=a+1 end; assert(a==1) | ||
502 | a = 0; for i=-1.5, -1.5, 1 do a=a+1 end; assert(a==1) | ||
503 | a = 0; for i=1e6, 1e6, -1 do a=a+1 end; assert(a==1) | ||
504 | a = 0; for i=1.0, 0.99999, 1 do a=a+1 end; assert(a==0) | ||
505 | a = 0; for i=99999, 1e5, -1.0 do a=a+1 end; assert(a==0) | ||
506 | a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1) | ||
507 | end | ||
508 | |||
509 | -- conversion | ||
510 | a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) | ||
511 | |||
512 | do -- checking types | ||
513 | local c | ||
514 | local function checkfloat (i) | ||
515 | assert(math.type(i) == "float") | ||
516 | c = c + 1 | ||
517 | end | ||
518 | |||
519 | c = 0; for i = 1.0, 10 do checkfloat(i) end | ||
520 | assert(c == 10) | ||
521 | |||
522 | c = 0; for i = -1, -10, -1.0 do checkfloat(i) end | ||
523 | assert(c == 10) | ||
524 | |||
525 | local function checkint (i) | ||
526 | assert(math.type(i) == "integer") | ||
527 | c = c + 1 | ||
528 | end | ||
529 | |||
530 | local m = math.maxinteger | ||
531 | c = 0; for i = m, m - 10, -1 do checkint(i) end | ||
532 | assert(c == 11) | ||
533 | |||
534 | c = 0; for i = 1, 10.9 do checkint(i) end | ||
535 | assert(c == 10) | ||
536 | |||
537 | c = 0; for i = 10, 0.001, -1 do checkint(i) end | ||
538 | assert(c == 10) | ||
539 | |||
540 | c = 0; for i = 1, "10.8" do checkint(i) end | ||
541 | assert(c == 10) | ||
542 | |||
543 | c = 0; for i = 9, "3.4", -1 do checkint(i) end | ||
544 | assert(c == 6) | ||
545 | |||
546 | c = 0; for i = 0, " -3.4 ", -1 do checkint(i) end | ||
547 | assert(c == 4) | ||
548 | |||
549 | c = 0; for i = 100, "96.3", -2 do checkint(i) end | ||
550 | assert(c == 2) | ||
551 | |||
552 | c = 0; for i = 1, math.huge do if i > 10 then break end; checkint(i) end | ||
553 | assert(c == 10) | ||
554 | |||
555 | c = 0; for i = -1, -math.huge, -1 do | ||
556 | if i < -10 then break end; checkint(i) | ||
557 | end | ||
558 | assert(c == 10) | ||
559 | |||
560 | |||
561 | for i = math.mininteger, -10e100 do assert(false) end | ||
562 | for i = math.maxinteger, 10e100, -1 do assert(false) end | ||
563 | |||
564 | end | ||
565 | |||
566 | collectgarbage() | ||
567 | |||
568 | |||
569 | -- testing generic 'for' | ||
570 | |||
571 | local function f (n, p) | ||
572 | local t = {}; for i=1,p do t[i] = i*10 end | ||
573 | return function (_,n) | ||
574 | if n > 0 then | ||
575 | n = n-1 | ||
576 | return n, table.unpack(t) | ||
577 | end | ||
578 | end, nil, n | ||
579 | end | ||
580 | |||
581 | local x = 0 | ||
582 | for n,a,b,c,d in f(5,3) do | ||
583 | x = x+1 | ||
584 | assert(a == 10 and b == 20 and c == 30 and d == nil) | ||
585 | end | ||
586 | assert(x == 5) | ||
587 | |||
588 | |||
589 | |||
590 | -- testing __pairs and __ipairs metamethod | ||
591 | a = {} | ||
592 | do | ||
593 | local x,y,z = pairs(a) | ||
594 | assert(type(x) == 'function' and y == a and z == nil) | ||
595 | end | ||
596 | |||
597 | local function foo (e,i) | ||
598 | assert(e == a) | ||
599 | if i <= 10 then return i+1, i+2 end | ||
600 | end | ||
601 | |||
602 | local function foo1 (e,i) | ||
603 | i = i + 1 | ||
604 | assert(e == a) | ||
605 | if i <= e.n then return i,a[i] end | ||
606 | end | ||
607 | |||
608 | setmetatable(a, {__pairs = function (x) return foo, x, 0 end}) | ||
609 | |||
610 | local i = 0 | ||
611 | for k,v in pairs(a) do | ||
612 | i = i + 1 | ||
613 | assert(k == i and v == k+1) | ||
614 | end | ||
615 | |||
616 | a.n = 5 | ||
617 | a[3] = 30 | ||
618 | |||
619 | -- testing ipairs with metamethods | ||
620 | a = {n=10} | ||
621 | setmetatable(a, { __index = function (t,k) | ||
622 | if k <= t.n then return k * 10 end | ||
623 | end}) | ||
624 | i = 0 | ||
625 | for k,v in ipairs(a) do | ||
626 | i = i + 1 | ||
627 | assert(k == i and v == i * 10) | ||
628 | end | ||
629 | assert(i == a.n) | ||
630 | |||
631 | print"OK" | ||