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