aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2024-02-21 22:30:40 -0300
committerHisham Muhammad <hisham@gobolinux.org>2024-02-23 04:33:35 -0300
commit79bd1739d8ca004ddd0b2fa5e24da4a6f4b776fa (patch)
treeb8ead4801340bd958fccbcb97c35cc7d463f2435
parenta75d447e10bb7842cdbed0bb494697ddd88fd455 (diff)
downloadluarocks-79bd1739d8ca004ddd0b2fa5e24da4a6f4b776fa.tar.gz
luarocks-79bd1739d8ca004ddd0b2fa5e24da4a6f4b776fa.tar.bz2
luarocks-79bd1739d8ca004ddd0b2fa5e24da4a6f4b776fa.zip
tests: introduce quick tests
-rw-r--r--.github/workflows/test.yml4
-rw-r--r--appveyor.yml14
-rw-r--r--spec/build_spec.lua40
-rw-r--r--spec/config_spec.lua16
-rw-r--r--spec/list_spec.lua5
-rw-r--r--spec/quick/build.q122
-rw-r--r--spec/quick/config.q17
-rw-r--r--spec/quick/install.q124
-rw-r--r--spec/quick/list.q10
-rw-r--r--spec/quick_spec.lua20
-rw-r--r--spec/rockspecs_spec.lua2
-rw-r--r--spec/util/quick.lua384
-rw-r--r--spec/util/test_env.lua16
13 files changed, 706 insertions, 68 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 603a5613..07803faf 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -54,8 +54,8 @@ jobs:
54 - name: Integration Test 54 - name: Integration Test
55 run: | 55 run: |
56 eval $(luarocks path) 56 eval $(luarocks path)
57 busted -o htest --exclude-tags=ssh,gpg,git,unit --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci" 57 busted -o htest --exclude-tags=ssh,gpg,git,unit,quick --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci"
58 busted -o htest --exclude-tags=ssh,gpg,git,unit --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci,env=full" 58 busted -o htest --exclude-tags=ssh,gpg,git,unit,quick --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci,env=full"
59 59
60 - name: Coverage 60 - name: Coverage
61 run: | 61 run: |
diff --git a/appveyor.yml b/appveyor.yml
index b084cff5..0d350d8a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,17 +9,23 @@ environment:
9 LUAROCKS_VER: 3.0.0 9 LUAROCKS_VER: 3.0.0
10 10
11 matrix: 11 matrix:
12 # quick tests
13 - LUAV: "2.1"
14 LUAT: "luajit"
15 COMPILER: "vs"
16 FILES: ""
17 EXCLUDE: "integration,unit"
12 # Lua 5.4 tests 18 # Lua 5.4 tests
13 - LUAV: "5.4" 19 - LUAV: "5.4"
14 LUAT: "lua" 20 LUAT: "lua"
15 COMPILER: "vs" 21 COMPILER: "vs"
16 FILES: "" 22 FILES: ""
17 EXCLUDE: "integration" 23 EXCLUDE: "integration,quick"
18 - LUAV: "5.4" 24 - LUAV: "5.4"
19 LUAT: "lua" 25 LUAT: "lua"
20 COMPILER: "vs" 26 COMPILER: "vs"
21 FILES: "" 27 FILES: ""
22 EXCLUDE: "unit" 28 EXCLUDE: "unit,quick"
23 - LUAV: "5.4" 29 - LUAV: "5.4"
24 LUAT: "lua" 30 LUAT: "lua"
25 COMPILER: "mingw" 31 COMPILER: "mingw"
@@ -30,12 +36,12 @@ environment:
30 LUAT: "luajit" 36 LUAT: "luajit"
31 COMPILER: "vs" 37 COMPILER: "vs"
32 FILES: "" 38 FILES: ""
33 EXCLUDE: "integration" 39 EXCLUDE: "integration,quick"
34 - LUAV: "2.1" 40 - LUAV: "2.1"
35 LUAT: "luajit" 41 LUAT: "luajit"
36 COMPILER: "vs" 42 COMPILER: "vs"
37 FILES: "" 43 FILES: ""
38 EXCLUDE: "unit" 44 EXCLUDE: "unit,quick"
39 - LUAV: "2.1" 45 - LUAV: "2.1"
40 LUAT: "luajit" 46 LUAT: "luajit"
41 COMPILER: "mingw" 47 COMPILER: "mingw"
diff --git a/spec/build_spec.lua b/spec/build_spec.lua
index 3b33a1aa..5e78aa4f 100644
--- a/spec/build_spec.lua
+++ b/spec/build_spec.lua
@@ -49,45 +49,7 @@ describe("LuaRocks build #integration", function()
49 test_env.setup_specs(extra_rocks) 49 test_env.setup_specs(extra_rocks)
50 end) 50 end)
51 51
52 describe("basic testing set", function()
53 it("invalid", function()
54 assert.is_false(run.luarocks_bool("build invalid"))
55 end)
56
57 it("with no arguments behaves as luarocks make", function()
58 test_env.run_in_tmp(function(tmpdir)
59 write_file("c_module-1.0-1.rockspec", [[
60 package = "c_module"
61 version = "1.0-1"
62 source = {
63 url = "http://example.com/c_module"
64 }
65 build = {
66 type = "builtin",
67 modules = {
68 c_module = { "c_module.c" }
69 }
70 }
71 ]], finally)
72 write_file("c_module.c", c_module_source, finally)
73
74 assert.is_true(run.luarocks_bool("build"))
75 assert.truthy(lfs.attributes(tmpdir .. "/c_module." .. test_env.lib_extension))
76 end, finally)
77 end)
78 end)
79
80 describe("building with flags", function() 52 describe("building with flags", function()
81 it("fails if it doesn't have the permissions to access the specified tree #unix", function()
82 assert.is_false(run.luarocks_bool("build --tree=/usr " .. testing_paths.fixtures_dir .. "/a_rock-1.0.1-rockspec"))
83 assert.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
84 end)
85
86 it("fails if it doesn't have the permissions to access the specified tree's parent #unix", function()
87 assert.is_false(run.luarocks_bool("build --tree=/usr/invalid " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec"))
88 assert.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
89 end)
90
91 it("verbose", function() 53 it("verbose", function()
92 test_env.run_in_tmp(function(tmpdir) 54 test_env.run_in_tmp(function(tmpdir)
93 write_file("test-1.0-1.rockspec", [[ 55 write_file("test-1.0-1.rockspec", [[
@@ -429,7 +391,7 @@ describe("LuaRocks build #integration", function()
429 package = "a_rock" 391 package = "a_rock"
430 version = "1.0-1" 392 version = "1.0-1"
431 source = { 393 source = {
432 url = "file://]] .. testing_paths.fixtures_dir .. [[/a_rock.lua" 394 url = "file://]] .. testing_paths.fixtures_dir:gsub("\\", "/") .. [[/a_rock.lua"
433 } 395 }
434 description = { 396 description = {
435 summary = "An example rockspec", 397 summary = "An example rockspec",
diff --git a/spec/config_spec.lua b/spec/config_spec.lua
index 98fcb24c..9615f050 100644
--- a/spec/config_spec.lua
+++ b/spec/config_spec.lua
@@ -115,22 +115,6 @@ describe("LuaRocks config tests #integration", function()
115 assert.is_false(run.luarocks_bool("config --system-config")) 115 assert.is_false(run.luarocks_bool("config --system-config"))
116 end) 116 end)
117 117
118 it("outputs the path of the system config", function()
119 lfs.mkdir(testing_paths.testing_lrprefix)
120 lfs.mkdir(testing_paths.testing_lrprefix .. "/etc/")
121 lfs.mkdir(scdir)
122
123 local sysconfig = io.open(configfile, "w+")
124 sysconfig:write(" ")
125 sysconfig:close()
126 finally(function()
127 os.remove(configfile)
128 end)
129
130 local output = run.luarocks("config --system-config")
131 assert.are.same(configfile, output)
132 end)
133
134 it("fails if system config is invalid", function() 118 it("fails if system config is invalid", function()
135 lfs.mkdir(testing_paths.testing_lrprefix) 119 lfs.mkdir(testing_paths.testing_lrprefix)
136 lfs.mkdir(testing_paths.testing_lrprefix .. "/etc/") 120 lfs.mkdir(testing_paths.testing_lrprefix .. "/etc/")
diff --git a/spec/list_spec.lua b/spec/list_spec.lua
index 54c63bea..4c7fc776 100644
--- a/spec/list_spec.lua
+++ b/spec/list_spec.lua
@@ -38,9 +38,4 @@ describe("luarocks list #integration", function()
38 assert.is.truthy(output:find("say")) 38 assert.is.truthy(output:find("say"))
39 assert.matches("1.0-1 < ", output, 1, true) 39 assert.matches("1.0-1 < ", output, 1, true)
40 end) 40 end)
41
42 it("invalid tree", function()
43 local output = run.luarocks("--tree=/some/invalid/tree list")
44 assert(output:find("Rocks installed for Lua "..test_env.lua_version.." in /some/invalid/tree", 1, true))
45 end)
46end) 41end)
diff --git a/spec/quick/build.q b/spec/quick/build.q
new file mode 100644
index 00000000..c6ca433c
--- /dev/null
+++ b/spec/quick/build.q
@@ -0,0 +1,122 @@
1TEST: luarocks build: fails when given invalid argument
2RUN: luarocks build aoesuthaoeusahtoeustnaou --only-server=localhost
3EXIT: 1
4STDERR:
5--------------------------------------------------------------------------------
6Could not find a result named aoesuthaoeusahtoeustnaou
7--------------------------------------------------------------------------------
8
9
10
11================================================================================
12TEST: luarocks build: with no arguments behaves as luarocks make
13
14FILE: c_module-1.0-1.rockspec
15--------------------------------------------------------------------------------
16package = "c_module"
17version = "1.0-1"
18source = {
19 url = "http://example.com/c_module"
20}
21build = {
22 type = "builtin",
23 modules = {
24 c_module = { "c_module.c" }
25 }
26}
27--------------------------------------------------------------------------------
28FILE: c_module.c
29--------------------------------------------------------------------------------
30#include <lua.h>
31#include <lauxlib.h>
32
33int luaopen_c_module(lua_State* L) {
34 lua_newtable(L);
35 lua_pushinteger(L, 1);
36 lua_setfield(L, -2, "c_module");
37 return 1;
38}
39--------------------------------------------------------------------------------
40RUN: luarocks build
41EXISTS: c_module.%{lib_extension}
42
43
44
45================================================================================
46TEST: luarocks build: defaults to builtin type
47
48FILE: a_rock-1.0-1.rockspec
49--------------------------------------------------------------------------------
50rockspec_format = "3.0"
51package = "a_rock"
52version = "1.0-1"
53source = {
54 url = "file://%{url(%{fixtures_dir})}/a_rock.lua"
55}
56description = {
57 summary = "An example rockspec",
58}
59dependencies = {
60 "lua >= 5.1"
61}
62build = {
63 modules = {
64 build = "a_rock.lua"
65 },
66}
67--------------------------------------------------------------------------------
68RUN: luarocks build a_rock-1.0-1.rockspec
69RUN: luarocks show a_rock
70STDOUT:
71--------------------------------------------------------------------------------
72a_rock 1.0
73--------------------------------------------------------------------------------
74
75
76================================================================================
77TEST: luarocks build: fails if no permissions to access the specified tree #unix
78
79RUN: luarocks build --tree=/usr ./a_rock-1.0.1-rockspec
80EXIT: 4
81STDERR:
82--------------------------------------------------------------------------------
83requires exclusive access
84use --force-lock
85--------------------------------------------------------------------------------
86
87NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec
88
89RUN: luarocks build --tree=/usr ./a_rock-1.0.1-rockspec --force-lock
90EXIT: 4
91STDERR:
92--------------------------------------------------------------------------------
93requires exclusive access
94failed to force the lock
95--------------------------------------------------------------------------------
96
97NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec
98
99
100
101================================================================================
102TEST: luarocks build: fails if no permissions to access the parent #unix
103
104RUN: luarocks build --tree=/usr/invalid ./a_rock-1.0.1-rockspec
105EXIT: 4
106STDERR:
107--------------------------------------------------------------------------------
108requires exclusive access
109use --force-lock
110--------------------------------------------------------------------------------
111
112NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec
113
114RUN: luarocks build --tree=/usr/invalid ./a_rock-1.0.1-rockspec --force-lock
115EXIT: 4
116STDERR:
117--------------------------------------------------------------------------------
118requires exclusive access
119failed to force the lock
120--------------------------------------------------------------------------------
121
122NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec
diff --git a/spec/quick/config.q b/spec/quick/config.q
new file mode 100644
index 00000000..ec338f98
--- /dev/null
+++ b/spec/quick/config.q
@@ -0,0 +1,17 @@
1================================================================================
2TEST: luarocks config --system-config shows the path of the system config
3
4MKDIR: %{testing_lrprefix}/etc/luarocks
5
6FILE: %{testing_lrprefix}/etc/luarocks/config-%{LUA_VERSION}.lua
7--------------------------------------------------------------------------------
8
9--------------------------------------------------------------------------------
10
11RUN: luarocks config --system-config
12
13STDOUT:
14--------------------------------------------------------------------------------
15%{testing_lrprefix}/etc/luarocks/config-%{LUA_VERSION}.lua
16--------------------------------------------------------------------------------
17#TODO: ^^^ %{path()}
diff --git a/spec/quick/install.q b/spec/quick/install.q
new file mode 100644
index 00000000..2bccf2f1
--- /dev/null
+++ b/spec/quick/install.q
@@ -0,0 +1,124 @@
1===============================================================================
2TEST: luarocks install: handle versioned modules when installing another version with --keep #268
3
4FILE: myrock-1.0-1.rockspec
5--------------------------------------------------------------------------------
6rockspec_format = "3.0"
7package = "myrock"
8version = "1.0-1"
9source = {
10 url = "file://%{url(tmpdir)}/rock.lua"
11}
12build = {
13 modules = { rock = "rock.lua" }
14}
15--------------------------------------------------------------------------------
16
17FILE: myrock-2.0-1.rockspec
18--------------------------------------------------------------------------------
19rockspec_format = "3.0"
20package = "myrock"
21version = "2.0-1"
22source = {
23 url = "file://%{url(tmpdir)}/rock.lua"
24}
25build = {
26 modules = { rock = "rock.lua" }
27}
28--------------------------------------------------------------------------------
29
30FILE: rock.lua
31--------------------------------------------------------------------------------
32return "hello"
33--------------------------------------------------------------------------------
34
35RUN: luarocks build myrock-1.0-1.rockspec
36RUN: luarocks pack myrock
37RUN: luarocks remove myrock
38
39RUN: luarocks build myrock-2.0-1.rockspec
40RUN: luarocks pack myrock
41RUN: luarocks remove myrock
42
43RUN: luarocks install ./myrock-2.0-1.all.rock
44
45EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua
46
47RUN: luarocks install ./myrock-1.0-1.all.rock --keep
48
49EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua
50EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/myrock_1_0_1-rock.lua
51
52RUN: luarocks install ./myrock-2.0-1.all.rock
53
54EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua
55NOT_EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/myrock_1_0_1-rock.lua
56
57
58
59===============================================================================
60TEST: luarocks install: handle versioned libraries when installing another version with --keep #268
61
62FILE: myrock-1.0-1.rockspec
63--------------------------------------------------------------------------------
64rockspec_format = "3.0"
65package = "myrock"
66version = "1.0-1"
67source = {
68 url = "file://%{url(tmpdir)}/c_module.c"
69}
70build = {
71 modules = {
72 c_module = { "c_module.c" }
73 }
74}
75--------------------------------------------------------------------------------
76
77FILE: myrock-2.0-1.rockspec
78--------------------------------------------------------------------------------
79rockspec_format = "3.0"
80package = "myrock"
81version = "2.0-1"
82source = {
83 url = "file://%{url(tmpdir)}/c_module.c"
84}
85build = {
86 modules = {
87 c_module = { "c_module.c" }
88 }
89}
90--------------------------------------------------------------------------------
91FILE: c_module.c
92--------------------------------------------------------------------------------
93#include <lua.h>
94#include <lauxlib.h>
95
96int luaopen_c_module(lua_State* L) {
97 lua_newtable(L);
98 lua_pushinteger(L, 1);
99 lua_setfield(L, -2, "c_module");
100 return 1;
101}
102--------------------------------------------------------------------------------
103
104RUN: luarocks build myrock-1.0-1.rockspec
105RUN: luarocks pack myrock
106RUN: luarocks remove myrock
107
108RUN: luarocks build myrock-2.0-1.rockspec
109RUN: luarocks pack myrock
110RUN: luarocks remove myrock
111
112RUN: luarocks install ./myrock-2.0-1.%{platform}.rock
113
114EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension}
115
116RUN: luarocks install ./myrock-1.0-1.%{platform}.rock --keep
117
118EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension}
119EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/myrock_1_0_1-c_module.%{lib_extension}
120
121RUN: luarocks install ./myrock-2.0-1.%{platform}.rock
122
123EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension}
124NOT_EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/myrock_1_0_1-c_module.%{lib_extension}
diff --git a/spec/quick/list.q b/spec/quick/list.q
new file mode 100644
index 00000000..7cbdee43
--- /dev/null
+++ b/spec/quick/list.q
@@ -0,0 +1,10 @@
1================================================================================
2TEST: luarocks list: invalid tree
3
4RUN: luarocks --tree=%{path(/some/invalid/tree)} list
5
6STDOUT:
7--------------------------------------------------------------------------------
8Rocks installed for Lua %{lua_version} in /some/invalid/tree
9--------------------------------------------------------------------------------
10#TODO: ^^^ %{path()}
diff --git a/spec/quick_spec.lua b/spec/quick_spec.lua
new file mode 100644
index 00000000..8b8206cf
--- /dev/null
+++ b/spec/quick_spec.lua
@@ -0,0 +1,20 @@
1local lfs = require("lfs")
2local test_env = require("spec.util.test_env")
3local quick = require("spec.util.quick")
4
5describe("quick tests: #quick", function()
6 before_each(function()
7 test_env.setup_specs()
8 end)
9
10 local spec_quick = test_env.testing_paths.spec_dir .. "/quick"
11 for f in lfs.dir(spec_quick) do
12 if f:match("%.q$") then
13 local tests = quick.compile(spec_quick .. "/" .. f, getfenv and getfenv() or _ENV)
14 for _, t in ipairs(tests) do
15 it(t.name, t.fn)
16 end
17 end
18 end
19end)
20
diff --git a/spec/rockspecs_spec.lua b/spec/rockspecs_spec.lua
index 76b33f65..5b0573fe 100644
--- a/spec/rockspecs_spec.lua
+++ b/spec/rockspecs_spec.lua
@@ -4,7 +4,7 @@ local cfg = require("luarocks.core.cfg")
4local test_env = require("spec.util.test_env") 4local test_env = require("spec.util.test_env")
5local lfs = require("lfs") 5local lfs = require("lfs")
6 6
7describe("luarocks.rockspecs", function() 7describe("luarocks.rockspecs #unit", function()
8 8
9 setup(function() 9 setup(function()
10 cfg.init() 10 cfg.init()
diff --git a/spec/util/quick.lua b/spec/util/quick.lua
new file mode 100644
index 00000000..c8bfb61a
--- /dev/null
+++ b/spec/util/quick.lua
@@ -0,0 +1,384 @@
1local quick = {}
2
3local dir_sep = package.config:sub(1, 1)
4
5local cfg, dir, fs, versions
6local initialized = false
7
8local function initialize()
9 if initialized then
10 return
11 end
12 initialized = true
13
14 cfg = require("luarocks.core.cfg")
15 dir = require("luarocks.dir")
16 fs = require("luarocks.fs")
17 versions = require("spec.util.versions")
18 cfg.init()
19 fs.init()
20end
21
22local function native_slash(pathname)
23 return (pathname:gsub("[/\\]", dir_sep))
24end
25
26local function parse_cmd(line)
27 local cmd, arg = line:match("^%s*([A-Z_]+):%s*(.*)%s*$")
28 return cmd, arg
29end
30
31local function is_blank(line)
32 return not not line:match("^%s*$")
33end
34
35local function is_hr(line)
36 return not not line:match("^%-%-%-%-%-")
37end
38
39local function parse(filename)
40 local fd = assert(io.open(filename, "r"))
41 local input = assert(fd:read("*a"))
42 fd:close()
43
44 initialize()
45
46 local tests = {}
47
48 local cur_line = 0
49 local cur_test
50 local cur_op
51 local cur_block
52 local cur_block_name
53 local stack = { "start" }
54
55 local function start_test(arg)
56 cur_test = {
57 name = arg,
58 ops = {},
59 }
60 cur_op = nil
61 table.insert(tests, cur_test)
62 table.insert(stack, "test")
63 end
64
65 local function fail(msg)
66 io.stderr:write("Error reading " .. filename .. ":" .. cur_line .. ": " .. msg .. "\n")
67 os.exit(1)
68 end
69
70 local function bool_arg(cmd, cur_block, field, arg)
71 if arg ~= "true" and arg ~= "false" then
72 fail(cmd .. " argument must be 'true' or 'false'")
73 end
74 cur_block[field] = (arg == "true")
75 end
76
77 local test_env = require("spec.util.test_env")
78 local function expand_vars(line)
79 if not line then
80 return nil
81 end
82 return (line:gsub("%%%b{}", function(var)
83 var = var:sub(3, -2)
84 local fn, fnarg = var:match("^%s*([a-z_]+)%s*%(%s*([^)]+)%s*%)%s*$")
85
86 local value
87 if var == "tmpdir" then
88 value = "%{tmpdir}"
89 elseif var == "url(tmpdir)" then
90 value = "%{url(tmpdir)}"
91 elseif fn == "url" then
92 value = expand_vars(fnarg)
93 value = value:gsub("\\", "/")
94 elseif fn == "path" then
95 value = expand_vars(fnarg)
96 value = value:gsub("[/\\]", dir_sep)
97 elseif fn == "version" then
98 value = versions[fnarg:lower()] or ""
99 elseif fn == "version_" then
100 value = (versions[fnarg:lower()] or ""):gsub("[%.%-]", "_")
101 else
102 value = test_env.testing_paths[var]
103 or test_env.env_variables[var]
104 or test_env[var]
105 or ""
106 end
107
108 return value
109 end))
110 end
111
112 for line in input:gmatch("[^\n]*") do
113 cur_line = cur_line + 1
114
115 local state = stack[#stack]
116 if state == "start" then
117 local cmd, arg = parse_cmd(line)
118 if cmd == "TEST" then
119 start_test(arg)
120 elseif cmd then
121 fail("expected TEST, got " .. cmd)
122 elseif is_blank(line) then
123 -- skip blank lines and arbitrary text,
124 -- which is interpreted as a comment
125 end
126 elseif state == "test" then
127 local cmd, arg = parse_cmd(line)
128 arg = expand_vars(arg)
129 if cmd == "FILE" then
130 cur_op = {
131 op = "FILE",
132 name = arg,
133 data = {},
134 }
135 table.insert(cur_test.ops, cur_op)
136 cur_block = cur_op
137 cur_block_name = "FILE"
138 table.insert(stack, "block start")
139 elseif cmd == "RUN" then
140 local program, args = arg:match("([^ ]+)%s*(.*)$")
141 if not program then
142 fail("expected a program argument in RUN")
143 end
144
145 cur_op = {
146 op = "RUN",
147 exit = 0,
148 exit_line = cur_line,
149 line = cur_line,
150 program = program,
151 args = args,
152 }
153 table.insert(cur_test.ops, cur_op)
154 elseif cmd == "EXISTS" then
155 cur_op = {
156 op = "EXISTS",
157 file = dir.normalize(arg),
158 }
159 table.insert(cur_test.ops, cur_op)
160 elseif cmd == "NOT_EXISTS" then
161 cur_op = {
162 op = "NOT_EXISTS",
163 file = dir.normalize(arg),
164 }
165 table.insert(cur_test.ops, cur_op)
166 elseif cmd == "MKDIR" then
167 cur_op = {
168 op = "MKDIR",
169 file = dir.normalize(arg),
170 line = cur_line,
171 }
172 table.insert(cur_test.ops, cur_op)
173 elseif cmd == "EXIT" then
174 if not cur_op or cur_op.op ~= "RUN" then
175 fail("EXIT must be given in the context of a RUN")
176 end
177
178 local code = tonumber(arg)
179 if not code and not (code >= 0 and code <= 128) then
180 fail("EXIT code must be a number in the range 0-128, got " .. arg)
181 end
182
183 cur_op.exit = code
184 cur_op.exit_line = cur_line
185 elseif cmd == "STDERR" then
186 if not cur_op or cur_op.op ~= "RUN" then
187 fail("STDERR must be given in the context of a RUN")
188 end
189 if cur_op.stderr then
190 fail("STDERR was already declared")
191 end
192
193 cur_op.stderr = {
194 data = {}
195 }
196 cur_block = cur_op.stderr
197 cur_block_name = "STDERR"
198 table.insert(stack, "block start")
199 elseif cmd == "STDOUT" then
200 if not cur_op or cur_op.op ~= "RUN" then
201 fail("STDOUT must be given in the context of a RUN")
202 end
203 if cur_op.stdout then
204 fail("STDOUT was already declared")
205 end
206
207 cur_op.stdout = {
208 data = {}
209 }
210 cur_block = cur_op.stdout
211 cur_block_name = "STDOUT"
212 table.insert(stack, "block start")
213 elseif cmd == "TEST" then
214 table.remove(stack)
215 start_test(arg)
216 elseif cmd then
217 fail("expected a command, got " .. cmd)
218 else
219 -- skip blank lines and arbitrary text,
220 -- which is interpreted as a comment
221 end
222 elseif state == "block start" then
223 local cmd, arg = parse_cmd(line)
224 if is_blank(line) then
225 -- skip
226 elseif is_hr(line) then
227 stack[#stack] = "block data"
228 cur_block.start = cur_line
229 elseif cmd == "PLAIN" then
230 bool_arg("PLAIN", cur_block, "plain", arg)
231 else
232 fail("expected '-----' to start " .. cur_block_name .. " block")
233 end
234 elseif state == "block data" then
235 if is_hr(line) then
236 cur_block = nil
237 table.remove(stack)
238 else
239 if not cur_block.plain then
240 line = expand_vars(line)
241 end
242 table.insert(cur_block.data, line)
243 end
244 end
245 end
246
247 return tests
248end
249
250function quick.compile(filename, env)
251 local tests = parse(filename)
252
253-- local dev_null = (package.config:sub(1, 1) == "/")
254-- and "/dev/null"
255-- or "NUL"
256
257 local cmd_helpers = {
258 ["luarocks"] = "luarocks_cmd",
259 ["luarocks-admin"] = "luarocks_admin_cmd",
260 }
261
262 for tn, t in ipairs(tests) do
263 local code = {}
264 local function write(...)
265 table.insert(code, table.concat({...}))
266 end
267
268 write([=[ local test_env = require("spec.util.test_env") ]=])
269 write([=[ local lfs = require("lfs") ]=])
270 write([=[ local fs = require("lfs") ]=])
271 write([=[ local dir_sep = package.config:sub(1, 1) ]=])
272 write([=[ local luarocks_cmd = test_env.execute_helper(test_env.Q(test_env.testing_paths.lua) .. " " .. test_env.testing_paths.src_dir .. "/bin/luarocks", false, test_env.env_variables):sub(1, -5) ]=])
273 write([=[ local luarocks_admin_cmd = test_env.execute_helper(test_env.Q(test_env.testing_paths.lua) .. " " .. test_env.testing_paths.src_dir .. "/bin/luarocks-admin", false, test_env.env_variables):sub(1, -5) ]=])
274
275 write(([=[ local function error_message(line, msg, input) ]=]))
276 write(([=[ local out = {"\n\n", %q, ":", line, ": ", msg} ]=]):format(filename))
277 write(([=[ if input then ]=]))
278 write(([=[ if input:match("\n") then ]=]))
279 write(([=[ table.insert(out, "\n") ]=]))
280 write(([=[ table.insert(out, ("-"):rep(40)) ]=]))
281 write(([=[ table.insert(out, "\n") ]=]))
282 write(([=[ table.insert(out, input) ]=]))
283 write(([=[ table.insert(out, ("-"):rep(40)) ]=]))
284 write(([=[ table.insert(out, "\n") ]=]))
285 write(([=[ else ]=]))
286 write(([=[ table.insert(out, ": ") ]=]))
287 write(([=[ table.insert(out, input) ]=]))
288 write(([=[ end ]=]))
289 write(([=[ end ]=]))
290 write(([=[ return table.concat(out) ]=]))
291 write(([=[ end ]=]))
292
293 write([=[ return function() ]=])
294 write([=[ test_env.run_in_tmp(function(tmpdir) ]=])
295 write([=[ local function handle_tmpdir(s) ]=])
296 write([=[ return (s:gsub("%%{url%(tmpdir%)}", (tmpdir:gsub("\\", "/"))) ]=])
297 write([=[ :gsub("%%{tmpdir}", (tmpdir:gsub("[\\/]", dir_sep)))) ]=])
298 write([=[ end ]=])
299 for _, op in ipairs(t.ops) do
300 if op.op == "FILE" then
301 write([=[ test_env.write_file(handle_tmpdir("]=], op.name, [=["), handle_tmpdir([=====[ ]=])
302 for _, line in ipairs(op.data) do
303 write(line)
304 end
305 write([=[ ]=====]), finally) ]=])
306 elseif op.op == "EXISTS" then
307 write(([=[ assert.truthy(lfs.attributes(%q)) ]=]):format(op.file))
308 elseif op.op == "NOT_EXISTS" then
309 write(([=[ assert.falsy(lfs.attributes(%q)) ]=]):format(op.file))
310 elseif op.op == "MKDIR" then
311 local bits = {}
312 op.file = native_slash(op.file)
313 if op.file:sub(1, 1) == dir_sep then bits[1] = "" end
314 write([=[ local ok, err ]=])
315 for p in op.file:gmatch("[^" .. dir_sep .. "]+") do
316 table.insert(bits, p)
317 local d = table.concat(bits, dir_sep)
318 write(([=[ ok, err = lfs.mkdir(%q) ]=]):format(d, d))
319 end
320 write(([=[ assert.truthy((lfs.attributes(%q) or {}).mode == "directory", error_message(%d, "MKDIR failed: " .. %q .. " - " .. (err or "") )) ]=]):format(op.file, op.line, op.file))
321 elseif op.op == "RUN" then
322 local cmd_helper = cmd_helpers[op.program] or op.program
323 local redirs = " 1>stdout.txt 2>stderr.txt "
324 write(([=[ local ok, _, code = os.execute(%s .. " " .. %q .. %q) ]=]):format(cmd_helper, op.args, redirs))
325 write([=[ if type(ok) == "number" then code = (ok >= 256 and ok / 256 or ok) end ]=])
326
327 write([=[ local fd_stderr = assert(io.open("stderr.txt", "r")) ]=])
328 write([=[ local stderr_data = fd_stderr:read("*a") ]=])
329 write([=[ fd_stderr:close() ]=])
330
331 write([=[ if stderr_data:match("please report") then ]=])
332 write(([=[ assert(false, error_message(%d, "RUN crashed: ", stderr_data)) ]=]):format(op.line))
333 write([=[ end ]=])
334
335 if op.stdout then
336 write([=[ local fd_stdout = assert(io.open("stdout.txt", "r")) ]=])
337 write([=[ local stdout_data = fd_stdout:read("*a") ]=])
338 write([=[ fd_stdout:close() ]=])
339
340 write([=[ do ]=])
341 write([=[ local block_at = 1 ]=])
342 write([=[ local s, e, line ]=])
343 for i, line in ipairs(op.stdout.data) do
344 write(([=[ line = %q ]=]):format(line))
345 write(([=[ s, e = string.find(stdout_data, line, block_at, true) ]=]))
346 write(([=[ assert(s, error_message(%d, "STDOUT did not match: " .. line, stdout_data)) ]=]):format(op.stdout.start + i))
347 write(([=[ block_at = e + 1 ]=]):format(i))
348 end
349 write([=[ end ]=])
350 end
351
352 if op.stderr then
353 write([=[ do ]=])
354 write([=[ local block_at = 1 ]=])
355 write([=[ local s, e, line ]=])
356 for i, line in ipairs(op.stderr.data) do
357 write(([=[ line = %q ]=]):format(line))
358 write(([=[ s, e = string.find(stderr_data, line, block_at, true) ]=]))
359 write(([=[ assert(s, error_message(%d, "STDERR did not match: " .. line, stderr_data)) ]=]):format(op.stderr.start + i))
360 write(([=[ block_at = e + 1 ]=]):format(i))
361 end
362 write([=[ end ]=])
363 end
364
365 if op.exit then
366 write(([=[ assert.same(%d, code, error_message(%d, "EXIT did not match: " .. %d, stderr_data)) ]=]):format(op.exit, op.exit_line, op.exit))
367 end
368 end
369 end
370 write([=[ end) ]=])
371 write([=[ end ]=])
372
373 local program = table.concat(code, "\n")
374 local chunk = assert(load(program, "@" .. filename .. ": test " .. tn, "t", env or _ENV))
375 if env and setfenv then
376 setfenv(chunk, env)
377 end
378 t.fn = chunk()
379 end
380
381 return tests
382end
383
384return quick
diff --git a/spec/util/test_env.lua b/spec/util/test_env.lua
index f9f83b8c..dcda6311 100644
--- a/spec/util/test_env.lua
+++ b/spec/util/test_env.lua
@@ -715,6 +715,7 @@ local function create_paths(luaversion_full)
715 testing_paths.util_dir = base_dir .. "/spec/util" 715 testing_paths.util_dir = base_dir .. "/spec/util"
716 testing_paths.testrun_dir = base_dir .. "/testrun" 716 testing_paths.testrun_dir = base_dir .. "/testrun"
717 testing_paths.src_dir = base_dir .. "/src" 717 testing_paths.src_dir = base_dir .. "/src"
718 testing_paths.spec_dir = base_dir .. "/spec"
718 testing_paths.testing_lrprefix = testing_paths.testrun_dir .. "/testing_lrprefix-" .. luaversion_full 719 testing_paths.testing_lrprefix = testing_paths.testrun_dir .. "/testing_lrprefix-" .. luaversion_full
719 testing_paths.testing_tree = testing_paths.testrun_dir .. "/testing-" .. luaversion_full 720 testing_paths.testing_tree = testing_paths.testrun_dir .. "/testing-" .. luaversion_full
720 testing_paths.testing_tree_copy = testing_paths.testrun_dir .. "/testing_copy-" .. luaversion_full 721 testing_paths.testing_tree_copy = testing_paths.testrun_dir .. "/testing_copy-" .. luaversion_full
@@ -753,6 +754,16 @@ function test_env.unload_luarocks()
753 end 754 end
754end 755end
755 756
757local function get_luarocks_platform(variables)
758 local print_arch_script = "\"" ..
759 "cfg = require('luarocks.core.cfg');" ..
760 "cfg.init();" ..
761 "print(cfg.arch)" ..
762 "\""
763 local cmd = test_env.testing_paths.lua .. " -e " .. print_arch_script
764 return execute_output(cmd, false, variables)
765end
766
756--- Function for initial setup of environment, variables, md5sums for spec files 767--- Function for initial setup of environment, variables, md5sums for spec files
757function test_env.setup_specs(extra_rocks) 768function test_env.setup_specs(extra_rocks)
758 -- if global variable about successful creation of testing environment doesn't exist, build environment 769 -- if global variable about successful creation of testing environment doesn't exist, build environment
@@ -770,11 +781,12 @@ function test_env.setup_specs(extra_rocks)
770 781
771 -- preload before meddling with package.path 782 -- preload before meddling with package.path
772 require("spec.util.git_repo") 783 require("spec.util.git_repo")
784 require("spec.util.quick")
773 785
774 package.path = test_env.env_variables.LUA_PATH 786 package.path = test_env.env_variables.LUA_PATH
775 package.cpath = test_env.env_variables.LUA_CPATH 787 package.cpath = test_env.env_variables.LUA_CPATH
776 788
777 test_env.platform = execute_output(test_env.testing_paths.lua .. " -e \"cfg = require('luarocks.core.cfg'); cfg.init(); print(cfg.arch)\"", false, test_env.env_variables) 789 test_env.platform = get_luarocks_platform(test_env.env_variables)
778 test_env.wrapper_extension = test_env.TEST_TARGET_OS == "windows" and ".bat" or "" 790 test_env.wrapper_extension = test_env.TEST_TARGET_OS == "windows" and ".bat" or ""
779 test_env.md5sums = create_md5sums(test_env.testing_paths) 791 test_env.md5sums = create_md5sums(test_env.testing_paths)
780 test_env.setup_done = true 792 test_env.setup_done = true
@@ -1104,5 +1116,7 @@ test_env.env_variables = create_env(test_env.testing_paths)
1104test_env.run = make_run_functions() 1116test_env.run = make_run_functions()
1105test_env.exists = exists 1117test_env.exists = exists
1106test_env.V = V 1118test_env.V = V
1119test_env.Q = Q
1120test_env.platform = get_luarocks_platform(test_env.env_variables)
1107 1121
1108return test_env 1122return test_env