main.lua 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. # testing special comment on first line
  2. -- $Id: testes/main.lua $
  3. -- See Copyright Notice in file all.lua
  4. -- most (all?) tests here assume a reasonable "Unix-like" shell
  5. if _port then return end
  6. -- use only "double quotes" inside shell scripts (better change to
  7. -- run on Windows)
  8. print ("testing stand-alone interpreter")
  9. assert(os.execute()) -- machine has a system command
  10. local arg = arg or ARG
  11. local prog = os.tmpname()
  12. local otherprog = os.tmpname()
  13. local out = os.tmpname()
  14. local progname
  15. do
  16. local i = 0
  17. while arg[i] do i=i-1 end
  18. progname = arg[i+1]
  19. end
  20. print("progname: "..progname)
  21. local prepfile = function (s, mod, p)
  22. mod = mod and "wb" or "w" -- mod true means binary files
  23. p = p or prog -- file to write the program
  24. local f = io.open(p, mod)
  25. f:write(s)
  26. assert(f:close())
  27. end
  28. local function getoutput ()
  29. local f = io.open(out)
  30. local t = f:read("a")
  31. f:close()
  32. assert(os.remove(out))
  33. return t
  34. end
  35. local function checkprogout (s)
  36. -- expected result must end with new line
  37. assert(string.sub(s, -1) == "\n")
  38. local t = getoutput()
  39. for line in string.gmatch(s, ".-\n") do
  40. assert(string.find(t, line, 1, true))
  41. end
  42. end
  43. local function checkout (s)
  44. local t = getoutput()
  45. if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end
  46. assert(s == t)
  47. return t
  48. end
  49. local function RUN (p, ...)
  50. p = string.gsub(p, "lua", '"'..progname..'"', 1)
  51. local s = string.format(p, ...)
  52. assert(os.execute(s))
  53. end
  54. local function NoRun (msg, p, ...)
  55. p = string.gsub(p, "lua", '"'..progname..'"', 1)
  56. local s = string.format(p, ...)
  57. s = string.format("%s >%s 2>&1", s, out) -- send output and error to 'out'
  58. assert(not os.execute(s))
  59. assert(string.find(getoutput(), msg, 1, true)) -- check error message
  60. end
  61. RUN('lua -v')
  62. print(string.format("(temporary program file used in these tests: %s)", prog))
  63. -- running stdin as a file
  64. prepfile""
  65. RUN('lua - < %s > %s', prog, out)
  66. checkout("")
  67. prepfile[[
  68. print(
  69. 1, a
  70. )
  71. ]]
  72. RUN('lua - < %s > %s', prog, out)
  73. checkout("1\tnil\n")
  74. RUN('echo "print(10)\nprint(2)\n" | lua > %s', out)
  75. checkout("10\n2\n")
  76. -- testing BOM
  77. prepfile("\xEF\xBB\xBF")
  78. RUN('lua %s > %s', prog, out)
  79. checkout("")
  80. prepfile("\xEF\xBB\xBFprint(3)")
  81. RUN('lua %s > %s', prog, out)
  82. checkout("3\n")
  83. prepfile("\xEF\xBB\xBF# comment!!\nprint(3)")
  84. RUN('lua %s > %s', prog, out)
  85. checkout("3\n")
  86. -- bad BOMs
  87. prepfile("\xEF", true)
  88. NoRun("unexpected symbol", 'lua %s', prog)
  89. prepfile("\xEF\xBB", true)
  90. NoRun("unexpected symbol", 'lua %s', prog)
  91. prepfile("\xEFprint(3)", true)
  92. NoRun("unexpected symbol", 'lua %s', prog)
  93. prepfile("\xEF\xBBprint(3)", true)
  94. NoRun("unexpected symbol", 'lua %s', prog)
  95. -- test option '-'
  96. RUN('echo "print(arg[1])" | lua - -h > %s', out)
  97. checkout("-h\n")
  98. -- test environment variables used by Lua
  99. prepfile("print(package.path)")
  100. -- test LUA_PATH
  101. RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out)
  102. checkout("x\n")
  103. -- test LUA_PATH_version
  104. RUN('env LUA_INIT= LUA_PATH_5_4=y LUA_PATH=x lua %s > %s', prog, out)
  105. checkout("y\n")
  106. -- test LUA_CPATH
  107. prepfile("print(package.cpath)")
  108. RUN('env LUA_INIT= LUA_CPATH=xuxu lua %s > %s', prog, out)
  109. checkout("xuxu\n")
  110. -- test LUA_CPATH_version
  111. RUN('env LUA_INIT= LUA_CPATH_5_4=yacc LUA_CPATH=x lua %s > %s', prog, out)
  112. checkout("yacc\n")
  113. -- test LUA_INIT (and its access to 'arg' table)
  114. prepfile("print(X)")
  115. RUN('env LUA_INIT="X=tonumber(arg[1])" lua %s 3.2 > %s', prog, out)
  116. checkout("3.2\n")
  117. -- test LUA_INIT_version
  118. prepfile("print(X)")
  119. RUN('env LUA_INIT_5_4="X=10" LUA_INIT="X=3" lua %s > %s', prog, out)
  120. checkout("10\n")
  121. -- test LUA_INIT for files
  122. prepfile("x = x or 10; print(x); x = x + 1")
  123. RUN('env LUA_INIT="@%s" lua %s > %s', prog, prog, out)
  124. checkout("10\n11\n")
  125. -- test errors in LUA_INIT
  126. NoRun('LUA_INIT:1: msg', 'env LUA_INIT="error(\'msg\')" lua')
  127. -- test option '-E'
  128. local defaultpath, defaultCpath
  129. do
  130. prepfile("print(package.path, package.cpath)")
  131. RUN('env LUA_INIT="error(10)" LUA_PATH=xxx LUA_CPATH=xxx lua -E %s > %s',
  132. prog, out)
  133. local output = getoutput()
  134. defaultpath = string.match(output, "^(.-)\t")
  135. defaultCpath = string.match(output, "\t(.-)$")
  136. -- running with an empty environment
  137. RUN('env -i lua %s > %s', prog, out)
  138. local out = getoutput()
  139. assert(defaultpath == string.match(output, "^(.-)\t"))
  140. assert(defaultCpath == string.match(output, "\t(.-)$"))
  141. end
  142. -- paths did not change
  143. assert(not string.find(defaultpath, "xxx") and
  144. string.find(defaultpath, "lua") and
  145. not string.find(defaultCpath, "xxx") and
  146. string.find(defaultCpath, "lua"))
  147. -- test replacement of ';;' to default path
  148. local function convert (p)
  149. prepfile("print(package.path)")
  150. RUN('env LUA_PATH="%s" lua %s > %s', p, prog, out)
  151. local expected = getoutput()
  152. expected = string.sub(expected, 1, -2) -- cut final end of line
  153. if string.find(p, ";;") then
  154. p = string.gsub(p, ";;", ";"..defaultpath..";")
  155. p = string.gsub(p, "^;", "") -- remove ';' at the beginning
  156. p = string.gsub(p, ";$", "") -- remove ';' at the end
  157. end
  158. assert(p == expected)
  159. end
  160. convert(";")
  161. convert(";;")
  162. convert("a;;b")
  163. convert(";;b")
  164. convert("a;;")
  165. convert("a;b;;c")
  166. -- test -l over multiple libraries
  167. prepfile("print(1); a=2; return {x=15}")
  168. prepfile(("print(a); print(_G['%s'].x)"):format(prog), false, otherprog)
  169. RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
  170. checkout("1\n2\n15\n2\n15\n")
  171. -- test explicit global names in -l
  172. prepfile("print(str.upper'alo alo', m.max(10, 20))")
  173. RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
  174. checkout("0.0\nALO ALO\t20\n")
  175. -- test module names with version sufix ("libs/lib2-v2")
  176. RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s",
  177. out)
  178. checkout("true\n")
  179. -- test 'arg' table
  180. local a = [[
  181. assert(#arg == 3 and arg[1] == 'a' and
  182. arg[2] == 'b' and arg[3] == 'c')
  183. assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s')
  184. assert(arg[4] == undef and arg[-4] == undef)
  185. local a, b, c = ...
  186. assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
  187. ]]
  188. a = string.format(a, progname)
  189. prepfile(a)
  190. RUN('lua "-e " -- %s a b c', prog) -- "-e " runs an empty command
  191. -- test 'arg' availability in libraries
  192. prepfile"assert(arg)"
  193. prepfile("assert(arg)", false, otherprog)
  194. RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
  195. -- test messing up the 'arg' table
  196. RUN('echo "print(...)" | lua -e "arg[1] = 100" - > %s', out)
  197. checkout("100\n")
  198. NoRun("'arg' is not a table", 'echo "" | lua -e "arg = 1" -')
  199. -- test error in 'print'
  200. RUN('echo 10 | lua -e "print=nil" -i > /dev/null 2> %s', out)
  201. assert(string.find(getoutput(), "error calling 'print'"))
  202. -- test 'debug.debug'
  203. RUN('echo "io.stderr:write(1000)\ncont" | lua -e "require\'debug\'.debug()" 2> %s', out)
  204. checkout("lua_debug> 1000lua_debug> ")
  205. print("testing warnings")
  206. -- no warnings by default
  207. RUN('echo "io.stderr:write(1); warn[[XXX]]" | lua 2> %s', out)
  208. checkout("1")
  209. prepfile[[
  210. warn("@allow") -- unknown control, ignored
  211. warn("@off", "XXX", "@off") -- these are not control messages
  212. warn("@off") -- this one is
  213. warn("@on", "YYY", "@on") -- not control, but warn is off
  214. warn("@off") -- keep it off
  215. warn("@on") -- restart warnings
  216. warn("", "@on") -- again, no control, real warning
  217. warn("@on") -- keep it "started"
  218. warn("Z", "Z", "Z") -- common warning
  219. ]]
  220. RUN('lua -W %s 2> %s', prog, out)
  221. checkout[[
  222. Lua warning: @offXXX@off
  223. Lua warning: @on
  224. Lua warning: ZZZ
  225. ]]
  226. prepfile[[
  227. warn("@allow")
  228. -- create two objects to be finalized when closing state
  229. -- the errors in the finalizers must generate warnings
  230. u1 = setmetatable({}, {__gc = function () error("XYZ") end})
  231. u2 = setmetatable({}, {__gc = function () error("ZYX") end})
  232. ]]
  233. RUN('lua -W %s 2> %s', prog, out)
  234. checkprogout("ZYX)\nXYZ)\n")
  235. -- bug since 5.2: finalizer called when closing a state could
  236. -- subvert finalization order
  237. prepfile[[
  238. -- should be called last
  239. print("creating 1")
  240. setmetatable({}, {__gc = function () print(1) end})
  241. print("creating 2")
  242. setmetatable({}, {__gc = function ()
  243. print("2")
  244. print("creating 3")
  245. -- this finalizer should not be called, as object will be
  246. -- created after 'lua_close' has been called
  247. setmetatable({}, {__gc = function () print(3) end})
  248. print(collectgarbage()) -- cannot call collector here
  249. os.exit(0, true)
  250. end})
  251. ]]
  252. RUN('lua -W %s > %s', prog, out)
  253. checkout[[
  254. creating 1
  255. creating 2
  256. 2
  257. creating 3
  258. nil
  259. 1
  260. ]]
  261. -- test many arguments
  262. prepfile[[print(({...})[30])]]
  263. RUN('lua %s %s > %s', prog, string.rep(" a", 30), out)
  264. checkout("a\n")
  265. RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
  266. checkout("1\n3\n")
  267. -- test iteractive mode
  268. prepfile[[
  269. (6*2-6) -- ===
  270. a =
  271. 10
  272. print(a)
  273. a]]
  274. RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
  275. checkprogout("6\n10\n10\n\n")
  276. prepfile("a = [[b\nc\nd\ne]]\n=a")
  277. RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
  278. checkprogout("b\nc\nd\ne\n\n")
  279. -- input interrupted in continuation line
  280. prepfile("a.\n")
  281. RUN([[lua -i < %s > /dev/null 2> %s]], prog, out)
  282. checkprogout("near <eof>\n")
  283. local prompt = "alo"
  284. prepfile[[ --
  285. a = 2
  286. ]]
  287. RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
  288. local t = getoutput()
  289. assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt))
  290. -- using the prompt default
  291. prepfile[[ --
  292. a = 2
  293. ]]
  294. RUN([[lua -i < %s > %s]], prog, out)
  295. local t = getoutput()
  296. prompt = "> " -- the default
  297. assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt))
  298. -- non-string prompt
  299. prompt =
  300. "local C = 0;\z
  301. _PROMPT=setmetatable({},{__tostring = function () \z
  302. C = C + 1; return C end})"
  303. prepfile[[ --
  304. a = 2
  305. ]]
  306. RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out)
  307. local t = getoutput()
  308. assert(string.find(t, [[
  309. 1 --
  310. 2a = 2
  311. 3
  312. ]], 1, true))
  313. -- test for error objects
  314. prepfile[[
  315. debug = require "debug"
  316. m = {x=0}
  317. setmetatable(m, {__tostring = function(x)
  318. return tostring(debug.getinfo(4).currentline + x.x)
  319. end})
  320. error(m)
  321. ]]
  322. NoRun(progname .. ": 6\n", [[lua %s]], prog)
  323. prepfile("error{}")
  324. NoRun("error object is a table value", [[lua %s]], prog)
  325. -- chunk broken in many lines
  326. local s = [=[ --
  327. function f ( x )
  328. local a = [[
  329. xuxu
  330. ]]
  331. local b = "\
  332. xuxu\n"
  333. if x == 11 then return 1 + 12 , 2 + 20 end --[[ test multiple returns ]]
  334. return x + 1
  335. --\\
  336. end
  337. return( f( 100 ) )
  338. assert( a == b )
  339. do return f( 11 ) end ]=]
  340. s = string.gsub(s, ' ', '\n\n') -- change all spaces for newlines
  341. prepfile(s)
  342. RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
  343. checkprogout("101\n13\t22\n\n")
  344. prepfile[[#comment in 1st line without \n at the end]]
  345. RUN('lua %s', prog)
  346. -- first-line comment with binary file
  347. prepfile("#comment\n" .. string.dump(load("print(3)")), true)
  348. RUN('lua %s > %s', prog, out)
  349. checkout('3\n')
  350. -- close Lua with an open file
  351. prepfile(string.format([[io.output(%q); io.write('alo')]], out))
  352. RUN('lua %s', prog)
  353. checkout('alo')
  354. -- bug in 5.2 beta (extra \0 after version line)
  355. RUN([[lua -v -e"print'hello'" > %s]], out)
  356. t = getoutput()
  357. assert(string.find(t, "PUC%-Rio\nhello"))
  358. -- testing os.exit
  359. prepfile("os.exit(nil, true)")
  360. RUN('lua %s', prog)
  361. prepfile("os.exit(0, true)")
  362. RUN('lua %s', prog)
  363. prepfile("os.exit(true, true)")
  364. RUN('lua %s', prog)
  365. prepfile("os.exit(1, true)")
  366. NoRun("", "lua %s", prog) -- no message
  367. prepfile("os.exit(false, true)")
  368. NoRun("", "lua %s", prog) -- no message
  369. -- to-be-closed variables in main chunk
  370. prepfile[[
  371. local x <close> = setmetatable({},
  372. {__close = function (self, err)
  373. assert(err == nil)
  374. print("Ok")
  375. end})
  376. local e1 <close> = setmetatable({}, {__close = function () print(120) end})
  377. os.exit(true, true)
  378. ]]
  379. RUN('lua %s > %s', prog, out)
  380. checkprogout("120\nOk\n")
  381. -- remove temporary files
  382. assert(os.remove(prog))
  383. assert(os.remove(otherprog))
  384. assert(not os.remove(out))
  385. -- invalid options
  386. NoRun("unrecognized option '-h'", "lua -h")
  387. NoRun("unrecognized option '---'", "lua ---")
  388. NoRun("unrecognized option '-Ex'", "lua -Ex")
  389. NoRun("unrecognized option '-vv'", "lua -vv")
  390. NoRun("unrecognized option '-iv'", "lua -iv")
  391. NoRun("'-e' needs argument", "lua -e")
  392. NoRun("syntax error", "lua -e a")
  393. NoRun("'-l' needs argument", "lua -l")
  394. if T then -- test library?
  395. print("testing 'not enough memory' to create a state")
  396. NoRun("not enough memory", "env MEMLIMIT=100 lua")
  397. -- testing 'warn'
  398. warn("@store")
  399. warn("@123", "456", "789")
  400. assert(_WARN == "@123456789"); _WARN = false
  401. warn("zip", "", " ", "zap")
  402. assert(_WARN == "zip zap"); _WARN = false
  403. warn("ZIP", "", " ", "ZAP")
  404. assert(_WARN == "ZIP ZAP"); _WARN = false
  405. warn("@normal")
  406. end
  407. do
  408. -- 'warn' must get at least one argument
  409. local st, msg = pcall(warn)
  410. assert(string.find(msg, "string expected"))
  411. -- 'warn' does not leave unfinished warning in case of errors
  412. -- (message would appear in next warning)
  413. st, msg = pcall(warn, "SHOULD NOT APPEAR", {})
  414. assert(string.find(msg, "string expected"))
  415. end
  416. print('+')
  417. print('testing Ctrl C')
  418. do
  419. -- interrupt a script
  420. local function kill (pid)
  421. return os.execute(string.format('kill -INT %s 2> /dev/null', pid))
  422. end
  423. -- function to run a script in background, returning its output file
  424. -- descriptor and its pid
  425. local function runback (luaprg)
  426. -- shell script to run 'luaprg' in background and echo its pid
  427. local shellprg = string.format('%s -e "%s" & echo $!', progname, luaprg)
  428. local f = io.popen(shellprg, "r") -- run shell script
  429. local pid = f:read() -- get pid for Lua script
  430. print("(if test fails now, it may leave a Lua script running in \z
  431. background, pid " .. pid .. ")")
  432. return f, pid
  433. end
  434. -- Lua script that runs protected infinite loop and then prints '42'
  435. local f, pid = runback[[
  436. pcall(function () print(12); while true do end end); print(42)]]
  437. -- wait until script is inside 'pcall'
  438. assert(f:read() == "12")
  439. kill(pid) -- send INT signal to Lua script
  440. -- check that 'pcall' captured the exception and script continued running
  441. assert(f:read() == "42") -- expected output
  442. assert(f:close())
  443. print("done")
  444. -- Lua script in a long unbreakable search
  445. local f, pid = runback[[
  446. print(15); string.find(string.rep('a', 100000), '.*b')]]
  447. -- wait (so script can reach the loop)
  448. assert(f:read() == "15")
  449. assert(os.execute("sleep 1"))
  450. -- must send at least two INT signals to stop this Lua script
  451. local n = 100
  452. for i = 0, 100 do -- keep sending signals
  453. if not kill(pid) then -- until it fails
  454. n = i -- number of non-failed kills
  455. break
  456. end
  457. end
  458. assert(f:close())
  459. assert(n >= 2)
  460. print(string.format("done (with %d kills)", n))
  461. end
  462. print("OK")