attrib.lua 12 KB

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