diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
commit | 063d4e4543088e7a21965bda8ee5a0f952a9029e (patch) | |
tree | 6c3f2f8e98c26f071a94a32f9f2754396a66a9de /testes/attrib.lua | |
parent | e354c6355e7f48e087678ec49e340ca0696725b1 (diff) | |
download | lua-5.3.5.tar.gz lua-5.3.5.tar.bz2 lua-5.3.5.zip |
Lua 5.3.5 ported to gitv5.3.5
This is the first commit for the branch Lua 5.3. All source files
were copied from the official distribution of 5.3.5 in the Lua site.
The test files are the same of 5.3.4. The manual came from the
previous RCS repository, revision 1.167.1.2.
Diffstat (limited to 'testes/attrib.lua')
-rw-r--r-- | testes/attrib.lua | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/testes/attrib.lua b/testes/attrib.lua new file mode 100644 index 00000000..993a96cc --- /dev/null +++ b/testes/attrib.lua | |||
@@ -0,0 +1,470 @@ | |||
1 | -- $Id: attrib.lua,v 1.65 2016/11/07 13:11:28 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] == nil) | ||
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 | |||
401 | -- test of large float/integer indices | ||
402 | |||
403 | -- compute maximum integer where all bits fit in a float | ||
404 | local maxint = math.maxinteger | ||
405 | |||
406 | while maxint - 1.0 == maxint - 0.0 do -- trim (if needed) to fit in a float | ||
407 | maxint = maxint // 2 | ||
408 | end | ||
409 | |||
410 | maxintF = maxint + 0.0 -- float version | ||
411 | |||
412 | assert(math.type(maxintF) == "float" and maxintF >= 2.0^14) | ||
413 | |||
414 | -- floats and integers must index the same places | ||
415 | a[maxintF] = 10; a[maxintF - 1.0] = 11; | ||
416 | a[-maxintF] = 12; a[-maxintF + 1.0] = 13; | ||
417 | |||
418 | assert(a[maxint] == 10 and a[maxint - 1] == 11 and | ||
419 | a[-maxint] == 12 and a[-maxint + 1] == 13) | ||
420 | |||
421 | a[maxint] = 20 | ||
422 | a[-maxint] = 22 | ||
423 | |||
424 | assert(a[maxintF] == 20 and a[maxintF - 1.0] == 11 and | ||
425 | a[-maxintF] == 22 and a[-maxintF + 1.0] == 13) | ||
426 | |||
427 | a = nil | ||
428 | |||
429 | |||
430 | -- test conflicts in multiple assignment | ||
431 | do | ||
432 | local a,i,j,b | ||
433 | a = {'a', 'b'}; i=1; j=2; b=a | ||
434 | i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i | ||
435 | assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and | ||
436 | b[3] == 1) | ||
437 | end | ||
438 | |||
439 | -- repeat test with upvalues | ||
440 | do | ||
441 | local a,i,j,b | ||
442 | a = {'a', 'b'}; i=1; j=2; b=a | ||
443 | local function foo () | ||
444 | i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i | ||
445 | end | ||
446 | foo() | ||
447 | assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and | ||
448 | b[3] == 1) | ||
449 | local t = {} | ||
450 | (function (a) t[a], a = 10, 20 end)(1); | ||
451 | assert(t[1] == 10) | ||
452 | end | ||
453 | |||
454 | -- bug in 5.2 beta | ||
455 | local function foo () | ||
456 | local a | ||
457 | return function () | ||
458 | local b | ||
459 | a, b = 3, 14 -- local and upvalue have same index | ||
460 | return a, b | ||
461 | end | ||
462 | end | ||
463 | |||
464 | local a, b = foo()() | ||
465 | assert(a == 3 and b == 14) | ||
466 | |||
467 | print('OK') | ||
468 | |||
469 | return res | ||
470 | |||