attrib.lua 14 KB

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