main.lua 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. # testing special comment on first line
  2. -- $Id: main.lua,v 1.65 2016/11/07 13:11:28 roberto Exp $
  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, p)
  22. p = p or prog
  23. io.output(p)
  24. io.write(s)
  25. assert(io.close())
  26. end
  27. local function getoutput ()
  28. io.input(out)
  29. local t = io.read("a")
  30. io.input():close()
  31. assert(os.remove(out))
  32. return t
  33. end
  34. local function checkprogout (s)
  35. local t = getoutput()
  36. for line in string.gmatch(s, ".-\n") do
  37. assert(string.find(t, line, 1, true))
  38. end
  39. end
  40. local function checkout (s)
  41. local t = getoutput()
  42. if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end
  43. assert(s == t)
  44. return t
  45. end
  46. local function RUN (p, ...)
  47. p = string.gsub(p, "lua", '"'..progname..'"', 1)
  48. local s = string.format(p, ...)
  49. assert(os.execute(s))
  50. end
  51. local function NoRun (msg, p, ...)
  52. p = string.gsub(p, "lua", '"'..progname..'"', 1)
  53. local s = string.format(p, ...)
  54. s = string.format("%s 2> %s", s, out) -- will send error to 'out'
  55. assert(not os.execute(s))
  56. assert(string.find(getoutput(), msg, 1, true)) -- check error message
  57. end
  58. RUN('lua -v')
  59. print(string.format("(temporary program file used in these tests: %s)", prog))
  60. -- running stdin as a file
  61. prepfile""
  62. RUN('lua - < %s > %s', prog, out)
  63. checkout("")
  64. prepfile[[
  65. print(
  66. 1, a
  67. )
  68. ]]
  69. RUN('lua - < %s > %s', prog, out)
  70. checkout("1\tnil\n")
  71. RUN('echo "print(10)\nprint(2)\n" | lua > %s', out)
  72. checkout("10\n2\n")
  73. -- test option '-'
  74. RUN('echo "print(arg[1])" | lua - -h > %s', out)
  75. checkout("-h\n")
  76. -- test environment variables used by Lua
  77. prepfile("print(package.path)")
  78. -- test LUA_PATH
  79. RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out)
  80. checkout("x\n")
  81. -- test LUA_PATH_version
  82. RUN('env LUA_INIT= LUA_PATH_5_3=y LUA_PATH=x lua %s > %s', prog, out)
  83. checkout("y\n")
  84. -- test LUA_CPATH
  85. prepfile("print(package.cpath)")
  86. RUN('env LUA_INIT= LUA_CPATH=xuxu lua %s > %s', prog, out)
  87. checkout("xuxu\n")
  88. -- test LUA_CPATH_version
  89. RUN('env LUA_INIT= LUA_CPATH_5_3=yacc LUA_CPATH=x lua %s > %s', prog, out)
  90. checkout("yacc\n")
  91. -- test LUA_INIT (and its access to 'arg' table)
  92. prepfile("print(X)")
  93. RUN('env LUA_INIT="X=tonumber(arg[1])" lua %s 3.2 > %s', prog, out)
  94. checkout("3.2\n")
  95. -- test LUA_INIT_version
  96. prepfile("print(X)")
  97. RUN('env LUA_INIT_5_3="X=10" LUA_INIT="X=3" lua %s > %s', prog, out)
  98. checkout("10\n")
  99. -- test LUA_INIT for files
  100. prepfile("x = x or 10; print(x); x = x + 1")
  101. RUN('env LUA_INIT="@%s" lua %s > %s', prog, prog, out)
  102. checkout("10\n11\n")
  103. -- test errors in LUA_INIT
  104. NoRun('LUA_INIT:1: msg', 'env LUA_INIT="error(\'msg\')" lua')
  105. -- test option '-E'
  106. local defaultpath, defaultCpath
  107. do
  108. prepfile("print(package.path, package.cpath)")
  109. RUN('env LUA_INIT="error(10)" LUA_PATH=xxx LUA_CPATH=xxx lua -E %s > %s',
  110. prog, out)
  111. local out = getoutput()
  112. defaultpath = string.match(out, "^(.-)\t")
  113. defaultCpath = string.match(out, "\t(.-)$")
  114. end
  115. -- paths did not changed
  116. assert(not string.find(defaultpath, "xxx") and
  117. string.find(defaultpath, "lua") and
  118. not string.find(defaultCpath, "xxx") and
  119. string.find(defaultCpath, "lua"))
  120. -- test replacement of ';;' to default path
  121. local function convert (p)
  122. prepfile("print(package.path)")
  123. RUN('env LUA_PATH="%s" lua %s > %s', p, prog, out)
  124. local expected = getoutput()
  125. expected = string.sub(expected, 1, -2) -- cut final end of line
  126. assert(string.gsub(p, ";;", ";"..defaultpath..";") == expected)
  127. end
  128. convert(";")
  129. convert(";;")
  130. convert(";;;")
  131. convert(";;;;")
  132. convert(";;;;;")
  133. convert(";;a;;;bc")
  134. -- test -l over multiple libraries
  135. prepfile("print(1); a=2; return {x=15}")
  136. prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog)
  137. RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
  138. checkout("1\n2\n15\n2\n15\n")
  139. -- test 'arg' table
  140. local a = [[
  141. assert(#arg == 3 and arg[1] == 'a' and
  142. arg[2] == 'b' and arg[3] == 'c')
  143. assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s')
  144. assert(arg[4] == nil and arg[-4] == nil)
  145. local a, b, c = ...
  146. assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
  147. ]]
  148. a = string.format(a, progname)
  149. prepfile(a)
  150. RUN('lua "-e " -- %s a b c', prog) -- "-e " runs an empty command
  151. -- test 'arg' availability in libraries
  152. prepfile"assert(arg)"
  153. prepfile("assert(arg)", otherprog)
  154. RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
  155. -- test messing up the 'arg' table
  156. RUN('echo "print(...)" | lua -e "arg[1] = 100" - > %s', out)
  157. checkout("100\n")
  158. NoRun("'arg' is not a table", 'echo "" | lua -e "arg = 1" -')
  159. -- test error in 'print'
  160. RUN('echo 10 | lua -e "print=nil" -i > /dev/null 2> %s', out)
  161. assert(string.find(getoutput(), "error calling 'print'"))
  162. -- test 'debug.debug'
  163. RUN('echo "io.stderr:write(1000)\ncont" | lua -e "require\'debug\'.debug()" 2> %s', out)
  164. checkout("lua_debug> 1000lua_debug> ")
  165. -- test many arguments
  166. prepfile[[print(({...})[30])]]
  167. RUN('lua %s %s > %s', prog, string.rep(" a", 30), out)
  168. checkout("a\n")
  169. RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out)
  170. checkout("1\n3\n")
  171. -- test iteractive mode
  172. prepfile[[
  173. (6*2-6) -- ===
  174. a =
  175. 10
  176. print(a)
  177. a]]
  178. RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
  179. checkprogout("6\n10\n10\n\n")
  180. prepfile("a = [[b\nc\nd\ne]]\n=a")
  181. RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
  182. checkprogout("b\nc\nd\ne\n\n")
  183. prompt = "alo"
  184. prepfile[[ --
  185. a = 2
  186. ]]
  187. RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out)
  188. local t = getoutput()
  189. assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt))
  190. -- test for error objects
  191. prepfile[[
  192. debug = require "debug"
  193. m = {x=0}
  194. setmetatable(m, {__tostring = function(x)
  195. return tostring(debug.getinfo(4).currentline + x.x)
  196. end})
  197. error(m)
  198. ]]
  199. NoRun(progname .. ": 6\n", [[lua %s]], prog)
  200. prepfile("error{}")
  201. NoRun("error object is a table value", [[lua %s]], prog)
  202. -- chunk broken in many lines
  203. s = [=[ --
  204. function f ( x )
  205. local a = [[
  206. xuxu
  207. ]]
  208. local b = "\
  209. xuxu\n"
  210. if x == 11 then return 1 + 12 , 2 + 20 end --[[ test multiple returns ]]
  211. return x + 1
  212. --\\
  213. end
  214. return( f( 100 ) )
  215. assert( a == b )
  216. do return f( 11 ) end ]=]
  217. s = string.gsub(s, ' ', '\n\n') -- change all spaces for newlines
  218. prepfile(s)
  219. RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
  220. checkprogout("101\n13\t22\n\n")
  221. prepfile[[#comment in 1st line without \n at the end]]
  222. RUN('lua %s', prog)
  223. prepfile[[#test line number when file starts with comment line
  224. debug = require"debug"
  225. print(debug.getinfo(1).currentline)
  226. ]]
  227. RUN('lua %s > %s', prog, out)
  228. checkprogout('3')
  229. -- close Lua with an open file
  230. prepfile(string.format([[io.output(%q); io.write('alo')]], out))
  231. RUN('lua %s', prog)
  232. checkout('alo')
  233. -- bug in 5.2 beta (extra \0 after version line)
  234. RUN([[lua -v -e"print'hello'" > %s]], out)
  235. t = getoutput()
  236. assert(string.find(t, "PUC%-Rio\nhello"))
  237. -- testing os.exit
  238. prepfile("os.exit(nil, true)")
  239. RUN('lua %s', prog)
  240. prepfile("os.exit(0, true)")
  241. RUN('lua %s', prog)
  242. prepfile("os.exit(true, true)")
  243. RUN('lua %s', prog)
  244. prepfile("os.exit(1, true)")
  245. NoRun("", "lua %s", prog) -- no message
  246. prepfile("os.exit(false, true)")
  247. NoRun("", "lua %s", prog) -- no message
  248. -- remove temporary files
  249. assert(os.remove(prog))
  250. assert(os.remove(otherprog))
  251. assert(not os.remove(out))
  252. -- invalid options
  253. NoRun("unrecognized option '-h'", "lua -h")
  254. NoRun("unrecognized option '---'", "lua ---")
  255. NoRun("unrecognized option '-Ex'", "lua -Ex")
  256. NoRun("unrecognized option '-vv'", "lua -vv")
  257. NoRun("unrecognized option '-iv'", "lua -iv")
  258. NoRun("'-e' needs argument", "lua -e")
  259. NoRun("syntax error", "lua -e a")
  260. NoRun("'-l' needs argument", "lua -l")
  261. if T then -- auxiliary library?
  262. print("testing 'not enough memory' to create a state")
  263. NoRun("not enough memory", "env MEMLIMIT=100 lua")
  264. end
  265. print('+')
  266. print('testing Ctrl C')
  267. do
  268. -- interrupt a script
  269. local function kill (pid)
  270. return os.execute(string.format('kill -INT %d 2> /dev/null', pid))
  271. end
  272. -- function to run a script in background, returning its output file
  273. -- descriptor and its pid
  274. local function runback (luaprg)
  275. -- shell script to run 'luaprg' in background and echo its pid
  276. local shellprg = string.format('%s -e "%s" & echo $!', progname, luaprg)
  277. local f = io.popen(shellprg, "r") -- run shell script
  278. local pid = f:read() -- get pid for Lua script
  279. print("(if test fails now, it may leave a Lua script running in \z
  280. background, pid " .. pid .. ")")
  281. return f, pid
  282. end
  283. -- Lua script that runs protected infinite loop and then prints '42'
  284. local f, pid = runback[[
  285. pcall(function () print(12); while true do end end); print(42)]]
  286. -- wait until script is inside 'pcall'
  287. assert(f:read() == "12")
  288. kill(pid) -- send INT signal to Lua script
  289. -- check that 'pcall' captured the exception and script continued running
  290. assert(f:read() == "42") -- expected output
  291. assert(f:close())
  292. print("done")
  293. -- Lua script in a long unbreakable search
  294. local f, pid = runback[[
  295. print(15); string.find(string.rep('a', 100000), '.*b')]]
  296. -- wait (so script can reach the loop)
  297. assert(f:read() == "15")
  298. assert(os.execute("sleep 1"))
  299. -- must send at least two INT signals to stop this Lua script
  300. local n = 100
  301. for i = 0, 100 do -- keep sending signals
  302. if not kill(pid) then -- until it fails
  303. n = i -- number of non-failed kills
  304. break
  305. end
  306. end
  307. assert(f:close())
  308. assert(n >= 2)
  309. print(string.format("done (with %d kills)", n))
  310. end
  311. print("OK")