diff options
Diffstat (limited to 'testes/attrib.lua')
| -rw-r--r-- | testes/attrib.lua | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/testes/attrib.lua b/testes/attrib.lua new file mode 100644 index 00000000..79a08a4f --- /dev/null +++ b/testes/attrib.lua | |||
| @@ -0,0 +1,487 @@ | |||
| 1 | -- $Id: attrib.lua,v 1.69 2018/03/12 13:51:02 roberto Exp $ | ||
| 2 | -- See Copyright Notice in file all.lua | ||
| 3 | |||
| 4 | print "testing require" | ||
| 5 | |||
| 6 | assert(require"string" == string) | ||
| 7 | assert(require"math" == math) | ||
| 8 | assert(require"table" == table) | ||
| 9 | assert(require"io" == io) | ||
| 10 | assert(require"os" == os) | ||
| 11 | assert(require"coroutine" == coroutine) | ||
| 12 | |||
| 13 | assert(type(package.path) == "string") | ||
| 14 | assert(type(package.cpath) == "string") | ||
| 15 | assert(type(package.loaded) == "table") | ||
| 16 | assert(type(package.preload) == "table") | ||
| 17 | |||
| 18 | assert(type(package.config) == "string") | ||
| 19 | print("package config: "..string.gsub(package.config, "\n", "|")) | ||
| 20 | |||
| 21 | do | ||
| 22 | -- create a path with 'max' templates, | ||
| 23 | -- each with 1-10 repetitions of '?' | ||
| 24 | local max = _soft and 100 or 2000 | ||
| 25 | local t = {} | ||
| 26 | for i = 1,max do t[i] = string.rep("?", i%10 + 1) end | ||
| 27 | t[#t + 1] = ";" -- empty template | ||
| 28 | local path = table.concat(t, ";") | ||
| 29 | -- use that path in a search | ||
| 30 | local s, err = package.searchpath("xuxu", path) | ||
| 31 | -- search fails; check that message has an occurence of | ||
| 32 | -- '??????????' with ? replaced by xuxu and at least 'max' lines | ||
| 33 | assert(not s and | ||
| 34 | string.find(err, string.rep("xuxu", 10)) and | ||
| 35 | #string.gsub(err, "[^\n]", "") >= max) | ||
| 36 | -- path with one very long template | ||
| 37 | local path = string.rep("?", max) | ||
| 38 | local s, err = package.searchpath("xuxu", path) | ||
| 39 | assert(not s and string.find(err, string.rep('xuxu', max))) | ||
| 40 | end | ||
| 41 | |||
| 42 | do | ||
| 43 | local oldpath = package.path | ||
| 44 | package.path = {} | ||
| 45 | local s, err = pcall(require, "no-such-file") | ||
| 46 | assert(not s and string.find(err, "package.path")) | ||
| 47 | package.path = oldpath | ||
| 48 | end | ||
| 49 | |||
| 50 | print('+') | ||
| 51 | |||
| 52 | |||
| 53 | -- The next tests for 'require' assume some specific directories and | ||
| 54 | -- libraries. | ||
| 55 | |||
| 56 | if not _port then --[ | ||
| 57 | |||
| 58 | local dirsep = string.match(package.config, "^([^\n]+)\n") | ||
| 59 | |||
| 60 | -- auxiliary directory with C modules and temporary files | ||
| 61 | local DIR = "libs" .. dirsep | ||
| 62 | |||
| 63 | -- prepend DIR to a name and correct directory separators | ||
| 64 | local function D (x) | ||
| 65 | x = string.gsub(x, "/", dirsep) | ||
| 66 | return DIR .. x | ||
| 67 | end | ||
| 68 | |||
| 69 | -- prepend DIR and pospend proper C lib. extension to a name | ||
| 70 | local function DC (x) | ||
| 71 | local ext = (dirsep == '\\') and ".dll" or ".so" | ||
| 72 | return D(x .. ext) | ||
| 73 | end | ||
| 74 | |||
| 75 | |||
| 76 | local function createfiles (files, preextras, posextras) | ||
| 77 | for n,c in pairs(files) do | ||
| 78 | io.output(D(n)) | ||
| 79 | io.write(string.format(preextras, n)) | ||
| 80 | io.write(c) | ||
| 81 | io.write(string.format(posextras, n)) | ||
| 82 | io.close(io.output()) | ||
| 83 | end | ||
| 84 | end | ||
| 85 | |||
| 86 | function removefiles (files) | ||
| 87 | for n in pairs(files) do | ||
| 88 | os.remove(D(n)) | ||
| 89 | end | ||
| 90 | end | ||
| 91 | |||
| 92 | local files = { | ||
| 93 | ["names.lua"] = "do return {...} end\n", | ||
| 94 | ["err.lua"] = "B = 15; a = a + 1;", | ||
| 95 | ["synerr.lua"] = "B =", | ||
| 96 | ["A.lua"] = "", | ||
| 97 | ["B.lua"] = "assert(...=='B');require 'A'", | ||
| 98 | ["A.lc"] = "", | ||
| 99 | ["A"] = "", | ||
| 100 | ["L"] = "", | ||
| 101 | ["XXxX"] = "", | ||
| 102 | ["C.lua"] = "package.loaded[...] = 25; require'C'", | ||
| 103 | } | ||
| 104 | |||
| 105 | AA = nil | ||
| 106 | local extras = [[ | ||
| 107 | NAME = '%s' | ||
| 108 | REQUIRED = ... | ||
| 109 | return AA]] | ||
| 110 | |||
| 111 | createfiles(files, "", extras) | ||
| 112 | |||
| 113 | -- testing explicit "dir" separator in 'searchpath' | ||
| 114 | assert(package.searchpath("C.lua", D"?", "", "") == D"C.lua") | ||
| 115 | assert(package.searchpath("C.lua", D"?", ".", ".") == D"C.lua") | ||
| 116 | assert(package.searchpath("--x-", D"?", "-", "X") == D"XXxX") | ||
| 117 | assert(package.searchpath("---xX", D"?", "---", "XX") == D"XXxX") | ||
| 118 | assert(package.searchpath(D"C.lua", "?", dirsep) == D"C.lua") | ||
| 119 | assert(package.searchpath(".\\C.lua", D"?", "\\") == D"./C.lua") | ||
| 120 | |||
| 121 | local oldpath = package.path | ||
| 122 | |||
| 123 | package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR) | ||
| 124 | |||
| 125 | local try = function (p, n, r) | ||
| 126 | NAME = nil | ||
| 127 | local rr = require(p) | ||
| 128 | assert(NAME == n) | ||
| 129 | assert(REQUIRED == p) | ||
| 130 | assert(rr == r) | ||
| 131 | end | ||
| 132 | |||
| 133 | a = require"names" | ||
| 134 | assert(a[1] == "names" and a[2] == D"names.lua") | ||
| 135 | |||
| 136 | _G.a = nil | ||
| 137 | local st, msg = pcall(require, "err") | ||
| 138 | assert(not st and string.find(msg, "arithmetic") and B == 15) | ||
| 139 | st, msg = pcall(require, "synerr") | ||
| 140 | assert(not st and string.find(msg, "error loading module")) | ||
| 141 | |||
| 142 | assert(package.searchpath("C", package.path) == D"C.lua") | ||
| 143 | assert(require"C" == 25) | ||
| 144 | assert(require"C" == 25) | ||
| 145 | AA = nil | ||
| 146 | try('B', 'B.lua', true) | ||
| 147 | assert(package.loaded.B) | ||
| 148 | assert(require"B" == true) | ||
| 149 | assert(package.loaded.A) | ||
| 150 | assert(require"C" == 25) | ||
| 151 | package.loaded.A = nil | ||
| 152 | try('B', nil, true) -- should not reload package | ||
| 153 | try('A', 'A.lua', true) | ||
| 154 | package.loaded.A = nil | ||
| 155 | os.remove(D'A.lua') | ||
| 156 | AA = {} | ||
| 157 | try('A', 'A.lc', AA) -- now must find second option | ||
| 158 | assert(package.searchpath("A", package.path) == D"A.lc") | ||
| 159 | assert(require("A") == AA) | ||
| 160 | AA = false | ||
| 161 | try('K', 'L', false) -- default option | ||
| 162 | try('K', 'L', false) -- default option (should reload it) | ||
| 163 | assert(rawget(_G, "_REQUIREDNAME") == nil) | ||
| 164 | |||
| 165 | AA = "x" | ||
| 166 | try("X", "XXxX", AA) | ||
| 167 | |||
| 168 | |||
| 169 | removefiles(files) | ||
| 170 | |||
| 171 | |||
| 172 | -- testing require of sub-packages | ||
| 173 | |||
| 174 | local _G = _G | ||
| 175 | |||
| 176 | package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR) | ||
| 177 | |||
| 178 | files = { | ||
| 179 | ["P1/init.lua"] = "AA = 10", | ||
| 180 | ["P1/xuxu.lua"] = "AA = 20", | ||
| 181 | } | ||
| 182 | |||
| 183 | createfiles(files, "_ENV = {}\n", "\nreturn _ENV\n") | ||
| 184 | AA = 0 | ||
| 185 | |||
| 186 | local m = assert(require"P1") | ||
| 187 | assert(AA == 0 and m.AA == 10) | ||
| 188 | assert(require"P1" == m) | ||
| 189 | assert(require"P1" == m) | ||
| 190 | |||
| 191 | assert(package.searchpath("P1.xuxu", package.path) == D"P1/xuxu.lua") | ||
| 192 | m.xuxu = assert(require"P1.xuxu") | ||
| 193 | assert(AA == 0 and m.xuxu.AA == 20) | ||
| 194 | assert(require"P1.xuxu" == m.xuxu) | ||
| 195 | assert(require"P1.xuxu" == m.xuxu) | ||
| 196 | assert(require"P1" == m and m.AA == 10) | ||
| 197 | |||
| 198 | |||
| 199 | removefiles(files) | ||
| 200 | |||
| 201 | |||
| 202 | package.path = "" | ||
| 203 | assert(not pcall(require, "file_does_not_exist")) | ||
| 204 | package.path = "??\0?" | ||
| 205 | assert(not pcall(require, "file_does_not_exist1")) | ||
| 206 | |||
| 207 | package.path = oldpath | ||
| 208 | |||
| 209 | -- check 'require' error message | ||
| 210 | local fname = "file_does_not_exist2" | ||
| 211 | local m, err = pcall(require, fname) | ||
| 212 | for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do | ||
| 213 | t = string.gsub(t, "?", fname) | ||
| 214 | assert(string.find(err, t, 1, true)) | ||
| 215 | end | ||
| 216 | |||
| 217 | do -- testing 'package.searchers' not being a table | ||
| 218 | local searchers = package.searchers | ||
| 219 | package.searchers = 3 | ||
| 220 | local st, msg = pcall(require, 'a') | ||
| 221 | assert(not st and string.find(msg, "must be a table")) | ||
| 222 | package.searchers = searchers | ||
| 223 | end | ||
| 224 | |||
| 225 | local function import(...) | ||
| 226 | local f = {...} | ||
| 227 | return function (m) | ||
| 228 | for i=1, #f do m[f[i]] = _G[f[i]] end | ||
| 229 | end | ||
| 230 | end | ||
| 231 | |||
| 232 | -- cannot change environment of a C function | ||
| 233 | assert(not pcall(module, 'XUXU')) | ||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | -- testing require of C libraries | ||
| 238 | |||
| 239 | |||
| 240 | local p = "" -- On Mac OS X, redefine this to "_" | ||
| 241 | |||
| 242 | -- check whether loadlib works in this system | ||
| 243 | local st, err, when = package.loadlib(DC"lib1", "*") | ||
| 244 | if not st then | ||
| 245 | local f, err, when = package.loadlib("donotexist", p.."xuxu") | ||
| 246 | assert(not f and type(err) == "string" and when == "absent") | ||
| 247 | ;(Message or print)('\n >>> cannot load dynamic library <<<\n') | ||
| 248 | print(err, when) | ||
| 249 | else | ||
| 250 | -- tests for loadlib | ||
| 251 | local f = assert(package.loadlib(DC"lib1", p.."onefunction")) | ||
| 252 | local a, b = f(15, 25) | ||
| 253 | assert(a == 25 and b == 15) | ||
| 254 | |||
| 255 | f = assert(package.loadlib(DC"lib1", p.."anotherfunc")) | ||
| 256 | assert(f(10, 20) == "10%20\n") | ||
| 257 | |||
| 258 | -- check error messages | ||
| 259 | local f, err, when = package.loadlib(DC"lib1", p.."xuxu") | ||
| 260 | assert(not f and type(err) == "string" and when == "init") | ||
| 261 | f, err, when = package.loadlib("donotexist", p.."xuxu") | ||
| 262 | assert(not f and type(err) == "string" and when == "open") | ||
| 263 | |||
| 264 | -- symbols from 'lib1' must be visible to other libraries | ||
| 265 | f = assert(package.loadlib(DC"lib11", p.."luaopen_lib11")) | ||
| 266 | assert(f() == "exported") | ||
| 267 | |||
| 268 | -- test C modules with prefixes in names | ||
| 269 | package.cpath = DC"?" | ||
| 270 | local lib2 = require"lib2-v2" | ||
| 271 | -- check correct access to global environment and correct | ||
| 272 | -- parameters | ||
| 273 | assert(_ENV.x == "lib2-v2" and _ENV.y == DC"lib2-v2") | ||
| 274 | assert(lib2.id("x") == "x") | ||
| 275 | |||
| 276 | -- test C submodules | ||
| 277 | local fs = require"lib1.sub" | ||
| 278 | assert(_ENV.x == "lib1.sub" and _ENV.y == DC"lib1") | ||
| 279 | assert(fs.id(45) == 45) | ||
| 280 | end | ||
| 281 | |||
| 282 | _ENV = _G | ||
| 283 | |||
| 284 | |||
| 285 | -- testing preload | ||
| 286 | |||
| 287 | do | ||
| 288 | local p = package | ||
| 289 | package = {} | ||
| 290 | p.preload.pl = function (...) | ||
| 291 | local _ENV = {...} | ||
| 292 | function xuxu (x) return x+20 end | ||
| 293 | return _ENV | ||
| 294 | end | ||
| 295 | |||
| 296 | local pl = require"pl" | ||
| 297 | assert(require"pl" == pl) | ||
| 298 | assert(pl.xuxu(10) == 30) | ||
| 299 | assert(pl[1] == "pl" and pl[2] == nil) | ||
| 300 | |||
| 301 | package = p | ||
| 302 | assert(type(package.path) == "string") | ||
| 303 | end | ||
| 304 | |||
| 305 | print('+') | ||
| 306 | |||
| 307 | end --] | ||
| 308 | |||
| 309 | print("testing assignments, logical operators, and constructors") | ||
| 310 | |||
| 311 | local res, res2 = 27 | ||
| 312 | |||
| 313 | a, b = 1, 2+3 | ||
| 314 | assert(a==1 and b==5) | ||
| 315 | a={} | ||
| 316 | function f() return 10, 11, 12 end | ||
| 317 | a.x, b, a[1] = 1, 2, f() | ||
| 318 | assert(a.x==1 and b==2 and a[1]==10) | ||
| 319 | a[f()], b, a[f()+3] = f(), a, 'x' | ||
| 320 | assert(a[10] == 10 and b == a and a[13] == 'x') | ||
| 321 | |||
| 322 | do | ||
| 323 | local f = function (n) local x = {}; for i=1,n do x[i]=i end; | ||
| 324 | return table.unpack(x) end; | ||
| 325 | local a,b,c | ||
| 326 | a,b = 0, f(1) | ||
| 327 | assert(a == 0 and b == 1) | ||
| 328 | A,b = 0, f(1) | ||
| 329 | assert(A == 0 and b == 1) | ||
| 330 | a,b,c = 0,5,f(4) | ||
| 331 | assert(a==0 and b==5 and c==1) | ||
| 332 | a,b,c = 0,5,f(0) | ||
| 333 | assert(a==0 and b==5 and c==nil) | ||
| 334 | end | ||
| 335 | |||
| 336 | a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6 | ||
| 337 | assert(not a and b and c and d==6) | ||
| 338 | |||
| 339 | d = 20 | ||
| 340 | a, b, c, d = f() | ||
| 341 | assert(a==10 and b==11 and c==12 and d==nil) | ||
| 342 | a,b = f(), 1, 2, 3, f() | ||
| 343 | assert(a==10 and b==1) | ||
| 344 | |||
| 345 | assert(a<b == false and a>b == true) | ||
| 346 | assert((10 and 2) == 2) | ||
| 347 | assert((10 or 2) == 10) | ||
| 348 | assert((10 or assert(nil)) == 10) | ||
| 349 | assert(not (nil and assert(nil))) | ||
| 350 | assert((nil or "alo") == "alo") | ||
| 351 | assert((nil and 10) == nil) | ||
| 352 | assert((false and 10) == false) | ||
| 353 | assert((true or 10) == true) | ||
| 354 | assert((false or 10) == 10) | ||
| 355 | assert(false ~= nil) | ||
| 356 | assert(nil ~= false) | ||
| 357 | assert(not nil == true) | ||
| 358 | assert(not not nil == false) | ||
| 359 | assert(not not 1 == true) | ||
| 360 | assert(not not a == true) | ||
| 361 | assert(not not (6 or nil) == true) | ||
| 362 | assert(not not (nil and 56) == false) | ||
| 363 | assert(not not (nil and true) == false) | ||
| 364 | assert(not 10 == false) | ||
| 365 | assert(not {} == false) | ||
| 366 | assert(not 0.5 == false) | ||
| 367 | assert(not "x" == false) | ||
| 368 | |||
| 369 | assert({} ~= {}) | ||
| 370 | print('+') | ||
| 371 | |||
| 372 | a = {} | ||
| 373 | a[true] = 20 | ||
| 374 | a[false] = 10 | ||
| 375 | assert(a[1<2] == 20 and a[1>2] == 10) | ||
| 376 | |||
| 377 | function f(a) return a end | ||
| 378 | |||
| 379 | local a = {} | ||
| 380 | for i=3000,-3000,-1 do a[i + 0.0] = i; end | ||
| 381 | a[10e30] = "alo"; a[true] = 10; a[false] = 20 | ||
| 382 | assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10) | ||
| 383 | for i=3000,-3000,-1 do assert(a[i] == i); end | ||
| 384 | a[print] = assert | ||
| 385 | a[f] = print | ||
| 386 | a[a] = a | ||
| 387 | assert(a[a][a][a][a][print] == assert) | ||
| 388 | a[print](a[a[f]] == a[print]) | ||
| 389 | assert(not pcall(function () local a = {}; a[nil] = 10 end)) | ||
| 390 | assert(not pcall(function () local a = {[nil] = 10} end)) | ||
| 391 | assert(a[nil] == undef) | ||
| 392 | a = nil | ||
| 393 | |||
| 394 | a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'} | ||
| 395 | a, a.x, a.y = a, a[-3] | ||
| 396 | assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y) | ||
| 397 | a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2 | ||
| 398 | a[1].alo(a[2]==10 and b==10 and c==print) | ||
| 399 | |||
| 400 | a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 = 10 | ||
| 401 | local function foo () | ||
| 402 | return a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 | ||
| 403 | end | ||
| 404 | assert(foo() == 10 and | ||
| 405 | a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 == | ||
| 406 | 10) | ||
| 407 | |||
| 408 | |||
| 409 | |||
| 410 | -- test of large float/integer indices | ||
| 411 | |||
| 412 | -- compute maximum integer where all bits fit in a float | ||
| 413 | local maxint = math.maxinteger | ||
| 414 | |||
| 415 | -- trim (if needed) to fit in a float | ||
| 416 | while maxint ~= (maxint + 0.0) or (maxint - 1) ~= (maxint - 1.0) do | ||
| 417 | maxint = maxint // 2 | ||
| 418 | end | ||
| 419 | |||
| 420 | maxintF = maxint + 0.0 -- float version | ||
| 421 | |||
| 422 | assert(maxintF == maxint and math.type(maxintF) == "float" and | ||
| 423 | maxintF >= 2.0^14) | ||
| 424 | |||
| 425 | -- floats and integers must index the same places | ||
| 426 | a[maxintF] = 10; a[maxintF - 1.0] = 11; | ||
| 427 | a[-maxintF] = 12; a[-maxintF + 1.0] = 13; | ||
| 428 | |||
| 429 | assert(a[maxint] == 10 and a[maxint - 1] == 11 and | ||
| 430 | a[-maxint] == 12 and a[-maxint + 1] == 13) | ||
| 431 | |||
| 432 | a[maxint] = 20 | ||
| 433 | a[-maxint] = 22 | ||
| 434 | |||
| 435 | assert(a[maxintF] == 20 and a[maxintF - 1.0] == 11 and | ||
| 436 | a[-maxintF] == 22 and a[-maxintF + 1.0] == 13) | ||
| 437 | |||
| 438 | a = nil | ||
| 439 | |||
| 440 | |||
| 441 | -- test conflicts in multiple assignment | ||
| 442 | do | ||
| 443 | local a,i,j,b | ||
| 444 | a = {'a', 'b'}; i=1; j=2; b=a | ||
| 445 | i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i | ||
| 446 | assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and | ||
| 447 | b[3] == 1) | ||
| 448 | a = {} | ||
| 449 | local function foo () -- assigining to upvalues | ||
| 450 | b, a.x, a = a, 10, 20 | ||
| 451 | end | ||
| 452 | foo() | ||
| 453 | assert(a == 20 and b.x == 10) | ||
| 454 | end | ||
| 455 | |||
| 456 | -- repeat test with upvalues | ||
| 457 | do | ||
| 458 | local a,i,j,b | ||
| 459 | a = {'a', 'b'}; i=1; j=2; b=a | ||
| 460 | local function foo () | ||
| 461 | i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i | ||
| 462 | end | ||
| 463 | foo() | ||
| 464 | assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and | ||
| 465 | b[3] == 1) | ||
| 466 | local t = {} | ||
| 467 | (function (a) t[a], a = 10, 20 end)(1); | ||
| 468 | assert(t[1] == 10) | ||
| 469 | end | ||
| 470 | |||
| 471 | -- bug in 5.2 beta | ||
| 472 | local function foo () | ||
| 473 | local a | ||
| 474 | return function () | ||
| 475 | local b | ||
| 476 | a, b = 3, 14 -- local and upvalue have same index | ||
| 477 | return a, b | ||
| 478 | end | ||
| 479 | end | ||
| 480 | |||
| 481 | local a, b = foo()() | ||
| 482 | assert(a == 3 and b == 14) | ||
| 483 | |||
| 484 | print('OK') | ||
| 485 | |||
| 486 | return res | ||
| 487 | |||
