github.com/xmx/lua@v0.0.0-20230324063450-8a298e091302/_lua5.1-tests/nextvar.lua (about) 1 print('testing tables, next, and for') 2 3 local a = {} 4 5 -- make sure table has lots of space in hash part 6 for i=1,100 do a[i.."+"] = true end 7 for i=1,100 do a[i.."+"] = nil end 8 -- fill hash part with numeric indices testing size operator 9 for i=1,100 do 10 a[i] = true 11 assert(#a == i) 12 end 13 14 15 if T then 16 -- testing table sizes 17 18 local l2 = math.log(2) 19 local function log2 (x) return math.log(x)/l2 end 20 21 local function mp2 (n) -- minimum power of 2 >= n 22 local mp = 2^math.ceil(log2(n)) 23 assert(n == 0 or (mp/2 < n and n <= mp)) 24 return mp 25 end 26 27 local function fb (n) 28 local r, nn = T.int2fb(n) 29 assert(r < 256) 30 return nn 31 end 32 33 -- test fb function 34 local a = 1 35 local lim = 2^30 36 while a < lim do 37 local n = fb(a) 38 assert(a <= n and n <= a*1.125) 39 a = math.ceil(a*1.3) 40 end 41 42 43 local function check (t, na, nh) 44 local a, h = T.querytab(t) 45 if a ~= na or h ~= nh then 46 print(na, nh, a, h) 47 assert(nil) 48 end 49 end 50 51 -- testing constructor sizes 52 local lim = 40 53 local s = 'return {' 54 for i=1,lim do 55 s = s..i..',' 56 local s = s 57 for k=0,lim do 58 local t = loadstring(s..'}')() 59 assert(#t == i) 60 check(t, fb(i), mp2(k)) 61 s = string.format('%sa%d=%d,', s, k, k) 62 end 63 end 64 65 66 -- tests with unknown number of elements 67 local a = {} 68 for i=1,lim do a[i] = i end -- build auxiliary table 69 for k=0,lim do 70 local a = {unpack(a,1,k)} 71 assert(#a == k) 72 check(a, k, 0) 73 a = {1,2,3,unpack(a,1,k)} 74 check(a, k+3, 0) 75 assert(#a == k + 3) 76 end 77 78 79 print'+' 80 81 -- testing tables dynamically built 82 local lim = 130 83 local a = {}; a[2] = 1; check(a, 0, 1) 84 a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) 85 a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) 86 a = {} 87 for i = 1,lim do 88 a[i] = 1 89 assert(#a == i) 90 check(a, mp2(i), 0) 91 end 92 93 a = {} 94 for i = 1,lim do 95 a['a'..i] = 1 96 assert(#a == 0) 97 check(a, 0, mp2(i)) 98 end 99 100 a = {} 101 for i=1,16 do a[i] = i end 102 check(a, 16, 0) 103 for i=1,11 do a[i] = nil end 104 for i=30,40 do a[i] = nil end -- force a rehash (?) 105 check(a, 0, 8) 106 a[10] = 1 107 for i=30,40 do a[i] = nil end -- force a rehash (?) 108 check(a, 0, 8) 109 for i=1,14 do a[i] = nil end 110 for i=30,50 do a[i] = nil end -- force a rehash (?) 111 check(a, 0, 4) 112 113 -- reverse filling 114 for i=1,lim do 115 local a = {} 116 for i=i,1,-1 do a[i] = i end -- fill in reverse 117 check(a, mp2(i), 0) 118 end 119 120 -- size tests for vararg 121 lim = 35 122 function foo (n, ...) 123 local arg = {...} 124 check(arg, n, 0) 125 assert(select('#', ...) == n) 126 arg[n+1] = true 127 check(arg, mp2(n+1), 0) 128 arg.x = true 129 check(arg, mp2(n+1), 1) 130 end 131 local a = {} 132 for i=1,lim do a[i] = true; foo(i, unpack(a)) end 133 134 end 135 136 137 -- test size operation on empty tables 138 assert(#{} == 0) 139 assert(#{nil} == 0) 140 assert(#{nil, nil} == 0) 141 assert(#{nil, nil, nil} == 0) 142 assert(#{nil, nil, nil, nil} == 0) 143 print'+' 144 145 146 local nofind = {} 147 148 a,b,c = 1,2,3 149 a,b,c = nil 150 151 local function find (name) 152 local n,v 153 while 1 do 154 n,v = next(_G, n) 155 if not n then return nofind end 156 assert(v ~= nil) 157 if n == name then return v end 158 end 159 end 160 161 local function find1 (name) 162 for n,v in pairs(_G) do 163 if n==name then return v end 164 end 165 return nil -- not found 166 end 167 168 do -- create 10000 new global variables 169 for i=1,10000 do _G[i] = i end 170 end 171 172 173 a = {x=90, y=8, z=23} 174 assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90) 175 assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil) 176 table.foreach({}, error) 177 178 table.foreachi({x=10, y=20}, error) 179 local a = {n = 1} 180 table.foreachi({n=3}, function (i, v) 181 assert(a.n == i and not v) 182 a.n=a.n+1 183 end) 184 a = {10,20,30,nil,50} 185 table.foreachi(a, function (i,v) assert(a[i] == v) end) 186 assert(table.foreachi({'a', 'b', 'c'}, function (i,v) 187 if i==2 then return v end 188 end) == 'b') 189 190 191 assert(print==find("print") and print == find1("print")) 192 assert(_G["print"]==find("print")) 193 assert(assert==find1("assert")) 194 assert(nofind==find("return")) 195 assert(not find1("return")) 196 _G["ret" .. "urn"] = nil 197 assert(nofind==find("return")) 198 _G["xxx"] = 1 199 assert(xxx==find("xxx")) 200 print('+') 201 202 a = {} 203 for i=0,10000 do 204 if math.mod(i,10) ~= 0 then 205 a['x'..i] = i 206 end 207 end 208 209 n = {n=0} 210 for i,v in pairs(a) do 211 n.n = n.n+1 212 assert(i and v and a[i] == v) 213 end 214 assert(n.n == 9000) 215 a = nil 216 217 -- remove those 10000 new global variables 218 for i=1,10000 do _G[i] = nil end 219 220 do -- clear global table 221 local a = {} 222 local preserve = {io = 1, string = 1, debug = 1, os = 1, 223 coroutine = 1, table = 1, math = 1} 224 for n,v in pairs(_G) do a[n]=v end 225 for n,v in pairs(a) do 226 if not preserve[n] and type(v) ~= "function" and 227 not string.find(n, "^[%u_]") then 228 _G[n] = nil 229 end 230 collectgarbage() 231 end 232 end 233 234 local function foo () 235 local getfenv, setfenv, assert, next = 236 getfenv, setfenv, assert, next 237 local n = {gl1=3} 238 setfenv(foo, n) 239 assert(getfenv(foo) == getfenv(1)) 240 assert(getfenv(foo) == n) 241 assert(print == nil and gl1 == 3) 242 gl1 = nil 243 gl = 1 244 assert(n.gl == 1 and next(n, 'gl') == nil) 245 end 246 foo() 247 248 print'+' 249 250 local function checknext (a) 251 local b = {} 252 table.foreach(a, function (k,v) b[k] = v end) 253 for k,v in pairs(b) do assert(a[k] == v) end 254 for k,v in pairs(a) do assert(b[k] == v) end 255 b = {} 256 do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end 257 for k,v in pairs(b) do assert(a[k] == v) end 258 for k,v in pairs(a) do assert(b[k] == v) end 259 end 260 261 checknext{1,x=1,y=2,z=3} 262 checknext{1,2,x=1,y=2,z=3} 263 checknext{1,2,3,x=1,y=2,z=3} 264 checknext{1,2,3,4,x=1,y=2,z=3} 265 checknext{1,2,3,4,5,x=1,y=2,z=3} 266 267 assert(table.getn{} == 0) 268 assert(table.getn{[-1] = 2} == 0) 269 assert(table.getn{1,2,3,nil,nil} == 3) 270 for i=0,40 do 271 local a = {} 272 for j=1,i do a[j]=j end 273 assert(table.getn(a) == i) 274 end 275 276 277 assert(table.maxn{} == 0) 278 assert(table.maxn{["1000"] = true} == 0) 279 assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) 280 assert(table.maxn{[1000] = true} == 1000) 281 assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) 282 283 284 -- int overflow 285 a = {} 286 for i=0,50 do a[math.pow(2,i)] = true end 287 assert(a[table.getn(a)]) 288 289 print("+") 290 291 292 -- erasing values 293 local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, 294 [100.3] = 4, [4] = 5} 295 296 local n = 0 297 for k, v in pairs( t ) do 298 n = n+1 299 assert(t[k] == v) 300 t[k] = nil 301 collectgarbage() 302 assert(t[k] == nil) 303 end 304 assert(n == 5) 305 306 307 local function test (a) 308 table.insert(a, 10); table.insert(a, 2, 20); 309 table.insert(a, 1, -1); table.insert(a, 40); 310 table.insert(a, table.getn(a)+1, 50) 311 table.insert(a, 2, -2) 312 assert(table.remove(a,1) == -1) 313 assert(table.remove(a,1) == -2) 314 assert(table.remove(a,1) == 10) 315 assert(table.remove(a,1) == 20) 316 assert(table.remove(a,1) == 40) 317 assert(table.remove(a,1) == 50) 318 assert(table.remove(a,1) == nil) 319 end 320 321 a = {n=0, [-7] = "ban"} 322 test(a) 323 assert(a.n == 0 and a[-7] == "ban") 324 325 a = {[-7] = "ban"}; 326 test(a) 327 assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban") 328 329 330 table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) 331 assert(table.remove(a) == 10) 332 assert(table.remove(a) == 20) 333 assert(table.remove(a) == -1) 334 335 a = {'c', 'd'} 336 table.insert(a, 3, 'a') 337 table.insert(a, 'b') 338 assert(table.remove(a, 1) == 'c') 339 assert(table.remove(a, 1) == 'd') 340 assert(table.remove(a, 1) == 'a') 341 assert(table.remove(a, 1) == 'b') 342 assert(table.getn(a) == 0 and a.n == nil) 343 print("+") 344 345 a = {} 346 for i=1,1000 do 347 a[i] = i; a[i-1] = nil 348 end 349 assert(next(a,nil) == 1000 and next(a,1000) == nil) 350 351 assert(next({}) == nil) 352 assert(next({}, nil) == nil) 353 354 for a,b in pairs{} do error"not here" end 355 for i=1,0 do error'not here' end 356 for i=0,1,-1 do error'not here' end 357 a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) 358 a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) 359 360 a = 0; for i=0, 1, 0.1 do a=a+1 end; assert(a==11) 361 -- precision problems 362 --a = 0; for i=1, 0, -0.01 do a=a+1 end; assert(a==101) 363 a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) 364 a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) 365 a = 0; for i=1e10, 1e10, -1 do a=a+1 end; assert(a==1) 366 a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) 367 a = 0; for i=99999, 1e5, -1 do a=a+1 end; assert(a==0) 368 a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) 369 370 -- conversion 371 a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) 372 373 374 collectgarbage() 375 376 377 -- testing generic 'for' 378 379 local function f (n, p) 380 local t = {}; for i=1,p do t[i] = i*10 end 381 return function (_,n) 382 if n > 0 then 383 n = n-1 384 return n, unpack(t) 385 end 386 end, nil, n 387 end 388 389 local x = 0 390 for n,a,b,c,d in f(5,3) do 391 x = x+1 392 assert(a == 10 and b == 20 and c == 30 and d == nil) 393 end 394 assert(x == 5) 395 396 print"OK"