summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorMike Vink <mike@pionative.com>2025-02-03 21:29:42 +0100
committerMike Vink <mike@pionative.com>2025-02-03 21:29:42 +0100
commit5155816b7b925dec5d5feb1568b1d7ceb00938b9 (patch)
treedeca28ea15e79f6f804c3d90d2ba757881638af5 /spec
fetch tarballHEADmaster
Diffstat (limited to 'spec')
-rw-r--r--spec/README.md58
-rw-r--r--spec/add_spec.lua41
-rw-r--r--spec/build_spec.lua456
-rw-r--r--spec/cmd_spec.lua105
-rw-r--r--spec/config_spec.lua253
-rw-r--r--spec/deps_spec.lua114
-rw-r--r--spec/doc_spec.lua154
-rw-r--r--spec/download_spec.lua55
-rw-r--r--spec/dummy_spec.lua24
-rw-r--r--spec/external_spec.lua32
-rw-r--r--spec/fixtures/a_repo/a_build_dep-1.0-1.rockspec18
-rw-r--r--spec/fixtures/a_repo/a_build_dep-1.0-1.src.rockbin0 -> 575 bytes
-rw-r--r--spec/fixtures/a_repo/a_rock-1.0-1.rockspec18
-rw-r--r--spec/fixtures/a_repo/a_rock-1.0-1.src.rockbin0 -> 446 bytes
-rw-r--r--spec/fixtures/a_repo/a_rock-2.0-1.src.rockbin0 -> 541 bytes
-rw-r--r--spec/fixtures/a_repo/busted_project-0.1-1.rockspec19
-rw-r--r--spec/fixtures/a_repo/busted_project-0.1-1.src.rockbin0 -> 937 bytes
-rw-r--r--spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.rockspec19
-rw-r--r--spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.src.rockbin0 -> 603 bytes
-rw-r--r--spec/fixtures/a_repo/has_build_dep-1.0-1.all.rockbin0 -> 1010 bytes
-rw-r--r--spec/fixtures/a_repo/has_build_dep-1.0-1.rockspec22
-rw-r--r--spec/fixtures/a_repo/has_build_dep-1.0-1.src.rockbin0 -> 584 bytes
-rw-r--r--spec/fixtures/a_repo/has_namespaced_dep-1.0-1.rockspec19
-rw-r--r--spec/fixtures/a_repo/has_namespaced_dep-1.0-1.src.rockbin0 -> 580 bytes
-rw-r--r--spec/fixtures/a_repo/manifest90
-rw-r--r--spec/fixtures/a_repo/manifest-5.190
-rw-r--r--spec/fixtures/a_repo/manifest-5.1.zipbin0 -> 343 bytes
-rw-r--r--spec/fixtures/a_repo/manifest-5.290
-rw-r--r--spec/fixtures/a_repo/manifest-5.2.zipbin0 -> 343 bytes
-rw-r--r--spec/fixtures/a_repo/manifest-5.390
-rw-r--r--spec/fixtures/a_repo/manifest-5.3.zipbin0 -> 343 bytes
-rw-r--r--spec/fixtures/a_repo/manifest-5.490
-rw-r--r--spec/fixtures/a_repo/manifest-5.4.zipbin0 -> 343 bytes
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.rockspec17
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.src.rockbin0 -> 446 bytes
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/manifest14
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/manifest-5.114
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/manifest-5.214
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/manifest-5.314
-rw-r--r--spec/fixtures/a_repo/manifests/a_user/manifest-5.414
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.rockspec17
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.src.rockbin0 -> 449 bytes
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/manifest14
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/manifest-5.114
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/manifest-5.214
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/manifest-5.314
-rw-r--r--spec/fixtures/a_repo/manifests/another_user/manifest-5.414
-rw-r--r--spec/fixtures/a_repo/non_lua_file-1.0-1.rockspec22
-rw-r--r--spec/fixtures/a_repo/non_lua_file-1.0-1.src.rockbin0 -> 852 bytes
-rw-r--r--spec/fixtures/a_repo/non_lua_file-1.0-2.rockspec22
-rw-r--r--spec/fixtures/a_repo/non_lua_file-1.0-2.src.rockbin0 -> 852 bytes
-rw-r--r--spec/fixtures/a_rock-1.0-1.rockspec17
-rw-r--r--spec/fixtures/a_rock-1.0-1.src.rockbin0 -> 446 bytes
-rw-r--r--spec/fixtures/a_rock.lua1
-rw-r--r--spec/fixtures/abc.bz2bin0 -> 66 bytes
-rw-r--r--spec/fixtures/an_upstream_tarball-0.1.tar.gzbin0 -> 260 bytes
-rw-r--r--spec/fixtures/bad_pack-0.1-1.rockspec19
-rw-r--r--spec/fixtures/build_only_deps-0.1-1.rockspec18
-rw-r--r--spec/fixtures/build_only_deps-0.1-1.src.rockbin0 -> 547 bytes
-rw-r--r--spec/fixtures/busted_project-0.1-1.rockspec19
-rw-r--r--spec/fixtures/busted_project-0.1.tar.gzbin0 -> 345 bytes
-rw-r--r--spec/fixtures/busted_project/spec/sum_spec.lua10
-rw-r--r--spec/fixtures/busted_project/sum.lua7
-rw-r--r--spec/fixtures/double_deploy_type/ddt.c6
-rw-r--r--spec/fixtures/double_deploy_type/ddt1.lua1
-rw-r--r--spec/fixtures/double_deploy_type/ddt2.lua1
-rw-r--r--spec/fixtures/double_deploy_type/ddt_file1
-rw-r--r--spec/fixtures/double_deploy_type/double_deploy_type-0.1.0-1.rockspec22
-rw-r--r--spec/fixtures/double_deploy_type/double_deploy_type-0.2.0-1.rockspec22
-rw-r--r--spec/fixtures/fixturedep.c4
-rw-r--r--spec/fixtures/git_repo/LICENSE19
-rw-r--r--spec/fixtures/git_repo/README.md3
-rw-r--r--spec/fixtures/gpg/private-keys-v1.d/5D2D3F97B88B18604D819EA9DF5B730C75D71B60.keybin0 -> 977 bytes
-rw-r--r--spec/fixtures/gpg/private-keys-v1.d/B71C36B4EDEB72A047FED1C01BCFF4D08837E3B1.keybin0 -> 978 bytes
-rw-r--r--spec/fixtures/gpg/pubring.kbxbin0 -> 1494 bytes
-rw-r--r--spec/fixtures/gpg/trustdb.gpgbin0 -> 1240 bytes
-rw-r--r--spec/fixtures/invalid_patch-0.1-1.rockspec29
-rw-r--r--spec/fixtures/invalid_say-1.3-1.rockspec23
-rw-r--r--spec/fixtures/legacyexternalcommand-0.1-1.rockspec17
-rw-r--r--spec/fixtures/legacyexternalcommand.lua34
-rw-r--r--spec/fixtures/luajit-fail-1.0-1.rockspec22
-rw-r--r--spec/fixtures/luajit-success-1.0-1.rockspec23
-rw-r--r--spec/fixtures/mixed_deploy_type/mdt.c6
-rw-r--r--spec/fixtures/mixed_deploy_type/mdt.lua1
-rw-r--r--spec/fixtures/mixed_deploy_type/mdt_file1
-rw-r--r--spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.1.0-1.rockspec21
-rw-r--r--spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.2.0-1.rockspec21
-rw-r--r--spec/fixtures/patch_create_delete-0.1-1.rockspec34
-rw-r--r--spec/fixtures/patch_create_delete/a_file.txt1
-rw-r--r--spec/fixtures/renamed_upstream_tarball-0.1.tar.gzbin0 -> 260 bytes
-rw-r--r--spec/fixtures/with_external_dep-0.1-1.rockspec25
-rw-r--r--spec/fixtures/with_external_dep.c10
-rw-r--r--spec/fixtures/with_external_dep/foo/foo.h1
-rw-r--r--spec/fs_spec.lua76
-rw-r--r--spec/help_spec.lua25
-rw-r--r--spec/init_spec.lua235
-rw-r--r--spec/install_spec.lua235
-rw-r--r--spec/lint_spec.lua109
-rw-r--r--spec/list_spec.lua34
-rw-r--r--spec/loader_spec.lua73
-rw-r--r--spec/make_spec.lua387
-rw-r--r--spec/pack_spec.lua102
-rw-r--r--spec/path_spec.lua58
-rw-r--r--spec/quick/admin_make_manifest.q46
-rw-r--r--spec/quick/build.q405
-rw-r--r--spec/quick/cmd.q36
-rw-r--r--spec/quick/config.q97
-rw-r--r--spec/quick/doc.q13
-rw-r--r--spec/quick/install.q688
-rw-r--r--spec/quick/list.q45
-rw-r--r--spec/quick/make.q88
-rw-r--r--spec/quick/new_version.q213
-rw-r--r--spec/quick/pack.q128
-rw-r--r--spec/quick/path.q22
-rw-r--r--spec/quick/purge.q103
-rw-r--r--spec/quick/test.q51
-rw-r--r--spec/quick_spec.lua22
-rw-r--r--spec/refresh_cache_spec.lua13
-rw-r--r--spec/remove_spec.lua129
-rw-r--r--spec/search_spec.lua33
-rw-r--r--spec/show_spec.lua105
-rw-r--r--spec/test_spec.lua93
-rw-r--r--spec/unit/build_spec.lua365
-rw-r--r--spec/unit/deps_spec.lua143
-rw-r--r--spec/unit/dir_spec.lua70
-rw-r--r--spec/unit/fetch_spec.lua486
-rw-r--r--spec/unit/fs_spec.lua1595
-rw-r--r--spec/unit/fun_spec.lua128
-rw-r--r--spec/unit/loader_spec.lua18
-rw-r--r--spec/unit/persist_spec.lua74
-rw-r--r--spec/unit/rockspecs_spec.lua126
-rw-r--r--spec/unit/sysdetect_spec.lua79
-rw-r--r--spec/unit/test_spec.lua173
-rw-r--r--spec/unit/tools_spec.lua251
-rw-r--r--spec/unit/util_spec.lua160
-rw-r--r--spec/unpack_spec.lua69
-rw-r--r--spec/upload_spec.lua63
-rw-r--r--spec/util/git_repo.lua108
-rw-r--r--spec/util/mock-server.lua98
-rw-r--r--spec/util/quick.lua472
-rw-r--r--spec/util/test_env.lua1187
-rw-r--r--spec/util/versions.lua17
-rw-r--r--spec/util_spec.lua55
-rw-r--r--spec/which_spec.lua39
-rw-r--r--spec/write_rockspec_spec.lua104
145 files changed, 12058 insertions, 0 deletions
diff --git a/spec/README.md b/spec/README.md
new file mode 100644
index 0000000..89e13ea
--- /dev/null
+++ b/spec/README.md
@@ -0,0 +1,58 @@
+
+# LuaRocks testsuite
+
+## Overview
+
+Test suite for LuaRocks project with Busted unit testing framework(http://olivinelabs.com/busted/).
+
+* Contains unit and integration tests
+* Easy setup for your purpose on command line or from configuration file
+
+## Dependencies
+
+* Lua >= 5.1
+* Busted with dependencies
+
+## Usage
+
+Running of tests is based on basic Busted usage. *-Xhelper* flag is used
+for inserting arguments into testing. Flag *--tags=* or *-t* is used
+for specifying which tests will run. Start tests inside
+LuaRocks folder or specify with *-C* flag.
+
+**Arguments for Busted helper script**
+
+```
+env=<type>, (default:"minimal") type what kind of environment to use ["minimal", "full"]
+noreset, Don't reset environment after each test
+clean, remove existing testing environment
+appveyor, add just if running on Appveyor
+ci, add just if running on Unix CI
+os=<version>, type your OS ["linux", "os x", "windows"]
+```
+---------------------------------------------------------------------------------------------
+## _**Tags** of tests are required and are in this format:_
+
+**unit** - run all unit tests
+
+**integration** - run all integration tests
+
+**ssh** - run all tests which require ssh
+
+**mock** - run all tests which require mock LuaRocks server (upload tests)
+
+**unix** - run all tests which are UNIX based, won't work on Windows systems
+
+## Examples
+
+To run all tests:
+
+`busted`
+
+To run unit tests in LuaRocks directory type :
+
+`busted -t "unit"`
+
+To run integration tests without tests which use ssh:
+
+`busted -t "integration" --exclude-tags=ssh`
diff --git a/spec/add_spec.lua b/spec/add_spec.lua
new file mode 100644
index 0000000..60eea86
--- /dev/null
+++ b/spec/add_spec.lua
@@ -0,0 +1,41 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+local extra_rocks = {
+ "/luasocket-${LUASOCKET}.src.rock",
+}
+
+describe("LuaRocks add tests #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ describe("LuaRocks-admin add tests", function()
+ it("invalid rock #ssh", function()
+ assert.is_false(run.luarocks_admin_bool("--server=testing add invalid"))
+ end)
+
+ it("missing argument", function()
+ assert.is_false(run.luarocks_admin_bool("--server=testing add"))
+ end)
+
+ it("invalid server", function()
+ assert.is_false(run.luarocks_admin_bool("--server=invalid add " .. testing_paths.testing_server .. "/luasocket-${LUASOCKET}.src.rock"))
+ end)
+
+ it("invalid server #ssh", function()
+ assert.is_true(run.luarocks_admin_bool("--server=testing add " .. testing_paths.testing_server .. "/luasocket-${LUASOCKET}.src.rock"))
+ end)
+
+ --TODO This test fails, sftp support not yet implemented
+ it("invalid server", function()
+ assert.is_false(run.luarocks_admin_bool("--server=testing add luasocket-${LUASOCKET}.src.rock", { LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/testing_config_sftp.lua" } ))
+ end)
+
+ it("split server url", function()
+ assert.is_false(run.luarocks_admin_bool("--server=\"localhost@/tmp/luarocks_testing\" add " .. testing_paths.testing_server .. "/luasocket-${LUASOCKET}.src.rock"))
+ end)
+ end)
+end)
diff --git a/spec/build_spec.lua b/spec/build_spec.lua
new file mode 100644
index 0000000..034c70d
--- /dev/null
+++ b/spec/build_spec.lua
@@ -0,0 +1,456 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local get_tmp_path = test_env.get_tmp_path
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+local git_repo = require("spec.util.git_repo")
+
+local cfg, fs
+
+local extra_rocks = {
+ "/lmathx-20120430.51-1.src.rock",
+ "/lmathx-20120430.51-1.rockspec",
+ "/lmathx-20120430.52-1.src.rock",
+ "/lmathx-20120430.52-1.rockspec",
+ "/lmathx-20150505-1.src.rock",
+ "/lmathx-20150505-1.rockspec",
+ "/lpeg-1.0.0-1.src.rock",
+ "/luafilesystem-${LUAFILESYSTEM}.src.rock",
+ "/luasocket-${LUASOCKET}.src.rock",
+ "spec/fixtures/a_rock-1.0-1.src.rock",
+}
+
+local c_module_source = [[
+ #include <lua.h>
+ #include <lauxlib.h>
+
+ int luaopen_c_module(lua_State* L) {
+ lua_newtable(L);
+ lua_pushinteger(L, 1);
+ lua_setfield(L, -2, "c_module");
+ return 1;
+ }
+]]
+
+describe("LuaRocks build #integration", function()
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ cfg = require("luarocks.core.cfg")
+ fs = require("luarocks.fs")
+ cfg.init()
+ fs.init()
+ end)
+
+ describe("building with flags", function()
+ it("verbose", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+
+ assert.is_true(run.luarocks_bool("build --verbose test-1.0-1.rockspec"))
+ assert.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/test/1.0-1/test-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("fails if the deps-mode argument is invalid", function()
+ assert.is_false(run.luarocks_bool("build --deps-mode=123 " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec"))
+ assert.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ end)
+
+ it("with --only-sources", function()
+ assert.is_true(run.luarocks_bool("download --server=" .. testing_paths.fixtures_dir .. "/a_repo --rockspec a_rock 1.0"))
+ assert.is_false(run.luarocks_bool("build --only-sources=\"http://example.com\" a_rock-1.0-1.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+
+ assert.is_true(run.luarocks_bool("download --server=" .. testing_paths.fixtures_dir .. "/a_repo --source a_rock 1.0"))
+ assert.is_true(run.luarocks_bool("build --only-sources=\"http://example.com\" a_rock-1.0-1.src.rock"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+
+ assert.is_true(os.remove("a_rock-1.0-1.rockspec"))
+ assert.is_true(os.remove("a_rock-1.0-1.src.rock"))
+ end)
+
+ it("fails if an empty tree is given", function()
+ assert.is_false(run.luarocks_bool("build --tree=\"\" " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec"))
+ assert.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ end)
+ end)
+
+ describe("basic builds", function()
+ it("luacov diff version", function()
+ assert.is_true(run.luarocks_bool("build luacov ${LUACOV}"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/luacov/${LUACOV}/luacov-${LUACOV}.rockspec"))
+ end)
+
+ it("fails if the current platform is not supported", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ supported_platforms = {
+ "unix", "macosx"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+
+ if test_env.TEST_TARGET_OS == "windows" then
+ assert.is_false(run.luarocks_bool("build test-1.0-1.rockspec")) -- Error: This rockspec does not support windows platforms
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/test/1.0-1/test-1.0-1.rockspec"))
+ else
+ assert.is_true(run.luarocks_bool("build test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/test/1.0-1/test-1.0-1.rockspec"))
+ end
+ end, finally)
+ end)
+
+ it("with skipping dependency checks", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock 1.0"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+
+ assert.is_true(run.luarocks_bool("build test-1.0-1.rockspec --deps-mode=none"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/test/1.0-1/test-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("lmathx deps partial match", function()
+ if test_env.LUA_V == "5.1" or test_env.LUAJIT_V then
+ assert.is_true(run.luarocks_bool("build lmathx"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lmathx/20120430.51-1/lmathx-20120430.51-1.rockspec"))
+ elseif test_env.LUA_V == "5.2" then
+ assert.is_true(run.luarocks_bool("build lmathx"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lmathx/20120430.52-1/lmathx-20120430.52-1.rockspec"))
+ elseif test_env.LUA_V == "5.3" then
+ assert.is_true(run.luarocks_bool("build lmathx"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lmathx/20150505-1/lmathx-20150505-1.rockspec"))
+ end
+ end)
+ end)
+
+ describe("#namespaces", function()
+ it("builds a namespaced package from the command-line", function()
+ assert(run.luarocks_bool("build a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.is_false(run.luarocks_bool("show a_rock 1.0"))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ end)
+
+ it("builds a package with a namespaced dependency", function()
+ assert(run.luarocks_bool("build has_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show has_namespaced_dep"))
+ assert.is_false(run.luarocks_bool("show a_rock 1.0"))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ end)
+
+ it("builds a package reusing a namespaced dependency", function()
+ assert(run.luarocks_bool("build a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ local output = run.luarocks("build has_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" )
+ assert.has.no.match("Missing dependencies", output)
+ end)
+
+ it("builds a package considering namespace of locally installed package", function()
+ assert(run.luarocks_bool("build a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ local output = run.luarocks("build has_another_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" )
+ assert.has.match("Missing dependencies", output)
+ print(output)
+ assert(run.luarocks_bool("show a_rock 3.0"))
+ end)
+ end)
+
+ describe("more complex tests", function()
+ if test_env.TYPE_TEST_ENV == "full" then
+ it("luacheck show downloads test_config", function()
+ local output = run.luarocks("build luacheck", { LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/testing_config_show_downloads.lua"} )
+ assert.is.truthy(output:match("%.%.%."))
+ end)
+ end
+
+ it("only deps", function()
+ local rockspec = testing_paths.fixtures_dir .. "/build_only_deps-0.1-1.rockspec"
+
+ assert.is_true(run.luarocks_bool("build " .. rockspec .. " --only-deps"))
+ assert.is_false(run.luarocks_bool("show build_only_deps"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/build_only_deps/0.1-1/build_only_deps-0.1-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ end)
+
+ it("only deps of a given rockspec", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock 1.0"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+
+ assert.is.truthy(run.luarocks_bool("build --server=" .. testing_paths.fixtures_dir .. "/a_repo test-1.0-1.rockspec --only-deps"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/test/1.0-1/test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("only deps of a given rock", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock 1.0"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+
+ assert.is.truthy(run.luarocks_bool("pack test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes("test-1.0-1.src.rock"))
+
+ assert.is.truthy(run.luarocks_bool("build --server=" .. testing_paths.fixtures_dir .. "/a_repo test-1.0-1.src.rock --only-deps"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/test/1.0-1/test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("fails if given an argument with an invalid patch", function()
+ assert.is_false(run.luarocks_bool("build " .. testing_paths.fixtures_dir .. "/invalid_patch-0.1-1.rockspec"))
+ end)
+ end)
+
+ describe("rockspec format 3.0 #rs3", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ tmpdir = get_tmp_path()
+ olddir = lfs.currentdir()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+
+ lfs.mkdir("autodetect")
+ write_file("autodetect/bla.lua", "return {}", finally)
+ write_file("c_module.c", c_module_source, finally)
+ end)
+
+ after_each(function()
+ if olddir then
+ lfs.chdir(olddir)
+ if tmpdir then
+ lfs.rmdir("autodetect")
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("defaults to build.type == 'builtin'", function()
+ local rockspec = "a_rock-1.0-1.rockspec"
+ test_env.write_file(rockspec, [[
+ rockspec_format = "3.0"
+ package = "a_rock"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. testing_paths.fixtures_dir:gsub("\\", "/") .. [[/a_rock.lua"
+ }
+ description = {
+ summary = "An example rockspec",
+ }
+ dependencies = {
+ "lua >= 5.1"
+ }
+ build = {
+ modules = {
+ build = "a_rock.lua"
+ },
+ }
+ ]], finally)
+ assert.truthy(run.luarocks_bool("build " .. rockspec))
+ assert.is.truthy(run.luarocks("show a_rock"))
+ end)
+
+ it("'builtin' detects lua files if build is not given", function()
+ local rockspec = "autodetect-1.0-1.rockspec"
+ test_env.write_file(rockspec, [[
+ rockspec_format = "3.0"
+ package = "autodetect"
+ version = "1.0-1"
+ source = {
+ url = "file://autodetect/bla.lua"
+ }
+ description = {
+ summary = "An example rockspec",
+ }
+ dependencies = {
+ "lua >= 5.1"
+ }
+ ]], finally)
+ assert.truthy(run.luarocks_bool("build " .. rockspec))
+ assert.match("bla.lua", run.luarocks("show autodetect"))
+ end)
+
+ it("'builtin' synthesizes external_dependencies if not given but a library is given in build", function()
+ local rockspec = "autodetect-1.0-1.rockspec"
+ test_env.write_file(rockspec, [[
+ rockspec_format = "3.0"
+ package = "autodetect"
+ version = "1.0-1"
+ source = {
+ url = "file://c_module.c"
+ }
+ description = {
+ summary = "An example rockspec",
+ }
+ dependencies = {
+ "lua >= 5.1"
+ }
+ build = {
+ modules = {
+ c_module = {
+ sources = "c_module.c",
+ libraries = "inexistent_library",
+ }
+ }
+ }
+ ]], finally)
+ assert.match("INEXISTENT_LIBRARY_DIR", run.luarocks("build " .. rockspec))
+ end)
+ end)
+
+ describe("#mock external dependencies", function()
+ lazy_setup(function()
+ test_env.setup_specs(nil, "mock")
+ test_env.mock_server_init()
+ end)
+
+ lazy_teardown(function()
+ test_env.mock_server_done()
+ end)
+
+ it("fails when missing external dependency", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("missing_external-0.1-1.rockspec", [[
+ package = "missing_external"
+ version = "0.1-1"
+ source = {
+ url = "https://example.com/build.lua"
+ }
+ external_dependencies = {
+ INEXISTENT = {
+ library = "inexistentlib*",
+ header = "inexistentheader*.h",
+ }
+ }
+ dependencies = {
+ "lua >= 5.1"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ build = "build.lua"
+ }
+ }
+ ]])
+ assert.is_false(run.luarocks_bool("build missing_external-0.1-1.rockspec INEXISTENT_INCDIR=\"/invalid/dir\""))
+ end, finally)
+ end)
+
+ it("builds with external dependency", function()
+ local rockspec = testing_paths.fixtures_dir .. "/with_external_dep-0.1-1.rockspec"
+ local foo_incdir = testing_paths.fixtures_dir .. "/with_external_dep"
+ assert.is_truthy(run.luarocks_bool("build " .. rockspec .. " FOO_INCDIR=\"" .. foo_incdir .. "\""))
+ assert.is.truthy(run.luarocks("show with_external_dep"))
+ end)
+ end)
+
+ describe("#build_dependencies", function()
+ it("builds with a build dependency", function()
+ assert(run.luarocks_bool("build has_build_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show has_build_dep 1.0"))
+ assert(run.luarocks_bool("show a_build_dep 1.0"))
+ end)
+ end)
+
+ describe("#unix build from #git", function()
+ local git
+
+ lazy_setup(function()
+ git = git_repo.start()
+ end)
+
+ lazy_teardown(function()
+ if git then
+ git:stop()
+ end
+ end)
+
+ it("using --branch", function()
+ write_file("my_branch-1.0-1.rockspec", [[
+ rockspec_format = "3.0"
+ package = "my_branch"
+ version = "1.0-1"
+ source = {
+ url = "git://localhost/testrock"
+ }
+ ]], finally)
+ assert.is_false(run.luarocks_bool("build --branch unknown-branch ./my_branch-1.0-1.rockspec"))
+ assert.is_true(run.luarocks_bool("build --branch test-branch ./my_branch-1.0-1.rockspec"))
+ end)
+ end)
+end)
diff --git a/spec/cmd_spec.lua b/spec/cmd_spec.lua
new file mode 100644
index 0000000..20248af
--- /dev/null
+++ b/spec/cmd_spec.lua
@@ -0,0 +1,105 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+
+describe("LuaRocks command line #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs()
+ end)
+
+ describe("--version", function()
+ it("returns the LuaRocks version", function()
+ local output = run.luarocks("--version")
+ assert.match("LuaRocks main command-line interface", output, 1, true)
+ end)
+
+ it("runs if Lua detection fails", function()
+ test_env.run_in_tmp(function(tmpdir)
+ test_env.write_file("bad_config.lua", [[
+ variables = {
+ LUA_DIR = "/bad/lua/dir",
+ }
+ ]], finally)
+ local env = {
+ LUAROCKS_CONFIG = "bad_config.lua"
+ }
+ local output = run.luarocks("--version", env)
+ assert.match("LuaRocks main command-line interface", output, 1, true)
+ end, finally)
+ end)
+ end)
+
+ describe("--lua-dir", function()
+ it("fails if given an invalid path", function()
+ local output = run.luarocks("--lua-dir=/bad/lua/path")
+ assert.match("Lua interpreter not found at /bad/lua/path", output, 1, true)
+ end)
+
+ it("fails if given a valid path without Lua", function()
+ local output = run.luarocks("--lua-dir=.")
+ assert.match("Lua interpreter not found at .", output, 1, true)
+ end)
+
+ it("passes if given a valid path with Lua", function()
+ assert.truthy(run.luarocks("--lua-dir=" .. test_env.testing_paths.luadir))
+ end)
+
+ it("passes if given a quoted path with Lua", function()
+ assert.truthy(run.luarocks("--lua-dir '" .. test_env.testing_paths.luadir .. "'"))
+ end)
+ end)
+
+ describe("--lua-version", function()
+ it("fails if given something that is not a number", function()
+ local output = run.luarocks("--lua-version=bozo")
+ assert.match("malformed", output, 1, true)
+ end)
+
+ it("sets the version independently of project tree", function()
+ test_env.run_in_tmp(function(tmpdir)
+ assert.truthy(run.luarocks_bool("init --lua-version=" .. test_env.lua_version .. " --lua-versions=" .. test_env.lua_version))
+
+ local output = run.luarocks("--lua-version=1.0")
+ assert.match("Version%s*:%s*1.0", output)
+
+ output = run.luarocks("--lua-version=1.0 --project-tree=.")
+ assert.match("Version%s*:%s*1.0", output)
+ end, finally)
+ end)
+ end)
+
+ it("detects version based on project tree", function()
+ test_env.run_in_tmp(function(tmpdir)
+ assert.truthy(run.luarocks_bool("init --lua-version=" .. test_env.lua_version))
+ assert.truthy(run.luarocks_bool("config lua_version 1.0 --project-tree=" .. tmpdir .. "/lua_modules"))
+
+ lfs.mkdir("aaa")
+ lfs.chdir("aaa")
+ lfs.mkdir("bbb")
+ lfs.chdir("bbb")
+
+ local output = run.luarocks("")
+ assert.match("Version%s*:%s*1.0", output)
+ end, finally)
+ end)
+
+ -- for backward compatibility
+ it("detects version of a project based on config", function()
+ test_env.run_in_tmp(function(tmpdir)
+ assert.truthy(run.luarocks_bool("init --lua-version=" .. test_env.lua_version))
+ os.remove(".luarocks/config-" .. test_env.lua_version .. ".lua")
+ os.remove(".luarocks/default-lua-version.lua")
+ test_env.write_file(".luarocks/config-5.2.lua", [[ ]], finally)
+
+ lfs.mkdir("aaa")
+ lfs.chdir("aaa")
+ lfs.mkdir("bbb")
+ lfs.chdir("bbb")
+
+ local output = run.luarocks("")
+ assert.match("Version%s*:%s*5.2", output)
+ end, finally)
+ end)
+
+end)
diff --git a/spec/config_spec.lua b/spec/config_spec.lua
new file mode 100644
index 0000000..9dd8fbc
--- /dev/null
+++ b/spec/config_spec.lua
@@ -0,0 +1,253 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local env_variables = test_env.env_variables
+local write_file = test_env.write_file
+local get_tmp_path = test_env.get_tmp_path
+local hardcoded
+
+describe("LuaRocks config tests #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs()
+ -- needs to be required here, because hardcoded is created after first loading of specs
+ hardcoded = require("luarocks.core.hardcoded")
+ end)
+
+ describe("full configuration query", function()
+ it("no flags/arguments", function()
+ assert.match("rocks_servers = {", run.luarocks("config"))
+ end)
+
+ it("--json", function()
+ assert.match('"rocks_servers":[', run.luarocks("config --json"), 1, true)
+ end)
+
+ it("with --tree respects custom config", function()
+ write_file("my_config.lua", [[
+ rocks_trees = {
+ {
+ name = "system",
+ root = "/example/tree",
+ lua_dir = "/example/luadir",
+ },
+ }
+ ]], finally)
+ local output = run.luarocks("config", {LUAROCKS_CONFIG = "my_config.lua"})
+ assert.match([[deploy_lua_dir = "/example/luadir"]], output)
+ output = run.luarocks("config --tree=system", {LUAROCKS_CONFIG = "my_config.lua"})
+ assert.match([[deploy_lua_dir = "/example/luadir"]], output)
+ end)
+
+ it("#unix can find config via $XDG_CONFIG_HOME", function()
+ local tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ lfs.mkdir(tmpdir .. "/luarocks")
+ local tmp_config_file = tmpdir .. "/luarocks/config-" .. test_env.lua_version .. ".lua"
+ write_file(tmp_config_file, [[
+ rocks_trees = {
+ {
+ name = "system",
+ root = "/example/tree",
+ lua_dir = "/example/luadir",
+ },
+ }
+ ]])
+ finally(function()
+ os.remove(tmp_config_file)
+ lfs.rmdir(tmpdir .. "/luarocks")
+ lfs.rmdir(tmpdir)
+ end)
+
+ local output = run.luarocks("config --verbose", {XDG_CONFIG_HOME = tmpdir, LUAROCKS_CONFIG="invalid"})
+ assert.match([[deploy_lua_dir = "/example/luadir"]], output)
+ end)
+ end)
+
+ describe("query flags", function()
+ it("--lua-incdir returns a subdir of LUA_DIR", function()
+ local output = run.luarocks("config --lua-incdir")
+ assert.match(hardcoded.LUA_DIR, output, 1, true)
+ end)
+
+ it("--lua-libdir returns a subdir of LUA_DIR", function()
+ local output = run.luarocks("config --lua-libdir")
+ assert.match(hardcoded.LUA_DIR, output, 1, true)
+ end)
+
+ it("--lua-ver returns the Lua version", function()
+ local output = run.luarocks("config --lua-ver")
+ local lua_version = _VERSION:gsub("Lua ", "")
+ if test_env.LUAJIT_V then
+ lua_version = "5.1"
+ end
+ assert.are.same(lua_version, output)
+ end)
+
+ it("--rock-trees lists rock trees", function()
+ assert.is_true(run.luarocks_bool("config --rock-trees"))
+ end)
+
+ describe("--user-config", function()
+ it("returns user config dir", function()
+ local user_config_path = run.luarocks("config --user-config")
+ assert.is.truthy(lfs.attributes(user_config_path))
+ end)
+
+ it("handles a missing user config", function()
+ local output = run.luarocks("config --user-config", {LUAROCKS_CONFIG = "missing_file.lua"})
+ assert.match("Warning", output)
+ end)
+ end)
+
+ describe("--system-config", function()
+ local scdir = testing_paths.testing_lrprefix .. "/etc/luarocks"
+ local configfile = scdir .. "/config-" .. env_variables.LUA_VERSION .. ".lua"
+
+ it("fails if system config doesn't exist", function()
+ os.rename(configfile, configfile .. ".bak")
+ finally(function()
+ os.rename(configfile .. ".bak", configfile)
+ end)
+ assert.is_false(run.luarocks_bool("config --system-config"))
+ end)
+
+ it("fails if system config is invalid", function()
+ lfs.mkdir(testing_paths.testing_lrprefix)
+ lfs.mkdir(testing_paths.testing_lrprefix .. "/etc/")
+ lfs.mkdir(scdir)
+
+ local sysconfig = io.open(configfile, "w+")
+ sysconfig:write("if if if")
+ sysconfig:close()
+ finally(function()
+ os.remove(configfile)
+ end)
+ assert.is_false(run.luarocks_bool("config --system-config"))
+ end)
+ end)
+ end)
+
+ describe("read config keys", function()
+ it("reads a simple config key", function()
+ local output = run.luarocks("config user_agent")
+ assert.match("LuaRocks/", output)
+ end)
+
+ it("reads an array config key", function()
+ local output = run.luarocks("config rocks_trees[2]")
+ assert.match("{%s*name", output)
+ end)
+
+ it("can read as JSON", function()
+ local output = run.luarocks("config rocks_trees --json")
+ assert.match('^%[{', output)
+ end)
+
+ it("reads an array -> hash config key", function()
+ local output = run.luarocks("config rocks_trees[2].name")
+ assert.match("[a-z]+", output)
+ end)
+
+ it("reads a hash config key", function()
+ local output = run.luarocks("config variables.ICACLS")
+ assert.same("icacls", output)
+ end)
+
+ it("fails on invalid config key", function()
+ local output = run.luarocks("config xyz")
+ assert.match("Error: Unknown entry xyz", output)
+ end)
+ end)
+
+ describe("unset config keys", function()
+ it("unsets a simple config key", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ assert.truthy(run.luarocks_bool("config my_var my_value"))
+
+ local output = run.luarocks("config my_var")
+ assert.match("my_value", output)
+
+ assert.truthy(run.luarocks_bool("config my_var --unset"))
+
+ output = run.luarocks("config my_var")
+ assert.not_match("my_value", output)
+ end, finally)
+ end)
+ end)
+
+ describe("write config keys", function()
+ it("rejects invalid --scope", function()
+ assert.is_false(run.luarocks_bool("config web_browser foo --scope=foo"))
+ end)
+
+ it("reads an array config key", function()
+ local output = run.luarocks("config rocks_trees[2]")
+ assert.match("{%s*name", output)
+ end)
+
+ it("writes a simple config key", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ assert.truthy(run.luarocks_bool("config web_browser foo --scope=project"))
+
+ local output = run.luarocks("config web_browser")
+ assert.match("foo", output)
+ end, finally)
+ end)
+
+ it("writes a hash config key", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ assert.truthy(run.luarocks_bool("config variables.FOO_DIR /foo/bar --scope=project"))
+
+ local output = run.luarocks("config variables.FOO_DIR")
+ assert.match("/foo/bar", output)
+ end, finally)
+ end)
+
+ it("writes a boolean config key", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ assert.truthy(run.luarocks_bool("config hooks_enabled true"))
+
+ local output = run.luarocks("config hooks_enabled")
+ assert.match("true", output)
+ end, finally)
+ end)
+
+ it("writes an array config key", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ assert.truthy(run.luarocks_bool("config external_deps_patterns.lib[1] testtest --scope=project"))
+
+ local output = run.luarocks("config external_deps_patterns.lib[1]")
+ assert.match("testtest", output)
+ end, finally)
+ end)
+
+ end)
+
+end)
diff --git a/spec/deps_spec.lua b/spec/deps_spec.lua
new file mode 100644
index 0000000..766e0f0
--- /dev/null
+++ b/spec/deps_spec.lua
@@ -0,0 +1,114 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+local extra_rocks = {
+ "/lxsh-${LXSH}.src.rock",
+ "/luasocket-${LUASOCKET}.src.rock",
+ "/lpeg-${LPEG}.src.rock",
+}
+
+describe("LuaRocks deps-mode #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("one", function()
+ assert.is_true(run.luarocks_bool("build --tree=system lpeg"))
+ assert.is_true(run.luarocks_bool("build --deps-mode=one --tree=" .. testing_paths.testing_tree .. " lxsh"))
+
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("order", function()
+ assert.is_true(run.luarocks_bool("build --tree=system lpeg"))
+ assert.is_true(run.luarocks_bool("build --deps-mode=order --tree=" .. testing_paths.testing_tree .. " lxsh"))
+
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("order sys", function()
+ assert.is_true(run.luarocks_bool("build --tree=" .. testing_paths.testing_tree .. " lpeg"))
+ assert.is_true(run.luarocks_bool("build --deps-mode=order --tree=" .. testing_paths.testing_sys_tree .. " lxsh"))
+
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("all sys", function()
+ assert.is_true(run.luarocks_bool("build --tree=" .. testing_paths.testing_tree .. " lpeg"))
+ assert.is_true(run.luarocks_bool("build --deps-mode=all --tree=" .. testing_paths.testing_sys_tree .. " lxsh"))
+
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("none", function()
+ assert.is_true(run.luarocks_bool("build --tree=" .. testing_paths.testing_tree .. " lpeg"))
+ assert.is_true(run.luarocks_bool("build --deps-mode=none lxsh"))
+
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("LuaRocks nodeps alias", function()
+ assert.is_true(run.luarocks_bool("build --tree=" .. testing_paths.testing_tree .. " --nodeps lxsh"))
+
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("make order", function()
+ assert.is_true(run.luarocks_bool("build --tree=" .. testing_paths.testing_sys_tree .. " lpeg"))
+ assert.is_true(run.luarocks_bool("download --source lxsh ${LXSH_V}"))
+ assert.is_true(run.luarocks_bool("unpack lxsh-${LXSH}.src.rock"))
+ lfs.chdir("lxsh-${LXSH}/lxsh-${LXSH_V}-1/")
+ assert.is_true(run.luarocks_bool("make --tree=" .. testing_paths.testing_tree .. " --deps-mode=order"))
+
+ finally(function()
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("lxsh-${LXSH}")
+ assert.is_true(os.remove("lxsh-${LXSH}.src.rock"))
+ end)
+
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("make order sys", function()
+ assert.is_true(run.luarocks_bool("build --tree=" .. testing_paths.testing_tree .. " lpeg"))
+ assert.is_true(run.luarocks_bool("download --source lxsh ${LXSH_V}"))
+ assert.is_true(run.luarocks_bool("unpack lxsh-${LXSH}.src.rock"))
+ lfs.chdir("lxsh-${LXSH}/lxsh-${LXSH_V}-1/")
+ assert.is_true(run.luarocks_bool("make --tree=" .. testing_paths.testing_sys_tree .. " --deps-mode=order"))
+
+ finally(function()
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("lxsh-${LXSH}")
+ assert.is_true(os.remove("lxsh-${LXSH}.src.rock"))
+ end)
+
+ assert.is.truthy(lfs.attributes(testing_paths.testing_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lpeg/${LPEG}/lpeg-${LPEG}.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+end)
diff --git a/spec/doc_spec.lua b/spec/doc_spec.lua
new file mode 100644
index 0000000..f48f951
--- /dev/null
+++ b/spec/doc_spec.lua
@@ -0,0 +1,154 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+describe("luarocks doc #integration", function()
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ describe("basic tests", function()
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("doc"))
+ end)
+
+ it("with invalid argument", function()
+ assert.is_false(run.luarocks_bool("doc invalid"))
+ end)
+
+ it("with no homepage and no doc folder", function()
+ test_env.run_in_tmp(function(tmpdir)
+ test_env.write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://test.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+ test_env.write_file("test.lua", "return {}", finally)
+
+ assert.is_true(run.luarocks_bool("install test-1.0-1.rockspec"))
+ assert.is_false(run.luarocks_bool("doc test --home"))
+ end, finally)
+ end)
+
+ it("with no doc folder but with homepage", function()
+ test_env.run_in_tmp(function(tmpdir)
+ test_env.write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://test.lua"
+ }
+ description = {
+ homepage = "http://www.example.com"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+ test_env.write_file("test.lua", "return {}", finally)
+
+ assert.is_true(run.luarocks_bool("install test-1.0-1.rockspec"))
+ local output = assert.is.truthy(run.luarocks("doc test"))
+ assert.is.truthy(output:find("documentation directory not found"))
+ end, finally)
+ end)
+ end)
+
+ describe("#namespaces", function()
+ it("retrieves docs for a namespaced package from the command-line", function()
+ assert(run.luarocks_bool("build a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("build a_rock 1.0 --keep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.match("a_rock 2.0", run.luarocks("doc a_user/a_rock"))
+ end)
+ end)
+
+ describe("tests with flags", function()
+ it("of installed package", function()
+ test_env.run_in_tmp(function(tmpdir)
+ test_env.write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://test.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+ test_env.write_file("test.lua", "return {}", finally)
+
+ assert.is_true(run.luarocks_bool("install test-1.0-1.rockspec"))
+ lfs.mkdir(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc")
+ test_env.write_file(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc/doc.md", "", finally)
+ test_env.write_file(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc/readme.md", "", finally)
+ assert.is_true(run.luarocks_bool("doc test"))
+ end, finally)
+ end)
+
+ it("with --list", function()
+ test_env.run_in_tmp(function(tmpdir)
+ test_env.write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://test.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+ test_env.write_file("test.lua", "return {}", finally)
+
+ assert.is_true(run.luarocks_bool("install test-1.0-1.rockspec"))
+ lfs.mkdir(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc")
+ test_env.write_file(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc/doc1.md", "", finally)
+ test_env.write_file(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc/doc2.md", "", finally)
+ local output = assert.is.truthy(run.luarocks("doc test --list"))
+ assert.is.truthy(output:find("doc1%.md"))
+ assert.is.truthy(output:find("doc2%.md"))
+ end, finally)
+ end)
+
+ it("with --porcelain", function()
+ test_env.run_in_tmp(function(tmpdir)
+ test_env.write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://test.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+ test_env.write_file("test.lua", "return {}", finally)
+
+ assert.is_true(run.luarocks_bool("install test-1.0-1.rockspec"))
+ lfs.mkdir(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc")
+ test_env.write_file(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc/doc1.md", "", finally)
+ test_env.write_file(testing_paths.testing_sys_rocks .. "/test/1.0-1/doc/doc2.md", "", finally)
+ assert.is_true(run.luarocks_bool("doc test --porcelain"))
+ end, finally)
+ end)
+ end)
+end)
diff --git a/spec/download_spec.lua b/spec/download_spec.lua
new file mode 100644
index 0000000..f7c10e8
--- /dev/null
+++ b/spec/download_spec.lua
@@ -0,0 +1,55 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+local extra_rocks = {
+ "/say-1.3-1.rockspec",
+}
+
+describe("luarocks download #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("download"))
+ end)
+
+ it("invalid", function()
+ assert.is_false(run.luarocks_bool("download invalid"))
+ end)
+
+ it("all with delete downloaded files", function() --TODO maybe download --all more rocks
+ assert.is_true(run.luarocks_bool("download --all say"))
+ assert.is.truthy(lfs.attributes("say-1.3-1.rockspec"))
+ test_env.remove_files(lfs.currentdir(), "say--")
+ end)
+
+ it("rockspec version", function()
+ assert.is_true(run.luarocks_bool("download --rockspec say 1.3-1"))
+ assert.is.truthy(lfs.attributes("say-1.3-1.rockspec"))
+ test_env.remove_files(lfs.currentdir(), "say--")
+ end)
+
+ describe("#namespaces", function()
+ it("retrieves namespaced rockspec", function()
+ finally(function()
+ os.remove("a_rock-2.0-1.rockspec")
+ end)
+ assert(run.luarocks_bool("download a_user/a_rock --rockspec --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(lfs.attributes("a_rock-2.0-1.rockspec"))
+ end)
+
+ it("retrieves namespaced rock", function()
+ finally(function()
+ os.remove("a_rock-2.0-1.src.rock")
+ end)
+ assert(run.luarocks_bool("download a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(lfs.attributes("a_rock-2.0-1.src.rock"))
+ end)
+ end)
+
+
+end)
diff --git a/spec/dummy_spec.lua b/spec/dummy_spec.lua
new file mode 100644
index 0000000..9ddd669
--- /dev/null
+++ b/spec/dummy_spec.lua
@@ -0,0 +1,24 @@
+-- Dummy test file for including files with 0% coverage in the luacov report
+
+local test_env = require("spec.util.test_env")
+local testing_paths = test_env.testing_paths
+
+test_env.setup_specs()
+local runner = require("luacov.runner")
+runner.init(testing_paths.testrun_dir .. "/luacov.config")
+
+require("luarocks.build.cmake")
+require("luarocks.build.command")
+require("luarocks.tools.tar")
+require("luarocks.fetch.cvs")
+require("luarocks.fetch.git_file")
+require("luarocks.fetch.git_https")
+require("luarocks.fetch.git_ssh")
+require("luarocks.fetch.hg_http")
+require("luarocks.fetch.hg_https")
+require("luarocks.fetch.hg_ssh")
+require("luarocks.fetch.hg")
+require("luarocks.fetch.sscm")
+require("luarocks.fetch.svn")
+
+runner.save_stats()
diff --git a/spec/external_spec.lua b/spec/external_spec.lua
new file mode 100644
index 0000000..5a69a67
--- /dev/null
+++ b/spec/external_spec.lua
@@ -0,0 +1,32 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+describe("luarocks external commands #integration", function()
+ lazy_setup(function()
+ test_env.setup_specs()
+ test_env.mock_server_init()
+ end)
+
+ lazy_teardown(function()
+ test_env.mock_server_done()
+ end)
+
+ it("installs a legacy external command", function()
+ local rockspec = testing_paths.fixtures_dir .. "/legacyexternalcommand-0.1-1.rockspec"
+ assert.is_truthy(run.luarocks_bool("build " .. rockspec))
+ assert.is.truthy(run.luarocks("show legacyexternalcommand"))
+ local output = run.luarocks("legacyexternalcommand")
+ assert.match("Argument missing", output)
+ output = run.luarocks("legacyexternalcommand foo")
+ assert.match("ARG1\tfoo", output)
+ assert.match("ARG2\tnil", output)
+ output = run.luarocks("legacyexternalcommand foo bar")
+ assert.match("ARG1\tfoo", output)
+ assert.match("ARG2\tbar", output)
+ output = run.luarocks("legacyexternalcommand foo bar bla")
+ assert.match("ARG1\tfoo", output)
+ assert.match("ARG2\tbar", output)
+ end)
+end)
+
diff --git a/spec/fixtures/a_repo/a_build_dep-1.0-1.rockspec b/spec/fixtures/a_repo/a_build_dep-1.0-1.rockspec
new file mode 100644
index 0000000..2398d3d
--- /dev/null
+++ b/spec/fixtures/a_repo/a_build_dep-1.0-1.rockspec
@@ -0,0 +1,18 @@
+rockspec_format = "3.0"
+package = "a_build_dep"
+version = "1.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec that is a build dependency for has_build_dep.",
+}
+dependencies = {
+ "lua >= 5.1",
+}
+build = {
+ type = "builtin",
+ modules = {
+ build_dep = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/a_build_dep-1.0-1.src.rock b/spec/fixtures/a_repo/a_build_dep-1.0-1.src.rock
new file mode 100644
index 0000000..c56ee34
--- /dev/null
+++ b/spec/fixtures/a_repo/a_build_dep-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/a_rock-1.0-1.rockspec b/spec/fixtures/a_repo/a_rock-1.0-1.rockspec
new file mode 100644
index 0000000..69d7820
--- /dev/null
+++ b/spec/fixtures/a_repo/a_rock-1.0-1.rockspec
@@ -0,0 +1,18 @@
+package = "a_rock"
+version = "1.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+ homepage = "http://www.example.com"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ build = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/a_rock-1.0-1.src.rock b/spec/fixtures/a_repo/a_rock-1.0-1.src.rock
new file mode 100644
index 0000000..9d0bb45
--- /dev/null
+++ b/spec/fixtures/a_repo/a_rock-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/a_rock-2.0-1.src.rock b/spec/fixtures/a_repo/a_rock-2.0-1.src.rock
new file mode 100644
index 0000000..5824c76
--- /dev/null
+++ b/spec/fixtures/a_repo/a_rock-2.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/busted_project-0.1-1.rockspec b/spec/fixtures/a_repo/busted_project-0.1-1.rockspec
new file mode 100644
index 0000000..54ed28a
--- /dev/null
+++ b/spec/fixtures/a_repo/busted_project-0.1-1.rockspec
@@ -0,0 +1,19 @@
+rockspec_format = "3.0"
+package = "busted_project"
+version = "0.1-1"
+source = {
+ url = "http://localhost:8080/file/busted_project-0.1.tar.gz",
+ dir = "busted_project",
+}
+description = {
+ summary = "A project that uses Busted tests",
+}
+build = {
+ type = "builtin",
+ modules = {
+ sum = "sum.lua",
+ }
+}
+test = {
+ type = "busted",
+}
diff --git a/spec/fixtures/a_repo/busted_project-0.1-1.src.rock b/spec/fixtures/a_repo/busted_project-0.1-1.src.rock
new file mode 100644
index 0000000..db92411
--- /dev/null
+++ b/spec/fixtures/a_repo/busted_project-0.1-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.rockspec b/spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.rockspec
new file mode 100644
index 0000000..04cb06c
--- /dev/null
+++ b/spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.rockspec
@@ -0,0 +1,19 @@
+rockspec_format = "3.0"
+package = "has_another_namespaced_dep"
+version = "1.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "another_user/a_rock",
+ "lua >= 5.1",
+}
+build = {
+ type = "builtin",
+ modules = {
+ bla = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.src.rock b/spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.src.rock
new file mode 100644
index 0000000..4bbbf1a
--- /dev/null
+++ b/spec/fixtures/a_repo/has_another_namespaced_dep-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/has_build_dep-1.0-1.all.rock b/spec/fixtures/a_repo/has_build_dep-1.0-1.all.rock
new file mode 100644
index 0000000..a2d09ab
--- /dev/null
+++ b/spec/fixtures/a_repo/has_build_dep-1.0-1.all.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/has_build_dep-1.0-1.rockspec b/spec/fixtures/a_repo/has_build_dep-1.0-1.rockspec
new file mode 100644
index 0000000..417473a
--- /dev/null
+++ b/spec/fixtures/a_repo/has_build_dep-1.0-1.rockspec
@@ -0,0 +1,22 @@
+rockspec_format = "3.0"
+package = "has_build_dep"
+version = "1.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec that has build dependencies.",
+}
+dependencies = {
+ "a_rock",
+ "lua >= 5.1",
+}
+build_dependencies = {
+ "a_build_dep",
+}
+build = {
+ type = "builtin",
+ modules = {
+ bla = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/has_build_dep-1.0-1.src.rock b/spec/fixtures/a_repo/has_build_dep-1.0-1.src.rock
new file mode 100644
index 0000000..fc4e11b
--- /dev/null
+++ b/spec/fixtures/a_repo/has_build_dep-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/has_namespaced_dep-1.0-1.rockspec b/spec/fixtures/a_repo/has_namespaced_dep-1.0-1.rockspec
new file mode 100644
index 0000000..6152c78
--- /dev/null
+++ b/spec/fixtures/a_repo/has_namespaced_dep-1.0-1.rockspec
@@ -0,0 +1,19 @@
+rockspec_format = "3.0"
+package = "has_namespaced_dep"
+version = "1.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "a_user/a_rock",
+ "lua >= 5.1",
+}
+build = {
+ type = "builtin",
+ modules = {
+ bla = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/has_namespaced_dep-1.0-1.src.rock b/spec/fixtures/a_repo/has_namespaced_dep-1.0-1.src.rock
new file mode 100644
index 0000000..c4d5f94
--- /dev/null
+++ b/spec/fixtures/a_repo/has_namespaced_dep-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/manifest b/spec/fixtures/a_repo/manifest
new file mode 100644
index 0000000..a5f770a
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest
@@ -0,0 +1,90 @@
+commands = {}
+modules = {}
+repository = {
+ a_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ a_rock = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ },
+ ["2.0-1"] = {
+ {
+ arch = "src"
+ }
+ }
+ },
+ busted_project = {
+ ["0.1-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ has_another_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ has_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ },
+ {
+ arch = "all"
+ }
+ }
+ },
+ has_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ non_lua_file = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ },
+ ["1.0-2"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifest-5.1 b/spec/fixtures/a_repo/manifest-5.1
new file mode 100644
index 0000000..a5f770a
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.1
@@ -0,0 +1,90 @@
+commands = {}
+modules = {}
+repository = {
+ a_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ a_rock = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ },
+ ["2.0-1"] = {
+ {
+ arch = "src"
+ }
+ }
+ },
+ busted_project = {
+ ["0.1-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ has_another_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ has_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ },
+ {
+ arch = "all"
+ }
+ }
+ },
+ has_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ non_lua_file = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ },
+ ["1.0-2"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifest-5.1.zip b/spec/fixtures/a_repo/manifest-5.1.zip
new file mode 100644
index 0000000..e63d6f1
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.1.zip
Binary files differ
diff --git a/spec/fixtures/a_repo/manifest-5.2 b/spec/fixtures/a_repo/manifest-5.2
new file mode 100644
index 0000000..a5f770a
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.2
@@ -0,0 +1,90 @@
+commands = {}
+modules = {}
+repository = {
+ a_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ a_rock = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ },
+ ["2.0-1"] = {
+ {
+ arch = "src"
+ }
+ }
+ },
+ busted_project = {
+ ["0.1-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ has_another_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ has_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ },
+ {
+ arch = "all"
+ }
+ }
+ },
+ has_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ non_lua_file = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ },
+ ["1.0-2"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifest-5.2.zip b/spec/fixtures/a_repo/manifest-5.2.zip
new file mode 100644
index 0000000..cec28c0
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.2.zip
Binary files differ
diff --git a/spec/fixtures/a_repo/manifest-5.3 b/spec/fixtures/a_repo/manifest-5.3
new file mode 100644
index 0000000..a5f770a
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.3
@@ -0,0 +1,90 @@
+commands = {}
+modules = {}
+repository = {
+ a_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ a_rock = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ },
+ ["2.0-1"] = {
+ {
+ arch = "src"
+ }
+ }
+ },
+ busted_project = {
+ ["0.1-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ has_another_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ has_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ },
+ {
+ arch = "all"
+ }
+ }
+ },
+ has_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ non_lua_file = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ },
+ ["1.0-2"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifest-5.3.zip b/spec/fixtures/a_repo/manifest-5.3.zip
new file mode 100644
index 0000000..23df5c3
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.3.zip
Binary files differ
diff --git a/spec/fixtures/a_repo/manifest-5.4 b/spec/fixtures/a_repo/manifest-5.4
new file mode 100644
index 0000000..a5f770a
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.4
@@ -0,0 +1,90 @@
+commands = {}
+modules = {}
+repository = {
+ a_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ a_rock = {
+ ["1.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ },
+ ["2.0-1"] = {
+ {
+ arch = "src"
+ }
+ }
+ },
+ busted_project = {
+ ["0.1-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ },
+ has_another_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ has_build_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ },
+ {
+ arch = "all"
+ }
+ }
+ },
+ has_namespaced_dep = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ },
+ non_lua_file = {
+ ["1.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ },
+ ["1.0-2"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifest-5.4.zip b/spec/fixtures/a_repo/manifest-5.4.zip
new file mode 100644
index 0000000..14b5621
--- /dev/null
+++ b/spec/fixtures/a_repo/manifest-5.4.zip
Binary files differ
diff --git a/spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.rockspec b/spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.rockspec
new file mode 100644
index 0000000..da5a9a1
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.rockspec
@@ -0,0 +1,17 @@
+package = "a_rock"
+version = "2.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ build = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.src.rock b/spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.src.rock
new file mode 100644
index 0000000..8d10fac
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/a_rock-2.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/manifests/a_user/manifest b/spec/fixtures/a_repo/manifests/a_user/manifest
new file mode 100644
index 0000000..74b0c61
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/manifest
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["2.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/a_user/manifest-5.1 b/spec/fixtures/a_repo/manifests/a_user/manifest-5.1
new file mode 100644
index 0000000..74b0c61
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/manifest-5.1
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["2.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/a_user/manifest-5.2 b/spec/fixtures/a_repo/manifests/a_user/manifest-5.2
new file mode 100644
index 0000000..74b0c61
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/manifest-5.2
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["2.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/a_user/manifest-5.3 b/spec/fixtures/a_repo/manifests/a_user/manifest-5.3
new file mode 100644
index 0000000..74b0c61
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/manifest-5.3
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["2.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/a_user/manifest-5.4 b/spec/fixtures/a_repo/manifests/a_user/manifest-5.4
new file mode 100644
index 0000000..74b0c61
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/a_user/manifest-5.4
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["2.0-1"] = {
+ {
+ arch = "rockspec"
+ },
+ {
+ arch = "src"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.rockspec b/spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.rockspec
new file mode 100644
index 0000000..628c5a4
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.rockspec
@@ -0,0 +1,17 @@
+package = "a_rock"
+version = "3.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ a_rock = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.src.rock b/spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.src.rock
new file mode 100644
index 0000000..4c20afc
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/a_rock-3.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/manifests/another_user/manifest b/spec/fixtures/a_repo/manifests/another_user/manifest
new file mode 100644
index 0000000..185aed0
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/manifest
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["3.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/another_user/manifest-5.1 b/spec/fixtures/a_repo/manifests/another_user/manifest-5.1
new file mode 100644
index 0000000..185aed0
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/manifest-5.1
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["3.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/another_user/manifest-5.2 b/spec/fixtures/a_repo/manifests/another_user/manifest-5.2
new file mode 100644
index 0000000..185aed0
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/manifest-5.2
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["3.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/another_user/manifest-5.3 b/spec/fixtures/a_repo/manifests/another_user/manifest-5.3
new file mode 100644
index 0000000..185aed0
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/manifest-5.3
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["3.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/manifests/another_user/manifest-5.4 b/spec/fixtures/a_repo/manifests/another_user/manifest-5.4
new file mode 100644
index 0000000..185aed0
--- /dev/null
+++ b/spec/fixtures/a_repo/manifests/another_user/manifest-5.4
@@ -0,0 +1,14 @@
+commands = {}
+modules = {}
+repository = {
+ a_rock = {
+ ["3.0-1"] = {
+ {
+ arch = "src"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/non_lua_file-1.0-1.rockspec b/spec/fixtures/a_repo/non_lua_file-1.0-1.rockspec
new file mode 100644
index 0000000..51ef42e
--- /dev/null
+++ b/spec/fixtures/a_repo/non_lua_file-1.0-1.rockspec
@@ -0,0 +1,22 @@
+-- regression test for sailorproject/sailor#138
+rockspec_format = "3.0"
+package = "non_lua_file"
+version = "1.0-1"
+source = {
+ url = "file://../upstream/non_lua_file-1.0.tar.gz"
+}
+description = {
+ summary = "An example rockspec that has a script.",
+}
+dependencies = {
+ "lua >= 5.1",
+}
+build = {
+ type = "builtin",
+ modules = {},
+ install = {
+ lua = {
+ ["sailor.blank-app.htaccess"] = "src/sailor/blank-app/.htaccess",
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/non_lua_file-1.0-1.src.rock b/spec/fixtures/a_repo/non_lua_file-1.0-1.src.rock
new file mode 100644
index 0000000..148f703
--- /dev/null
+++ b/spec/fixtures/a_repo/non_lua_file-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_repo/non_lua_file-1.0-2.rockspec b/spec/fixtures/a_repo/non_lua_file-1.0-2.rockspec
new file mode 100644
index 0000000..f9d2e2c
--- /dev/null
+++ b/spec/fixtures/a_repo/non_lua_file-1.0-2.rockspec
@@ -0,0 +1,22 @@
+-- regression test for sailorproject/sailor#138
+rockspec_format = "3.0"
+package = "non_lua_file"
+version = "1.0-2"
+source = {
+ url = "file://../upstream/non_lua_file-1.0.tar.gz"
+}
+description = {
+ summary = "An example rockspec that has a script.",
+}
+dependencies = {
+ "lua >= 5.1",
+}
+build = {
+ type = "builtin",
+ modules = {},
+ install = {
+ lua = {
+ ["sailor.blank-app.htaccess"] = "src/sailor/blank-app/.htaccess",
+ }
+ }
+}
diff --git a/spec/fixtures/a_repo/non_lua_file-1.0-2.src.rock b/spec/fixtures/a_repo/non_lua_file-1.0-2.src.rock
new file mode 100644
index 0000000..06eb9ac
--- /dev/null
+++ b/spec/fixtures/a_repo/non_lua_file-1.0-2.src.rock
Binary files differ
diff --git a/spec/fixtures/a_rock-1.0-1.rockspec b/spec/fixtures/a_rock-1.0-1.rockspec
new file mode 100644
index 0000000..9f15e87
--- /dev/null
+++ b/spec/fixtures/a_rock-1.0-1.rockspec
@@ -0,0 +1,17 @@
+package = "a_rock"
+version = "1.0-1"
+source = {
+ url = "http://localhost:8080/file/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ build = "a_rock.lua"
+ },
+}
diff --git a/spec/fixtures/a_rock-1.0-1.src.rock b/spec/fixtures/a_rock-1.0-1.src.rock
new file mode 100644
index 0000000..9d0bb45
--- /dev/null
+++ b/spec/fixtures/a_rock-1.0-1.src.rock
Binary files differ
diff --git a/spec/fixtures/a_rock.lua b/spec/fixtures/a_rock.lua
new file mode 100644
index 0000000..a564707
--- /dev/null
+++ b/spec/fixtures/a_rock.lua
@@ -0,0 +1 @@
+return {}
diff --git a/spec/fixtures/abc.bz2 b/spec/fixtures/abc.bz2
new file mode 100644
index 0000000..ee78671
--- /dev/null
+++ b/spec/fixtures/abc.bz2
Binary files differ
diff --git a/spec/fixtures/an_upstream_tarball-0.1.tar.gz b/spec/fixtures/an_upstream_tarball-0.1.tar.gz
new file mode 100644
index 0000000..518c8cb
--- /dev/null
+++ b/spec/fixtures/an_upstream_tarball-0.1.tar.gz
Binary files differ
diff --git a/spec/fixtures/bad_pack-0.1-1.rockspec b/spec/fixtures/bad_pack-0.1-1.rockspec
new file mode 100644
index 0000000..2393424
--- /dev/null
+++ b/spec/fixtures/bad_pack-0.1-1.rockspec
@@ -0,0 +1,19 @@
+rockspec_format = "3.0"
+package = "bad_pack"
+version = "0.1-1"
+source = {
+ url = "http://localhost:8080/file/busted_project-0.1.tar.gz",
+ dir = "invalid_dir",
+}
+description = {
+ summary = "A project that uses Busted tests",
+}
+build = {
+ type = "builtin",
+ modules = {
+ sum = "sum.lua",
+ }
+}
+test = {
+ type = "busted",
+}
diff --git a/spec/fixtures/build_only_deps-0.1-1.rockspec b/spec/fixtures/build_only_deps-0.1-1.rockspec
new file mode 100644
index 0000000..02d2b47
--- /dev/null
+++ b/spec/fixtures/build_only_deps-0.1-1.rockspec
@@ -0,0 +1,18 @@
+package = "build_only_deps"
+version = "0.1-1"
+source = {
+ url = "file://./a_rock.lua"
+}
+description = {
+ summary = "Fixture to test --only-deps",
+}
+dependencies = {
+ "lua >= 5.1",
+ "a_rock 1.0",
+}
+build = {
+ type = "builtin",
+ modules = {
+ dummy = "a_rock.lua",
+ }
+}
diff --git a/spec/fixtures/build_only_deps-0.1-1.src.rock b/spec/fixtures/build_only_deps-0.1-1.src.rock
new file mode 100644
index 0000000..74b2d1e
--- /dev/null
+++ b/spec/fixtures/build_only_deps-0.1-1.src.rock
Binary files differ
diff --git a/spec/fixtures/busted_project-0.1-1.rockspec b/spec/fixtures/busted_project-0.1-1.rockspec
new file mode 100644
index 0000000..54ed28a
--- /dev/null
+++ b/spec/fixtures/busted_project-0.1-1.rockspec
@@ -0,0 +1,19 @@
+rockspec_format = "3.0"
+package = "busted_project"
+version = "0.1-1"
+source = {
+ url = "http://localhost:8080/file/busted_project-0.1.tar.gz",
+ dir = "busted_project",
+}
+description = {
+ summary = "A project that uses Busted tests",
+}
+build = {
+ type = "builtin",
+ modules = {
+ sum = "sum.lua",
+ }
+}
+test = {
+ type = "busted",
+}
diff --git a/spec/fixtures/busted_project-0.1.tar.gz b/spec/fixtures/busted_project-0.1.tar.gz
new file mode 100644
index 0000000..bd4e055
--- /dev/null
+++ b/spec/fixtures/busted_project-0.1.tar.gz
Binary files differ
diff --git a/spec/fixtures/busted_project/spec/sum_spec.lua b/spec/fixtures/busted_project/spec/sum_spec.lua
new file mode 100644
index 0000000..2fa0537
--- /dev/null
+++ b/spec/fixtures/busted_project/spec/sum_spec.lua
@@ -0,0 +1,10 @@
+
+local sum = require("sum")
+
+describe("sum", function()
+
+ it("sums", function()
+ assert.equal(2, sum.sum(1, 1))
+ end)
+
+end)
diff --git a/spec/fixtures/busted_project/sum.lua b/spec/fixtures/busted_project/sum.lua
new file mode 100644
index 0000000..ba12805
--- /dev/null
+++ b/spec/fixtures/busted_project/sum.lua
@@ -0,0 +1,7 @@
+local sum = {}
+
+function sum.sum(a, b)
+ return a + b
+end
+
+return sum
diff --git a/spec/fixtures/double_deploy_type/ddt.c b/spec/fixtures/double_deploy_type/ddt.c
new file mode 100644
index 0000000..f9050a4
--- /dev/null
+++ b/spec/fixtures/double_deploy_type/ddt.c
@@ -0,0 +1,6 @@
+#include "lua.h"
+
+int luaopen_ddt(lua_State *L) {
+ lua_pushstring(L, "ddt.c");
+ return 1;
+}
diff --git a/spec/fixtures/double_deploy_type/ddt1.lua b/spec/fixtures/double_deploy_type/ddt1.lua
new file mode 100644
index 0000000..ea1dafe
--- /dev/null
+++ b/spec/fixtures/double_deploy_type/ddt1.lua
@@ -0,0 +1 @@
+return "ddt1"
diff --git a/spec/fixtures/double_deploy_type/ddt2.lua b/spec/fixtures/double_deploy_type/ddt2.lua
new file mode 100644
index 0000000..b1fa5d7
--- /dev/null
+++ b/spec/fixtures/double_deploy_type/ddt2.lua
@@ -0,0 +1 @@
+return "ddt2"
diff --git a/spec/fixtures/double_deploy_type/ddt_file b/spec/fixtures/double_deploy_type/ddt_file
new file mode 100644
index 0000000..988bbfb
--- /dev/null
+++ b/spec/fixtures/double_deploy_type/ddt_file
@@ -0,0 +1 @@
+return "ddt_file"
diff --git a/spec/fixtures/double_deploy_type/double_deploy_type-0.1.0-1.rockspec b/spec/fixtures/double_deploy_type/double_deploy_type-0.1.0-1.rockspec
new file mode 100644
index 0000000..ff13df0
--- /dev/null
+++ b/spec/fixtures/double_deploy_type/double_deploy_type-0.1.0-1.rockspec
@@ -0,0 +1,22 @@
+package = "double_deploy_type"
+version = "0.1.0-1"
+source = {
+ url = "http://example.com"
+}
+description = {
+ homepage = "http://example.com",
+ license = "*** please specify a license ***"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ ddt = "ddt/ddt.c"
+ },
+ install = {
+ lua = {
+ ddt = "ddt/ddt1.lua",
+ ddt_file = "ddt/ddt_file",
+ }
+ }
+}
diff --git a/spec/fixtures/double_deploy_type/double_deploy_type-0.2.0-1.rockspec b/spec/fixtures/double_deploy_type/double_deploy_type-0.2.0-1.rockspec
new file mode 100644
index 0000000..15f0c15
--- /dev/null
+++ b/spec/fixtures/double_deploy_type/double_deploy_type-0.2.0-1.rockspec
@@ -0,0 +1,22 @@
+package = "double_deploy_type"
+version = "0.2.0-1"
+source = {
+ url = "http://example.com"
+}
+description = {
+ homepage = "http://example.com",
+ license = "*** please specify a license ***"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ ddt = "ddt/ddt.c"
+ },
+ install = {
+ lua = {
+ ddt = "ddt/ddt2.lua",
+ ddt_file = "ddt/ddt_file",
+ }
+ }
+}
diff --git a/spec/fixtures/fixturedep.c b/spec/fixtures/fixturedep.c
new file mode 100644
index 0000000..e3fcdd5
--- /dev/null
+++ b/spec/fixtures/fixturedep.c
@@ -0,0 +1,4 @@
+
+int fixturedep_fn() {
+ return 0;
+}
diff --git a/spec/fixtures/git_repo/LICENSE b/spec/fixtures/git_repo/LICENSE
new file mode 100644
index 0000000..e8c415d
--- /dev/null
+++ b/spec/fixtures/git_repo/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2018 Test
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/spec/fixtures/git_repo/README.md b/spec/fixtures/git_repo/README.md
new file mode 100644
index 0000000..220327e
--- /dev/null
+++ b/spec/fixtures/git_repo/README.md
@@ -0,0 +1,3 @@
+
+
+Test repo
diff --git a/spec/fixtures/gpg/private-keys-v1.d/5D2D3F97B88B18604D819EA9DF5B730C75D71B60.key b/spec/fixtures/gpg/private-keys-v1.d/5D2D3F97B88B18604D819EA9DF5B730C75D71B60.key
new file mode 100644
index 0000000..26240f5
--- /dev/null
+++ b/spec/fixtures/gpg/private-keys-v1.d/5D2D3F97B88B18604D819EA9DF5B730C75D71B60.key
Binary files differ
diff --git a/spec/fixtures/gpg/private-keys-v1.d/B71C36B4EDEB72A047FED1C01BCFF4D08837E3B1.key b/spec/fixtures/gpg/private-keys-v1.d/B71C36B4EDEB72A047FED1C01BCFF4D08837E3B1.key
new file mode 100644
index 0000000..e75a2eb
--- /dev/null
+++ b/spec/fixtures/gpg/private-keys-v1.d/B71C36B4EDEB72A047FED1C01BCFF4D08837E3B1.key
Binary files differ
diff --git a/spec/fixtures/gpg/pubring.kbx b/spec/fixtures/gpg/pubring.kbx
new file mode 100644
index 0000000..fc63cbc
--- /dev/null
+++ b/spec/fixtures/gpg/pubring.kbx
Binary files differ
diff --git a/spec/fixtures/gpg/trustdb.gpg b/spec/fixtures/gpg/trustdb.gpg
new file mode 100644
index 0000000..cabca66
--- /dev/null
+++ b/spec/fixtures/gpg/trustdb.gpg
Binary files differ
diff --git a/spec/fixtures/invalid_patch-0.1-1.rockspec b/spec/fixtures/invalid_patch-0.1-1.rockspec
new file mode 100644
index 0000000..c2ecd16
--- /dev/null
+++ b/spec/fixtures/invalid_patch-0.1-1.rockspec
@@ -0,0 +1,29 @@
+package = "invalid_patch"
+version = "0.1-1"
+source = {
+ -- any valid URL
+ url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua"
+}
+description = {
+ summary = "A rockspec with an invalid patch",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ build = "build.lua"
+ },
+ patches = {
+ ["I_am_an_invalid_patch.patch"] =
+[[
+diff -Naur luadoc-3.0.1/src/luadoc/doclet/html.lua luadoc-3.0.1-new/src/luadoc/doclet/html.lua
+--- luadoc-3.0.1/src/luadoc/doclet/html.lua2007-12-21 15:50:48.000000000 -0200
++++ luadoc-3.0.1-new/src/luadoc/doclet/html.lua2008-02-28 01:59:53.000000000 -0300
+@@ -18,6 +18,7 @@
+- gabba gabba gabba
++ gobo gobo gobo
+]]
+ }
+}
diff --git a/spec/fixtures/invalid_say-1.3-1.rockspec b/spec/fixtures/invalid_say-1.3-1.rockspec
new file mode 100644
index 0000000..890b4db
--- /dev/null
+++ b/spec/fixtures/invalid_say-1.3-1.rockspec
@@ -0,0 +1,23 @@
+package = "say"
+version = "1.3-1"
+source = {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{++{
+ url = "https://github.com/Olivine-Labs/say/archive/v1.3-1.tar.gz",
+ dir = "say-1.3-1"
+}
+description = {
+ summary = "Lua String Hashing/Indexing Library",
+ detailed = [[
+ Useful for internationalization.
+ ]],
+ homepage = "http://olivinelabs.com/busted/",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ ["say.init"] = "src/init.lua"
+ }
+}
diff --git a/spec/fixtures/legacyexternalcommand-0.1-1.rockspec b/spec/fixtures/legacyexternalcommand-0.1-1.rockspec
new file mode 100644
index 0000000..47bcbb0
--- /dev/null
+++ b/spec/fixtures/legacyexternalcommand-0.1-1.rockspec
@@ -0,0 +1,17 @@
+package = "legacyexternalcommand"
+version = "0.1-1"
+source = {
+ url = "http://localhost:8080/file/legacyexternalcommand.lua"
+}
+description = {
+ summary = "an external command with legacy arg parsing",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ ["luarocks.cmd.external.legacyexternalcommand"] = "legacyexternalcommand.lua",
+ }
+}
diff --git a/spec/fixtures/legacyexternalcommand.lua b/spec/fixtures/legacyexternalcommand.lua
new file mode 100644
index 0000000..af57537
--- /dev/null
+++ b/spec/fixtures/legacyexternalcommand.lua
@@ -0,0 +1,34 @@
+
+--- Module implementing an external command with legacy arg parsing.
+local legacyexternalcommand = {}
+
+local util = require("luarocks.util")
+
+legacyexternalcommand.help_summary = "generate legacyexternalcommand package files of a rock."
+legacyexternalcommand.help_arguments = "arg1 [arg2]"
+legacyexternalcommand.help = [[
+This addon generates legacyexternalcommand package files of a rock.
+First argument is the name of a rock, the second argument is optional
+and needed when legacyexternalcommand uses another name (usually prefixed by lua-).
+Files are generated with the source content of the rock and more
+especially the rockspec. So, the rock is downloaded and unpacked.
+]]
+
+--- Driver function for the "legacyexternalcommand" command.
+-- @param arg1 string: arg1.
+-- @param arg2 string: arg2 (optional)
+-- @return boolean: true if successful
+function legacyexternalcommand.command(flags, arg1, arg2)
+ if type(arg1) ~= 'string' then
+ return nil, "Argument missing. "..util.see_help('legacyexternalcommand')
+ end
+
+ for k,v in pairs(flags) do
+ print("FLAGS", k,v)
+ end
+ print("ARG1", tostring(arg1))
+ print("ARG2", tostring(arg2))
+ return true
+end
+
+return legacyexternalcommand
diff --git a/spec/fixtures/luajit-fail-1.0-1.rockspec b/spec/fixtures/luajit-fail-1.0-1.rockspec
new file mode 100644
index 0000000..f820460
--- /dev/null
+++ b/spec/fixtures/luajit-fail-1.0-1.rockspec
@@ -0,0 +1,22 @@
+package = "luajit-fail"
+version = "1.0-1"
+source = {
+ url = "https://raw.githubusercontent.com/keplerproject/luarocks/master/test/testing.lua",
+}
+description = {
+ summary = "Test luajit dependency fail",
+ detailed = [[
+Fail luajit dependency when running with rockspec_format < 3.0.
+]],
+ homepage = "http://luarocks.org/",
+ license = "MIT/X license"
+}
+dependencies = {
+ "luajit >= 2.0"
+}
+build = {
+ type = "builtin",
+ modules = {
+ testing = "testing.lua"
+ }
+}
diff --git a/spec/fixtures/luajit-success-1.0-1.rockspec b/spec/fixtures/luajit-success-1.0-1.rockspec
new file mode 100644
index 0000000..31c930c
--- /dev/null
+++ b/spec/fixtures/luajit-success-1.0-1.rockspec
@@ -0,0 +1,23 @@
+rockspec_format = "3.0"
+package = "luajit-success"
+version = "1.0-1"
+source = {
+ url = "https://raw.githubusercontent.com/keplerproject/luarocks/master/test/testing.lua",
+}
+description = {
+ summary = "Test luajit dependency fail",
+ detailed = [[
+Use luajit dependency when running with rockspec_format >= 3.0.
+]],
+ homepage = "http://luarocks.org/",
+ license = "MIT/X license"
+}
+dependencies = {
+ "luajit >= 2.0"
+}
+build = {
+ type = "builtin",
+ modules = {
+ testing = "testing.lua"
+ }
+}
diff --git a/spec/fixtures/mixed_deploy_type/mdt.c b/spec/fixtures/mixed_deploy_type/mdt.c
new file mode 100644
index 0000000..a162ce2
--- /dev/null
+++ b/spec/fixtures/mixed_deploy_type/mdt.c
@@ -0,0 +1,6 @@
+#include "lua.h"
+
+int luaopen_mdt(lua_State *L) {
+ lua_pushstring(L, "mdt.c");
+ return 1;
+}
diff --git a/spec/fixtures/mixed_deploy_type/mdt.lua b/spec/fixtures/mixed_deploy_type/mdt.lua
new file mode 100644
index 0000000..c9ca9c6
--- /dev/null
+++ b/spec/fixtures/mixed_deploy_type/mdt.lua
@@ -0,0 +1 @@
+return "mdt.lua"
diff --git a/spec/fixtures/mixed_deploy_type/mdt_file b/spec/fixtures/mixed_deploy_type/mdt_file
new file mode 100644
index 0000000..1a15f7d
--- /dev/null
+++ b/spec/fixtures/mixed_deploy_type/mdt_file
@@ -0,0 +1 @@
+return "mdt_file"
diff --git a/spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.1.0-1.rockspec b/spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.1.0-1.rockspec
new file mode 100644
index 0000000..91b725d
--- /dev/null
+++ b/spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.1.0-1.rockspec
@@ -0,0 +1,21 @@
+package = "mixed_deploy_type"
+version = "0.1.0-1"
+source = {
+ url = "http://example.com"
+}
+description = {
+ homepage = "http://example.com",
+ license = "*** please specify a license ***"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ mdt = "mdt/mdt.lua"
+ },
+ install = {
+ lua = {
+ mdt_file = "mdt/mdt_file"
+ }
+ }
+}
diff --git a/spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.2.0-1.rockspec b/spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.2.0-1.rockspec
new file mode 100644
index 0000000..9ca0318
--- /dev/null
+++ b/spec/fixtures/mixed_deploy_type/mixed_deploy_type-0.2.0-1.rockspec
@@ -0,0 +1,21 @@
+package = "mixed_deploy_type"
+version = "0.2.0-1"
+source = {
+ url = "http://example.com"
+}
+description = {
+ homepage = "http://example.com",
+ license = "*** please specify a license ***"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ mdt = "mdt/mdt.c"
+ },
+ install = {
+ lib = {
+ mdt_file = "mdt/mdt_file"
+ }
+ }
+}
diff --git a/spec/fixtures/patch_create_delete-0.1-1.rockspec b/spec/fixtures/patch_create_delete-0.1-1.rockspec
new file mode 100644
index 0000000..3d55da5
--- /dev/null
+++ b/spec/fixtures/patch_create_delete-0.1-1.rockspec
@@ -0,0 +1,34 @@
+rockspec_format = "3.0"
+package = "patch_create_delete"
+version = "0.1-1"
+source = {
+ -- any valid URL
+ url = "git://github.com/luarocks/luarocks"
+}
+description = {
+ summary = "A rockspec with a patch that creates and deletes files",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ ["luarocks.loader"] = "src/luarocks/loader.lua"
+ },
+ patches = {
+ ["create_delete.patch"] =
+[[
+diff -Naur luarocks/spec/fixtures/patch_create_delete/a_file.txt luarocks-patch/spec/fixtures/patch_create_delete/a_file.txt
+--- luarocks/spec/fixtures/patch_create_delete/a_file.txt 2017-10-04 15:39:44.179306674 -0300
++++ luarocks-patch/spec/fixtures/patch_create_delete/a_file.txt 1969-12-31 21:00:00.000000000 -0300
+@@ -1 +0,0 @@
+-I am a file.
+diff -Naur luarocks/spec/fixtures/patch_create_delete/another_file.txt luarocks-patch/spec/fixtures/patch_create_delete/another_file.txt
+--- luarocks/spec/fixtures/patch_create_delete/another_file.txt 1969-12-31 21:00:00.000000000 -0300
++++ luarocks-patch/spec/fixtures/patch_create_delete/another_file.txt 2017-10-04 15:40:12.836306564 -0300
+@@ -0,0 +1 @@
++I am another file.
+]]
+ }
+}
diff --git a/spec/fixtures/patch_create_delete/a_file.txt b/spec/fixtures/patch_create_delete/a_file.txt
new file mode 100644
index 0000000..6539c24
--- /dev/null
+++ b/spec/fixtures/patch_create_delete/a_file.txt
@@ -0,0 +1 @@
+I am a file.
diff --git a/spec/fixtures/renamed_upstream_tarball-0.1.tar.gz b/spec/fixtures/renamed_upstream_tarball-0.1.tar.gz
new file mode 100644
index 0000000..518c8cb
--- /dev/null
+++ b/spec/fixtures/renamed_upstream_tarball-0.1.tar.gz
Binary files differ
diff --git a/spec/fixtures/with_external_dep-0.1-1.rockspec b/spec/fixtures/with_external_dep-0.1-1.rockspec
new file mode 100644
index 0000000..45fea4b
--- /dev/null
+++ b/spec/fixtures/with_external_dep-0.1-1.rockspec
@@ -0,0 +1,25 @@
+package = "with_external_dep"
+version = "0.1-1"
+source = {
+ url = "http://localhost:8080/file/with_external_dep.c"
+}
+description = {
+ summary = "An example rockspec",
+}
+external_dependencies = {
+ FOO = {
+ header = "foo/foo.h"
+ }
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ with_external_dep = {
+ sources = "with_external_dep.c",
+ incdirs = "$(FOO_INCDIR)",
+ }
+ }
+}
diff --git a/spec/fixtures/with_external_dep.c b/spec/fixtures/with_external_dep.c
new file mode 100644
index 0000000..16435d8
--- /dev/null
+++ b/spec/fixtures/with_external_dep.c
@@ -0,0 +1,10 @@
+#include <foo/foo.h>
+#include <lua.h>
+#include <lauxlib.h>
+
+int luaopen_with_external_dep(lua_State* L) {
+ lua_newtable(L);
+ lua_pushinteger(L, FOO);
+ lua_setfield(L, -2, "foo");
+ return 1;
+}
diff --git a/spec/fixtures/with_external_dep/foo/foo.h b/spec/fixtures/with_external_dep/foo/foo.h
new file mode 100644
index 0000000..eedd558
--- /dev/null
+++ b/spec/fixtures/with_external_dep/foo/foo.h
@@ -0,0 +1 @@
+#define FOO 42
diff --git a/spec/fs_spec.lua b/spec/fs_spec.lua
new file mode 100644
index 0000000..d5e93c4
--- /dev/null
+++ b/spec/fs_spec.lua
@@ -0,0 +1,76 @@
+local test_env = require("spec.util.test_env")
+
+local lfs = require("lfs")
+local testing_paths = test_env.testing_paths
+local get_tmp_path = test_env.get_tmp_path
+
+describe("luarocks.fs #integration", function()
+
+ local fs
+
+ describe("fs.download #mock", function()
+ local tmpfile
+ local tmpdir
+
+ lazy_setup(function()
+ test_env.setup_specs(nil, "mock")
+ local cfg = require("luarocks.core.cfg")
+ fs = require("luarocks.fs")
+ cfg.init()
+ fs.init()
+ test_env.mock_server_init()
+ end)
+
+ lazy_teardown(function()
+ test_env.mock_server_done()
+ end)
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true and fetches the url argument into the specified filename", function()
+ tmpfile = get_tmp_path()
+ assert.truthy(fs.download("http://localhost:8080/file/a_rock.lua", tmpfile))
+ local fd = assert(io.open(tmpfile, "r"))
+ local downloadcontent = assert(fd:read("*a"))
+ fd:close()
+ fd = assert(io.open(testing_paths.fixtures_dir .. "/a_rock.lua", "r"))
+ local originalcontent = assert(fd:read("*a"))
+ fd:close()
+ assert.same(downloadcontent, originalcontent)
+ end)
+
+ it("returns true and fetches the url argument into a file whose name matches the basename of the url if the filename argument is not given", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ fs.change_dir(tmpdir)
+ assert.truthy(fs.download("http://localhost:8080/file/a_rock.lua"))
+ tmpfile = tmpdir .. "/a_rock.lua"
+ local fd = assert(io.open(tmpfile, "r"))
+ local downloadcontent = assert(fd:read("*a"))
+ fd:close()
+ fd = assert(io.open(testing_paths.fixtures_dir .. "/a_rock.lua", "r"))
+ local originalcontent = assert(fd:read("*a"))
+ fd:close()
+ assert.same(downloadcontent, originalcontent)
+ fs.pop_dir()
+ end)
+
+ it("returns false and does nothing if the url argument contains a nonexistent file", function()
+ tmpfile = get_tmp_path()
+ assert.falsy(fs.download("http://localhost:8080/file/nonexistent", tmpfile))
+ end)
+
+ it("returns false and does nothing if the url argument is invalid", function()
+ assert.falsy(fs.download("invalidurl"))
+ end)
+ end)
+end)
diff --git a/spec/help_spec.lua b/spec/help_spec.lua
new file mode 100644
index 0000000..e13f1c3
--- /dev/null
+++ b/spec/help_spec.lua
@@ -0,0 +1,25 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+
+describe("luarocks help #integration", function()
+
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ it("with no flags/arguments", function()
+ assert.is_true(run.luarocks_bool("help"))
+ end)
+
+ it("invalid argument", function()
+ assert.is_false(run.luarocks_bool("help invalid"))
+ end)
+
+ it("config", function()
+ assert.is_true(run.luarocks_bool("help config"))
+ end)
+
+ it("luarocks-admin help with no flags/arguments", function()
+ assert.is_true(run.luarocks_admin_bool(test_env.quiet("help")))
+ end)
+end)
diff --git a/spec/init_spec.lua b/spec/init_spec.lua
new file mode 100644
index 0000000..88bd23a
--- /dev/null
+++ b/spec/init_spec.lua
@@ -0,0 +1,235 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local copy_dir = test_env.copy_dir
+local is_win = test_env.TEST_TARGET_OS == "windows"
+local write_file = test_env.write_file
+local lfs = require("lfs")
+
+describe("luarocks init #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs()
+ end)
+
+ it("with no arguments", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ if is_win then
+ assert.truthy(lfs.attributes(myproject .. "/lua.bat"))
+ assert.truthy(lfs.attributes(myproject .. "/luarocks.bat"))
+ else
+ assert.truthy(lfs.attributes(myproject .. "/lua"))
+ assert.truthy(lfs.attributes(myproject .. "/luarocks"))
+ end
+ assert.truthy(lfs.attributes(myproject .. "/lua_modules"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks/config-" .. test_env.lua_version .. ".lua"))
+ assert.truthy(lfs.attributes(myproject .. "/.gitignore"))
+ assert.truthy(lfs.attributes(myproject .. "/myproject-dev-1.rockspec"))
+ end, finally)
+ end)
+
+ it("with --no-gitignore", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init --no-gitignore"))
+ if is_win then
+ assert.truthy(lfs.attributes(myproject .. "/lua.bat"))
+ assert.truthy(lfs.attributes(myproject .. "/luarocks.bat"))
+ else
+ assert.truthy(lfs.attributes(myproject .. "/lua"))
+ assert.truthy(lfs.attributes(myproject .. "/luarocks"))
+ end
+ assert.truthy(lfs.attributes(myproject .. "/lua_modules"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks/config-" .. test_env.lua_version .. ".lua"))
+ assert.falsy(lfs.attributes(myproject .. "/.gitignore"))
+ assert.truthy(lfs.attributes(myproject .. "/myproject-dev-1.rockspec"))
+ end, finally)
+ end)
+
+ it("with --no-wrapper-scripts", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init --no-wrapper-scripts"))
+ assert.falsy(lfs.attributes(myproject .. "/lua.bat"))
+ assert.falsy(lfs.attributes(myproject .. "/luarocks.bat"))
+ assert.falsy(lfs.attributes(myproject .. "/lua"))
+ assert.falsy(lfs.attributes(myproject .. "/luarocks"))
+ assert.truthy(lfs.attributes(myproject .. "/lua_modules"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks/config-" .. test_env.lua_version .. ".lua"))
+ assert.truthy(lfs.attributes(myproject .. "/.gitignore"))
+ assert.truthy(lfs.attributes(myproject .. "/myproject-dev-1.rockspec"))
+ end, finally)
+ end)
+
+ it("with --wrapper-dir", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init --wrapper-dir=./bin"))
+ if is_win then
+ assert.truthy(lfs.attributes(myproject .. "/bin/lua.bat"))
+ assert.truthy(lfs.attributes(myproject .. "/bin/luarocks.bat"))
+ else
+ assert.truthy(lfs.attributes(myproject .. "/bin/lua"))
+ assert.truthy(lfs.attributes(myproject .. "/bin/luarocks"))
+ end
+ assert.truthy(lfs.attributes(myproject .. "/lua_modules"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks/config-" .. test_env.lua_version .. ".lua"))
+ assert.truthy(lfs.attributes(myproject .. "/.gitignore"))
+ assert.truthy(lfs.attributes(myproject .. "/myproject-dev-1.rockspec"))
+ end, finally)
+ end)
+
+ it("lua wrapper works", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ if is_win then
+ assert.truthy(lfs.attributes(myproject .. "/lua.bat"))
+ assert.truthy(lfs.attributes(myproject .. "/luarocks.bat"))
+ local pd = assert(io.popen([[echo print(_VERSION) | lua.bat]], "r"))
+ local output = pd:read("*a")
+ pd:close()
+ assert.match("5", output, 1, true)
+ local fd = io.open("hello.lua", "w")
+ fd:write("print('hello' .. _VERSION)")
+ fd:close()
+ pd = assert(io.popen([[lua.bat hello.lua]], "r"))
+ output = pd:read("*a")
+ pd:close()
+ assert.match("hello", output, 1, true)
+ else
+ assert.truthy(lfs.attributes(myproject .. "/lua"))
+ assert.truthy(lfs.attributes(myproject .. "/luarocks"))
+ local pd = assert(io.popen([[echo "print('hello ' .. _VERSION)" | ./lua]], "r"))
+ local output = pd:read("*a")
+ pd:close()
+ assert.match("hello", output, 1, true)
+ local fd = io.open("hello.lua", "w")
+ fd:write("print('hello' .. _VERSION)")
+ fd:close()
+ pd = assert(io.popen([[./lua ./hello.lua]], "r"))
+ output = pd:read("*a")
+ pd:close()
+ assert.match("hello", output, 1, true)
+ end
+ end, finally)
+ end)
+
+ it("with given arguments", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init customname 1.0"))
+ assert.truthy(lfs.attributes(myproject .. "/customname-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("with --lua-versions", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init --lua-versions=5.1,5.2,5.3,5.4"))
+ local rockspec_name = myproject .. "/myproject-dev-1.rockspec"
+ assert.truthy(lfs.attributes(rockspec_name))
+ local fd = assert(io.open(rockspec_name, "rb"))
+ local data = fd:read("*a")
+ fd:close()
+ assert.truthy(data:find("lua >= 5.1, < 5.5", 1, true))
+ end, finally)
+ end)
+
+ it("in a git repo", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ copy_dir(testing_paths.fixtures_dir .. "/git_repo", myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ local fd = assert(io.open(myproject .. "/myproject-dev-1.rockspec", "r"))
+ local content = assert(fd:read("*a"))
+ assert.truthy(content:find("summary = \"Test repo\""))
+ assert.truthy(content:find("detailed = .+Test repo.+"))
+ assert.truthy(content:find("license = \"MIT\""))
+
+ fd = assert(io.open(myproject .. "/.gitignore", "r"))
+ content = assert(fd:read("*a"))
+ assert.truthy(content:find("/foo"))
+ assert.truthy(content:find("/lua"))
+ assert.truthy(content:find("/lua_modules"))
+ end, finally)
+ end)
+
+ it("does not autodetect config or dependencies as modules of the package", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local myproject = tmpdir .. "/myproject"
+ lfs.mkdir(myproject)
+ lfs.chdir(myproject)
+
+ assert(run.luarocks("init"))
+ assert.truthy(lfs.attributes(myproject .. "/.luarocks/config-" .. test_env.lua_version .. ".lua"))
+ local rockspec_filename = myproject .. "/myproject-dev-1.rockspec"
+ assert.truthy(lfs.attributes(rockspec_filename))
+
+ -- install a package locally
+ write_file("my_dependency-1.0-1.rockspec", [[
+ package = "my_dependency"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/my_dependency.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ my_dependency = "my_dependency.lua"
+ }
+ }
+ ]], finally)
+ write_file(tmpdir .. "/my_dependency.lua", "return {}", finally)
+
+ assert.truthy(run.luarocks("build my_dependency-1.0-1.rockspec"))
+ assert.truthy(lfs.attributes(myproject .. "/lua_modules/share/lua/" .. test_env.lua_version .."/my_dependency.lua"))
+
+ os.remove(rockspec_filename)
+ os.remove("my_dependency-1.0-1.rockspec")
+
+ -- re-run init
+ assert(run.luarocks("init"))
+
+ -- file is recreated
+ assert.truthy(lfs.attributes(rockspec_filename))
+
+ local fd = assert(io.open(rockspec_filename, "rb"))
+ local rockspec = assert(fd:read("*a"))
+ fd:close()
+
+ assert.no.match("my_dependency", rockspec, 1, true)
+ assert.no.match("config", rockspec, 1, true)
+
+ end, finally)
+ end)
+end)
diff --git a/spec/install_spec.lua b/spec/install_spec.lua
new file mode 100644
index 0000000..e6b1ad0
--- /dev/null
+++ b/spec/install_spec.lua
@@ -0,0 +1,235 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local env_variables = test_env.env_variables
+local write_file = test_env.write_file
+local git_repo = require("spec.util.git_repo")
+local V = test_env.V
+
+local extra_rocks = {
+ "/cprint-${CPRINT}.src.rock",
+ "/lpeg-${LPEG}.src.rock",
+ "/luassert-1.7.0-1.src.rock",
+ "/luasocket-${LUASOCKET}.src.rock",
+ "/lxsh-${LXSH}.src.rock",
+ "/luafilesystem-${LUAFILESYSTEM}.src.rock",
+ "/luafilesystem-${LUAFILESYSTEM_OLD}.src.rock",
+ "spec/fixtures/a_repo/has_build_dep-1.0-1.all.rock",
+ "spec/fixtures/a_repo/a_build_dep-1.0-1.all.rock",
+ "spec/fixtures/a_repo/a_rock-1.0-1.src.rock",
+}
+
+describe("luarocks install #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ describe("basic tests", function()
+ pending("fails with local flag as root #unix", function()
+ if test_env.TYPE_TEST_ENV ~= "full" then
+ assert.is_false(run.luarocks_bool("install --local luasocket ", { USER = "root" } ))
+ end
+ end)
+
+ pending("fails with no downloader", function()
+ if test_env.TYPE_TEST_ENV ~= "full" then
+ local output = assert(run.luarocks("install https://example.com/rock-1.0.src.rock", { LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/testing_config_no_downloader.lua" } ))
+ assert.match("no downloader tool", output)
+
+ -- can do http but not https
+ assert(run.luarocks("install luasocket"))
+ output = assert(run.luarocks("install https://example.com/rock-1.0.src.rock", { LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/testing_config_no_downloader.lua" } ))
+ assert.match("no downloader tool", output)
+ end
+ end)
+
+ it("only-deps of lxsh show there is no lxsh", function()
+ assert.is_true(run.luarocks_bool("install lxsh ${LXSH} --only-deps"))
+ assert.is_false(run.luarocks_bool("show lxsh"))
+ end)
+
+ it("installs a package with a dependency", function()
+ assert.is_true(run.luarocks_bool("install has_build_dep"))
+ assert.is_true(run.luarocks_bool("show a_rock"))
+ end)
+ end)
+
+ describe("#namespaces", function()
+ it("installs a namespaced package from the command-line", function()
+ assert(run.luarocks_bool("install a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.is_false(run.luarocks_bool("show a_rock 1.0"))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ end)
+
+ it("installs a namespaced package given an URL and any string in --namespace", function()
+ -- This is not a "valid" namespace (as per luarocks.org rules)
+ -- but we're not doing any format checking in the luarocks codebase
+ -- so this keeps our options open.
+ assert(run.luarocks_bool("install --namespace=x.y@z file://" .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.src.rock" ))
+ assert.truthy(run.luarocks_bool("show a_rock 1.0"))
+ local fd = assert(io.open(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/rock_namespace", "r"))
+ finally(function() fd:close() end)
+ assert.same("x.y@z", fd:read("*l"))
+ end)
+
+ it("installs a package with a namespaced dependency", function()
+ assert(run.luarocks_bool("install has_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show has_namespaced_dep"))
+ assert.is_false(run.luarocks_bool("show a_rock 1.0"))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ end)
+
+ it("installs a package reusing a namespaced dependency", function()
+ assert(run.luarocks_bool("install a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ local output = run.luarocks("install has_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" )
+ assert.has.no.match("Missing dependencies", output)
+ end)
+
+ it("installs a package considering namespace of locally installed package", function()
+ assert(run.luarocks_bool("install a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("show a_rock 2.0"))
+ assert(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/2.0-1/rock_namespace"))
+ local output = run.luarocks("install has_another_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" )
+ assert.has.match("Missing dependencies", output)
+ print(output)
+ assert(run.luarocks_bool("show a_rock 3.0"))
+ end)
+ end)
+
+ describe("more complex tests", function()
+ it('skipping dependency checks', function()
+ assert.is_true(run.luarocks_bool("install has_build_dep --nodeps"))
+ assert.is_true(run.luarocks_bool("show has_build_dep"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/has_build_dep"))
+ end)
+
+ it('handle relative path in --tree #632', function()
+ local relative_path = "./temp_dir_"..math.random(100000)
+ if test_env.TEST_TARGET_OS == "windows" then
+ relative_path = relative_path:gsub("/", "\\")
+ end
+ test_env.remove_dir(relative_path)
+ assert.is.falsy(lfs.attributes(relative_path))
+ assert.is_true(run.luarocks_bool("install luafilesystem --tree="..relative_path))
+ assert.is.truthy(lfs.attributes(relative_path))
+ test_env.remove_dir(relative_path)
+ assert.is.falsy(lfs.attributes(relative_path))
+ end)
+
+ it("only-deps of luasocket packed rock", function()
+ assert.is_true(run.luarocks_bool("build --pack-binary-rock luasocket ${LUASOCKET}"))
+ local output = run.luarocks("install --only-deps " .. "luasocket-${LUASOCKET}." .. test_env.platform .. ".rock")
+ assert.match(V"Successfully installed dependencies for luasocket ${LUASOCKET}", output, 1, true)
+ assert.is_true(os.remove("luasocket-${LUASOCKET}." .. test_env.platform .. ".rock"))
+ end)
+
+ it("reinstall", function()
+ assert.is_true(run.luarocks_bool("build --pack-binary-rock luasocket ${LUASOCKET}"))
+ assert.is_true(run.luarocks_bool("install " .. "luasocket-${LUASOCKET}." .. test_env.platform .. ".rock"))
+ assert.is_true(run.luarocks_bool("install --deps-mode=none " .. "luasocket-${LUASOCKET}." .. test_env.platform .. ".rock"))
+ assert.is_true(os.remove("luasocket-${LUASOCKET}." .. test_env.platform .. ".rock"))
+ end)
+
+ it("binary rock of cprint", function()
+ assert.is_true(run.luarocks_bool("build --pack-binary-rock cprint"))
+ assert.is_true(run.luarocks_bool("install cprint-${CPRINT}." .. test_env.platform .. ".rock"))
+ assert.is_true(os.remove("cprint-${CPRINT}." .. test_env.platform .. ".rock"))
+ end)
+
+ it("accepts --no-manifest flag", function()
+ assert.is_true(run.luarocks_bool("install lxsh ${LXSH}"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/manifest"))
+ assert.is.truthy(os.remove(testing_paths.testing_sys_rocks .. "/manifest"))
+
+ assert.is_true(run.luarocks_bool("install --no-manifest lxsh ${LXSH}"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/manifest"))
+ end)
+ end)
+
+ describe("#build_dependencies", function()
+ it("install does not install a build dependency", function()
+ assert(run.luarocks_bool("install has_build_dep"))
+ assert(run.luarocks_bool("show has_build_dep 1.0"))
+ assert.falsy(run.luarocks_bool("show a_build_dep 1.0"))
+ end)
+ end)
+
+ it("respects luarocks.lock in package #pinning", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock >= 0.8"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+ write_file("luarocks.lock", [[
+ return {
+ dependencies = {
+ ["a_rock"] = "1.0-1",
+ }
+ }
+ ]])
+
+ assert.is_true(run.luarocks_bool("make --pack-binary-rock --server=" .. testing_paths.fixtures_dir .. "/a_repo test-1.0-1.rockspec"))
+ assert.is_true(os.remove("luarocks.lock"))
+
+ assert.is.truthy(lfs.attributes("./test-1.0-1.all.rock"))
+
+ assert.is.falsy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/1.0-1/test-1.0-1.rockspec"))
+ assert.is.falsy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+
+ print(run.luarocks("install ./test-1.0-1.all.rock --tree=lua_modules --server=" .. testing_paths.fixtures_dir .. "/a_repo"))
+
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/1.0-1/test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/1.0-1/luarocks.lock"))
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ assert.is.falsy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/a_rock/2.0-1"))
+ end, finally)
+ end)
+
+ describe("#unix install runs build from #git", function()
+ local git
+
+ lazy_setup(function()
+ git = git_repo.start()
+ end)
+
+ lazy_teardown(function()
+ if git then
+ git:stop()
+ end
+ end)
+
+ it("using --branch", function()
+ write_file("my_branch-1.0-1.rockspec", [[
+ rockspec_format = "3.0"
+ package = "my_branch"
+ version = "1.0-1"
+ source = {
+ url = "git://localhost/testrock"
+ }
+ ]], finally)
+ assert.is_false(run.luarocks_bool("install --branch unknown-branch ./my_branch-1.0-1.rockspec"))
+ assert.is_true(run.luarocks_bool("install --branch test-branch ./my_branch-1.0-1.rockspec"))
+ end)
+ end)
+
+end)
diff --git a/spec/lint_spec.lua b/spec/lint_spec.lua
new file mode 100644
index 0000000..919e4e7
--- /dev/null
+++ b/spec/lint_spec.lua
@@ -0,0 +1,109 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local get_tmp_path = test_env.get_tmp_path
+local write_file = test_env.write_file
+local lfs = require("lfs")
+
+local extra_rocks = {
+ "/say-1.3-1.rockspec"
+}
+
+describe("luarocks lint #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("lint"))
+ end)
+
+ it("invalid argument", function()
+ assert.is_false(run.luarocks_bool("lint invalid"))
+ end)
+
+ it("OK", function()
+ assert.is_true(run.luarocks_bool("download --rockspec say 1.3-1"))
+ local output = run.luarocks("lint say-1.3-1.rockspec")
+ assert.are.same(output, "")
+ assert.is_true(os.remove("say-1.3-1.rockspec"))
+ end)
+
+ describe("mismatch set", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ tmpdir = get_tmp_path()
+ olddir = lfs.currentdir()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+ end)
+
+ after_each(function()
+ if olddir then
+ lfs.chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("mismatch string", function()
+ write_file("type_mismatch_string-1.0-1.rockspec", [[
+ package="type_mismatch_version"
+ version=1.0
+ ]], finally)
+ assert.is_false(run.luarocks_bool("lint type_mismatch_string-1.0-1.rockspec"))
+ end)
+
+ it("mismatch version", function()
+ write_file("type_mismatch_version-1.0-1.rockspec", [[
+ package="type_mismatch_version"
+ version="1.0"
+ ]], finally)
+ assert.is_false(run.luarocks_bool("lint type_mismatch_version-1.0-1.rockspec"))
+ end)
+
+ it("mismatch table", function()
+ write_file("type_mismatch_table-1.0-1.rockspec", [[
+ package="type_mismatch_table"
+ version="1.0-1"
+
+ source = "not a table"
+ ]], finally)
+ assert.is_false(run.luarocks_bool("lint type_mismatch_table-1.0-1.rockspec"))
+ end)
+
+ it("mismatch no build table", function()
+ write_file("no_build_table-1.0-1.rockspec", [[
+ package = "no_build_table"
+ version = "0.1-1"
+ source = {
+ url = "http://example.com/foo/tar.gz"
+ }
+ description = {
+ summary = "A rockspec with no build field",
+ }
+ dependencies = {
+ "lua >= 5.1"
+ }
+ ]], finally)
+ assert.is_false(run.luarocks_bool("lint no_build_table-1.0-1.rockspec"))
+ end)
+
+ it("no description field", function()
+ write_file("nodesc-1.0-1.rockspec", [[
+ package = "nodesc"
+ version = "0.1-1"
+ source = {
+ url = "http://example.com/foo/tar.gz"
+ }
+ dependencies = {
+ "lua >= 5.1"
+ }
+ ]], finally)
+ assert.is_false(run.luarocks_bool("lint nodesc-1.0-1.rockspec"))
+ end)
+ end)
+end)
diff --git a/spec/list_spec.lua b/spec/list_spec.lua
new file mode 100644
index 0000000..08d8587
--- /dev/null
+++ b/spec/list_spec.lua
@@ -0,0 +1,34 @@
+local test_env = require("spec.util.test_env")
+local V = test_env.V
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+local extra_rocks = {
+ "/say-1.0-1.src.rock",
+ "/say-1.2-1.src.rock"
+}
+
+describe("luarocks list #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("with no flags/arguments", function()
+ local output = run.luarocks("list")
+ assert.match("luacov", output)
+ end)
+
+ it("shows version number", function()
+ local output = run.luarocks("list")
+ assert.is.truthy(output:find("luacov"))
+ assert.matches(V"${LUACOV}", output, 1, true)
+ end)
+
+ it("LuaRocks install outdated and list it", function()
+ assert.is_true(run.luarocks_bool("install say 1.0-1"))
+ local output = run.luarocks("list --outdated")
+ assert.is.truthy(output:find("say"))
+ assert.matches("1.0-1 < ", output, 1, true)
+ end)
+end)
diff --git a/spec/loader_spec.lua b/spec/loader_spec.lua
new file mode 100644
index 0000000..bd95a29
--- /dev/null
+++ b/spec/loader_spec.lua
@@ -0,0 +1,73 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+
+describe("luarocks.loader", function()
+
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ describe("#integration", function()
+ it("respects version constraints", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("rock_b_01.lua", "print('ROCK B 0.1'); return {}")
+ write_file("rock_b-0.1-1.rockspec", [[
+ package = "rock_b"
+ version = "0.1-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/rock_b_01.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ rock_b = "rock_b_01.lua"
+ }
+ }
+ ]])
+
+ write_file("rock_b_10.lua", "print('ROCK B 1.0'); return {}")
+ write_file("rock_b-1.0-1.rockspec", [[
+ package = "rock_b"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/rock_b_10.lua"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ rock_b = "rock_b_10.lua"
+ }
+ }
+ ]])
+
+ write_file("rock_a.lua", "require('rock_b'); return {}")
+ write_file("rock_a-2.0-1.rockspec", [[
+ package = "rock_a"
+ version = "2.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/rock_a.lua"
+ }
+ dependencies = {
+ "rock_b < 1.0",
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ rock_a = "rock_a.lua"
+ }
+ }
+ ]])
+
+ print(run.luarocks("make --server=" .. testing_paths.fixtures_dir .. "/a_repo --tree=" .. testing_paths.testing_tree .. " ./rock_b-0.1-1.rockspec"))
+ print(run.luarocks("make --server=" .. testing_paths.fixtures_dir .. "/a_repo --tree=" .. testing_paths.testing_tree .. " ./rock_b-1.0-1.rockspec --keep"))
+ print(run.luarocks("make --server=" .. testing_paths.fixtures_dir .. "/a_repo --tree=" .. testing_paths.testing_tree .. " ./rock_a-2.0-1.rockspec"))
+
+ local output = run.lua([[-e "require 'luarocks.loader'; require('rock_a')"]])
+
+ assert.matches("ROCK B 0.1", output, 1, true)
+ end, finally)
+ end)
+ end)
+end)
diff --git a/spec/make_spec.lua b/spec/make_spec.lua
new file mode 100644
index 0000000..b057263
--- /dev/null
+++ b/spec/make_spec.lua
@@ -0,0 +1,387 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local env_variables = test_env.env_variables
+local write_file = test_env.write_file
+
+local extra_rocks = {
+ "/luasocket-${LUASOCKET}.src.rock",
+ "/luasocket-${LUASOCKET}.rockspec",
+ "/lpeg-${LPEG}.src.rock",
+ "/lxsh-${LXSH}.src.rock",
+ "/lxsh-${LXSH}.rockspec"
+}
+
+describe("luarocks make #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("with no flags/arguments", function()
+ finally(function()
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("empty")
+ end)
+ assert(lfs.mkdir("empty"))
+ assert(lfs.chdir("empty"))
+ assert.is_false(run.luarocks_bool("make"))
+ end)
+
+ it("with rockspec", function()
+ finally(function()
+ -- delete downloaded and unpacked files
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("luasocket-${LUASOCKET}")
+ os.remove("luasocket-${LUASOCKET}.src.rock")
+ end)
+
+ -- make luasocket
+ assert.is_true(run.luarocks_bool("download --source luasocket ${LUASOCKET}"))
+ assert.is_true(run.luarocks_bool("unpack luasocket-${LUASOCKET}.src.rock"))
+ lfs.chdir("luasocket-${LUASOCKET}/luasocket/")
+ assert.is_true(run.luarocks_bool("make luasocket-${LUASOCKET}.rockspec"))
+
+ -- test it
+ assert.is_true(run.luarocks_bool("show luasocket"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/luasocket/${LUASOCKET}/luasocket-${LUASOCKET}.rockspec"))
+ end)
+
+ it("--no-doc", function()
+ finally(function()
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("luasocket-${LUASOCKET}")
+ os.remove("luasocket-${LUASOCKET}.src.rock")
+ end)
+
+ assert.is_true(run.luarocks_bool("download --source luasocket ${LUASOCKET}"))
+ assert.is_true(run.luarocks_bool("unpack luasocket-${LUASOCKET}.src.rock"))
+ lfs.chdir("luasocket-${LUASOCKET}/luasocket")
+ assert.is_true(run.luarocks_bool("make --no-doc luasocket-${LUASOCKET}.rockspec"))
+
+ assert.is_true(run.luarocks_bool("show luasocket"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/luasocket/${LUASOCKET}/doc"))
+ end)
+
+ it("--only-deps", function()
+ local rockspec = "build_only_deps-0.1-1.rockspec"
+ local src_rock = testing_paths.fixtures_dir .. "/build_only_deps-0.1-1.src.rock"
+
+ test_env.remove_dir("build_only_deps-0.1-1/")
+ assert.is_true(run.luarocks_bool("unpack " .. src_rock))
+ lfs.chdir("build_only_deps-0.1-1/")
+ assert.is_true(run.luarocks_bool("make " .. rockspec .. " --only-deps"))
+ assert.is_false(run.luarocks_bool("show build_only_deps"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/build_only_deps/0.1-1/build_only_deps-0.1-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ end)
+
+ describe("LuaRocks making rockspecs (using lxsh)", function()
+ --download lxsh and unpack it
+ before_each(function()
+ assert.is_true(run.luarocks_bool("download --source lxsh ${LXSH}"))
+ assert.is_true(run.luarocks_bool("unpack lxsh-${LXSH}.src.rock"))
+ assert.is_true(lfs.chdir("lxsh-${LXSH}/lxsh-${LXSH_V}-1/"))
+ end)
+
+ -- delete downloaded and unpacked files
+ after_each(function()
+ assert(lfs.chdir(testing_paths.testrun_dir))
+ test_env.remove_dir("lxsh-${LXSH}")
+ assert.is_true(os.remove("lxsh-${LXSH}.src.rock"))
+ end)
+
+ it("default rockspec", function()
+ assert.is_true(run.luarocks_bool("new_version lxsh-${LXSH}.rockspec"))
+ assert.is_true(run.luarocks_bool("make"))
+
+ assert.is_true(run.luarocks_bool("show lxsh"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH_V}-3/lxsh-${LXSH_V}-3.rockspec"))
+ end)
+
+ it("unnamed rockspec", function()
+ finally(function()
+ os.remove("rockspec")
+ end)
+
+ test_env.copy("lxsh-${LXSH}.rockspec", "rockspec")
+ assert.is_true(run.luarocks_bool("make"))
+
+ assert.is_true(run.luarocks_bool("show lxsh"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("ambiguous rockspec", function()
+ assert.is.truthy(os.rename("lxsh-${LXSH}.rockspec", "lxsh2-${LXSH}.rockspec"))
+ local output = run.luarocks("make")
+ assert.is.truthy(output:match("Error: Inconsistency between rockspec filename"))
+
+ assert.is_false(run.luarocks_bool("show lxsh"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("ambiguous unnamed rockspec", function()
+ assert.is.truthy(os.rename("lxsh-${LXSH}.rockspec", "1_rockspec"))
+ test_env.copy("1_rockspec", "2_rockspec")
+ local output = run.luarocks("make")
+ assert.is.truthy(output:match("Error: Please specify which rockspec file to use"))
+
+ assert.is_false(run.luarocks_bool("show lxsh"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/lxsh/${LXSH}/lxsh-${LXSH}.rockspec"))
+ end)
+
+ it("pack binary rock", function()
+ assert.is_true(run.luarocks_bool("make --deps-mode=none --pack-binary-rock"))
+ assert.is.truthy(lfs.attributes("lxsh-${LXSH}.all.rock"))
+ end)
+ end)
+
+ it("supports --pin #pinning", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock 1.0"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+
+ assert.is_true(run.luarocks_bool("make --server=" .. testing_paths.fixtures_dir .. "/a_repo --pin --tree=lua_modules"))
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/1.0-1/test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ local lockfilename = "./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/1.0-1/luarocks.lock"
+ assert.is.truthy(lfs.attributes(lockfilename))
+ local lockdata = loadfile(lockfilename)()
+ assert.same({
+ dependencies = {
+ ["a_rock"] = "1.0-1",
+ ["lua"] = test_env.lua_version .. "-1",
+ }
+ }, lockdata)
+ end, finally)
+ end)
+
+ it("respects luarocks.lock when present #pinning", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-2.0-1.rockspec", [[
+ package = "test"
+ version = "2.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock >= 0.8"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]])
+ write_file("test.lua", "return {}")
+ write_file("luarocks.lock", [[
+ return {
+ dependencies = {
+ ["a_rock"] = "1.0-1",
+ }
+ }
+ ]])
+
+ print(run.luarocks("make --server=" .. testing_paths.fixtures_dir .. "/a_repo --tree=lua_modules"))
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/2.0-1/test-2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes("./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec"))
+ local lockfilename = "./lua_modules/lib/luarocks/rocks-" .. test_env.lua_version .. "/test/2.0-1/luarocks.lock"
+ assert.is.truthy(lfs.attributes(lockfilename))
+ local lockdata = loadfile(lockfilename)()
+ assert.same({
+ dependencies = {
+ ["a_rock"] = "1.0-1",
+ }
+ }, lockdata)
+ end, finally)
+ end)
+
+ describe("#ddt upgrading rockspecs with double deploy types", function()
+ local deploy_lib_dir = testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION
+ local deploy_lua_dir = testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION
+ local so = test_env.lib_extension
+
+ before_each(function()
+ test_env.copy_dir(testing_paths.fixtures_dir .. "/double_deploy_type", "ddt")
+ end)
+
+ after_each(function()
+ test_env.remove_dir("ddt")
+ os.remove("ddt."..test_env.lib_extension)
+ end)
+
+ it("when upgrading", function()
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt1", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt2", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+ end)
+
+ it("modules with same name from lua/ and lib/ when upgrading with --keep", function()
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt1", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.2.0-1.rockspec --keep"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt2", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/double_deploy_type_0_1_0_1-ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/double_deploy_type_0_1_0_1-ddt.lua"))
+ assert.same("ddt1", loadfile(deploy_lua_dir.."/double_deploy_type_0_1_0_1-ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/double_deploy_type_0_1_0_1-ddt_file"))
+ end)
+
+ it("modules with same name from lua/ and lib/ when downgrading", function()
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt2", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt1", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+ end)
+
+ it("modules with same name from lua/ and lib/ when downgrading with --keep", function()
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt2", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+
+ assert.is_true(run.luarocks_bool("make ddt/double_deploy_type-0.1.0-1.rockspec --keep"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt.lua"))
+ assert.same("ddt2", loadfile(deploy_lua_dir.."/ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/ddt_file"))
+ assert.is.falsy(lfs.attributes(deploy_lib_dir.."/ddt."..so.."~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt.lua~"))
+ assert.is.falsy(lfs.attributes(deploy_lua_dir.."/ddt_file~"))
+ assert.is.truthy(lfs.attributes(deploy_lib_dir.."/double_deploy_type_0_1_0_1-ddt."..so))
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/double_deploy_type_0_1_0_1-ddt.lua"))
+ assert.same("ddt1", loadfile(deploy_lua_dir.."/double_deploy_type_0_1_0_1-ddt.lua")())
+ assert.is.truthy(lfs.attributes(deploy_lua_dir.."/double_deploy_type_0_1_0_1-ddt_file"))
+ end)
+ end)
+
+ describe("upgrading rockspecs with mixed deploy types", function()
+ before_each(function()
+ test_env.copy_dir(testing_paths.fixtures_dir .. "/mixed_deploy_type", "mdt")
+ end)
+
+ after_each(function()
+ test_env.remove_dir("mdt")
+ os.remove("mdt."..test_env.lib_extension)
+ end)
+
+ it("modules with same name from lua/ and lib/ when upgrading", function()
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt.lua"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt."..test_env.lib_extension))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt.lua"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt.lua"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt_file"))
+ end)
+
+ it("modules with same name from lua/ and lib/ when upgrading with --keep", function()
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt.lua"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.2.0-1.rockspec --keep"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt."..test_env.lib_extension))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt.lua"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt.lua"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt_file"))
+ end)
+
+ it("modules with same name from lua/ and lib/ when downgrading", function()
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt."..test_env.lib_extension))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.1.0-1.rockspec"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt."..test_env.lib_extension))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt."..test_env.lib_extension))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt_file"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt.lua"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt.lua"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt_file"))
+ end)
+
+ it("modules with same name from lua/ and lib/ when downgrading with --keep", function()
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.2.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt."..test_env.lib_extension))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+
+ assert.is_true(run.luarocks_bool("make mdt/mixed_deploy_type-0.1.0-1.rockspec --keep"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt."..test_env.lib_extension))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt.lua"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mdt_file"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt.lua"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_tree .. "/share/lua/"..env_variables.LUA_VERSION.."/mixed_deploy_type_0_1_0_1-mdt_file"))
+ end)
+ end)
+end)
diff --git a/spec/pack_spec.lua b/spec/pack_spec.lua
new file mode 100644
index 0000000..2a2fb3a
--- /dev/null
+++ b/spec/pack_spec.lua
@@ -0,0 +1,102 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+
+describe("luarocks pack #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs()
+ end)
+
+ describe("#mock", function()
+
+ lazy_setup(function()
+ test_env.setup_specs(extra_rocks, "mock")
+ test_env.mock_server_init()
+ end)
+
+ lazy_teardown(function()
+ test_env.mock_server_done()
+ end)
+
+ it("can pack a rockspec into a .src.rock", function()
+ finally(function()
+ os.remove("a_rock-1.0-1.src.rock")
+ end)
+ assert(run.luarocks_bool("download --rockspec --server=" .. testing_paths.fixtures_dir .. "/a_repo a_rock 1.0-1"))
+ assert(run.luarocks_bool("pack a_rock-1.0-1.rockspec"))
+ assert.is_truthy(lfs.attributes("a_rock-1.0-1.src.rock"))
+ end)
+
+ it("can pack a rockspec with a bare file:// in the url", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test.lua"
+ }
+ dependencies = {
+ "a_rock 1.0"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+ write_file("test.lua", "return {}", finally)
+
+ assert.is.truthy(run.luarocks_bool("pack test-1.0-1.rockspec"))
+ assert.is.truthy(lfs.attributes("test-1.0-1.src.rock"))
+
+ assert.is.truthy(run.luarocks_bool("unpack test-1.0-1.src.rock"))
+ assert.is.truthy(lfs.attributes("test-1.0-1/test.lua"))
+ end, finally)
+ end)
+
+ it("can pack a rockspec with a bare file:// fails if doesn't exist", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file("test-1.0-1.rockspec", [[
+ package = "test"
+ version = "1.0-1"
+ source = {
+ url = "file://]] .. tmpdir:gsub("\\", "/") .. [[/test_doesnt_exist.lua"
+ }
+ dependencies = {
+ "a_rock 1.0"
+ }
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ ]], finally)
+
+ assert.is.falsy(run.luarocks_bool("pack test-1.0-1.rockspec"))
+ assert.is.falsy(lfs.attributes("test-1.0-1.src.rock"))
+ end, finally)
+ end)
+
+
+ it("fails packing a rockspec into a .src.rock if dir doesn't exist", function()
+ local output = run.luarocks("pack " .. testing_paths.fixtures_dir .. "/bad_pack-0.1-1.rockspec")
+ assert.match("Directory invalid_dir not found", output)
+ assert.is_falsy(lfs.attributes("bad_pack-0.1-1.src.rock"))
+ end)
+
+ describe("namespaced dependencies", function()
+ it("can pack rockspec with namespaced dependencies", function()
+ finally(function()
+ os.remove("has_namespaced_dep-1.0-1.src.rock")
+ end)
+ assert(run.luarocks_bool("pack " .. testing_paths.fixtures_dir .. "/a_repo/has_namespaced_dep-1.0-1.rockspec"))
+ assert.is_truthy(lfs.attributes("has_namespaced_dep-1.0-1.src.rock"))
+ end)
+ end)
+ end)
+end)
diff --git a/spec/path_spec.lua b/spec/path_spec.lua
new file mode 100644
index 0000000..1ad6b3a
--- /dev/null
+++ b/spec/path_spec.lua
@@ -0,0 +1,58 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+
+describe("luarocks path #integration", function()
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ it("runs", function()
+ local output = run.luarocks("path")
+ assert.match("LUA_PATH=", output)
+ assert.match("LUA_CPATH=", output)
+ end)
+
+ if _VERSION:match("[23]") then
+ local v = _VERSION:gsub("Lua (%d+)%.(%d+)", "%1_%2")
+
+ it("with LUA_PATH_"..v, function()
+ local output = run.luarocks("path", {
+ ["LUA_PATH_"..v] = package.path,
+ })
+ assert.match("LUA_PATH_"..v.."=", output)
+ end)
+
+ it("with LUA_CPATH_"..v, function()
+ local output = run.luarocks("path", {
+ ["LUA_CPATH_"..v] = package.cpath,
+ })
+ assert.match("LUA_CPATH_"..v.."=", output)
+ end)
+
+ it("with LUA_PATH_"..v.." and LUA_CPATH_"..v, function()
+ local output = run.luarocks("path", {
+ ["LUA_PATH_"..v] = package.path,
+ ["LUA_CPATH_"..v] = package.cpath,
+ })
+ assert.match("LUA_PATH_"..v.."=", output)
+ assert.match("LUA_CPATH_"..v.."=", output)
+ end)
+
+ end
+
+ it("--bin", function()
+ assert.is_true(run.luarocks_bool("path --bin"))
+ end)
+
+ it("--lr-path", function()
+ assert.is_true(run.luarocks_bool("path --lr-path"))
+ end)
+
+ it("--lr-cpath", function()
+ assert.is_true(run.luarocks_bool("path --lr-cpath"))
+ end)
+
+ it("--tree", function()
+ assert.is_true(run.luarocks_bool("path --tree=lua_modules"))
+ end)
+end)
diff --git a/spec/quick/admin_make_manifest.q b/spec/quick/admin_make_manifest.q
new file mode 100644
index 0000000..527e86a
--- /dev/null
+++ b/spec/quick/admin_make_manifest.q
@@ -0,0 +1,46 @@
+SUITE: luarocks-admin make_manifest
+
+================================================================================
+TEST: runs
+
+FILE: test-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/test.lua"
+}
+build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: test.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks make --pack-binary-rock ./test-1.0-1.rockspec
+
+RUN: luarocks-admin make_manifest .
+
+FILE_CONTENTS: ./manifest-%{lua_version}
+--------------------------------------------------------------------------------
+commands = {}
+modules = {}
+repository = {
+ test = {
+ ["1.0-1"] = {
+ {
+ arch = "all"
+ },
+ {
+ arch = "rockspec"
+ }
+ }
+ }
+}
+--------------------------------------------------------------------------------
diff --git a/spec/quick/build.q b/spec/quick/build.q
new file mode 100644
index 0000000..d0d6a89
--- /dev/null
+++ b/spec/quick/build.q
@@ -0,0 +1,405 @@
+SUITE: luarocks build
+
+================================================================================
+TEST: fails when given invalid argument
+RUN: luarocks build aoesuthaoeusahtoeustnaou --only-server=localhost
+EXIT: 1
+STDERR:
+--------------------------------------------------------------------------------
+Could not find a result named aoesuthaoeusahtoeustnaou
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: with no arguments behaves as luarocks make
+
+FILE: c_module-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "c_module"
+version = "1.0-1"
+source = {
+ url = "http://example.com/c_module"
+}
+build = {
+ type = "builtin",
+ modules = {
+ c_module = { "c_module.c" }
+ }
+}
+--------------------------------------------------------------------------------
+FILE: c_module.c
+--------------------------------------------------------------------------------
+#include <lua.h>
+#include <lauxlib.h>
+
+int luaopen_c_module(lua_State* L) {
+ lua_newtable(L);
+ lua_pushinteger(L, 1);
+ lua_setfield(L, -2, "c_module");
+ return 1;
+}
+--------------------------------------------------------------------------------
+RUN: luarocks build
+EXISTS: c_module.%{lib_extension}
+
+
+
+================================================================================
+TEST: defaults to builtin type
+
+FILE: a_rock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "a_rock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ modules = {
+ build = "a_rock.lua"
+ },
+}
+--------------------------------------------------------------------------------
+RUN: luarocks build a_rock-1.0-1.rockspec
+RUN: luarocks show a_rock
+STDOUT:
+--------------------------------------------------------------------------------
+a_rock 1.0
+--------------------------------------------------------------------------------
+
+
+================================================================================
+TEST: fails if no permissions to access the specified tree #unix
+
+RUN: luarocks build --tree=/usr ./a_rock-1.0-1.rockspec
+EXIT: 2
+STDERR:
+--------------------------------------------------------------------------------
+You may want to run as a privileged user,
+or use --local to install into your local tree
+or run 'luarocks config local_by_default true' to make --local the default.
+
+(You may need to configure your Lua package paths
+to use the local tree, see 'luarocks path --help')
+--------------------------------------------------------------------------------
+
+We show the OS permission denied error, so we don't show the --force-lock
+message.
+
+NOT_STDERR:
+--------------------------------------------------------------------------------
+try --force-lock
+--------------------------------------------------------------------------------
+
+NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec
+
+
+
+================================================================================
+TEST: fails if tree is locked, --force-lock overrides #unix
+
+FILE: a_rock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "a_rock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ modules = {
+ build = "a_rock.lua"
+ },
+}
+--------------------------------------------------------------------------------
+
+FILE: %{testing_tree}/lockfile.lfs
+--------------------------------------------------------------------------------
+dummy lock file for testing
+--------------------------------------------------------------------------------
+
+RUN: luarocks build --tree=%{testing_tree} ./a_rock-1.0-1.rockspec
+EXIT: 4
+STDERR:
+--------------------------------------------------------------------------------
+requires exclusive write access
+try --force-lock
+--------------------------------------------------------------------------------
+
+RUN: luarocks build --tree=%{testing_tree} ./a_rock-1.0-1.rockspec --force-lock
+EXIT: 0
+
+
+
+================================================================================
+TEST: fails if no permissions to access the parent #unix
+
+RUN: luarocks build --tree=/usr/invalid ./a_rock-1.0-1.rockspec
+EXIT: 2
+STDERR:
+--------------------------------------------------------------------------------
+Error: /usr/invalid/lib/luarocks/rocks-%{lua_version} does not exist
+and your user does not have write permissions in /usr
+
+You may want to run as a privileged user,
+or use --local to install into your local tree
+or run 'luarocks config local_by_default true' to make --local the default.
+
+(You may need to configure your Lua package paths
+to use the local tree, see 'luarocks path --help')
+--------------------------------------------------------------------------------
+
+We show the OS permission denied error, so we don't show the --force-lock
+message.
+
+NOT_STDERR:
+--------------------------------------------------------------------------------
+try --force-lock
+--------------------------------------------------------------------------------
+
+NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec
+
+
+
+================================================================================
+TEST: luarocks build: do not rebuild when already installed
+
+FILE: a_rock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "a_rock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ modules = {
+ build = "a_rock.lua"
+ },
+}
+--------------------------------------------------------------------------------
+RUN: luarocks build a_rock-1.0-1.rockspec
+
+RUN: luarocks show a_rock
+STDOUT:
+--------------------------------------------------------------------------------
+a_rock 1.0
+--------------------------------------------------------------------------------
+
+RUN: luarocks build a_rock-1.0-1.rockspec
+STDOUT:
+--------------------------------------------------------------------------------
+a_rock 1.0-1 is already installed
+Use --force to reinstall
+--------------------------------------------------------------------------------
+
+
+RUN: luarocks build a_rock-1.0-1.rockspec --force
+NOT_STDOUT:
+--------------------------------------------------------------------------------
+a_rock 1.0-1 is already installed
+Use --force to reinstall
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: supports --pin #pinning
+
+FILE: test-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/test.lua"
+}
+dependencies = {
+ "a_rock >= 0.8"
+}
+build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: test.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build --only-server=%{fixtures_dir}/a_repo test-1.0-1.rockspec --pin --tree=lua_modules
+
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/1.0-1/test-1.0-1.rockspec
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/a_rock/2.0-1/a_rock-2.0-1.rockspec
+
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/1.0-1/luarocks.lock
+
+FILE_CONTENTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/1.0-1/luarocks.lock
+--------------------------------------------------------------------------------
+return {
+ dependencies = {
+ a_rock = "2.0-1",
+ lua = "%{lua_version}-1"
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: supports --pin --only-deps #pinning
+
+FILE: test-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/test.lua"
+}
+dependencies = {
+ "a_rock >= 0.8"
+}
+build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: test.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build --only-server=%{fixtures_dir}/a_repo test-1.0-1.rockspec --pin --only-deps --tree=lua_modules
+
+NOT_EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/1.0-1/test-1.0-1.rockspec
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/a_rock/2.0-1/a_rock-2.0-1.rockspec
+
+EXISTS: ./luarocks.lock
+
+FILE_CONTENTS: ./luarocks.lock
+--------------------------------------------------------------------------------
+return {
+ dependencies = {
+ a_rock = "2.0-1",
+ lua = "%{lua_version}-1"
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: installs bin entries correctly
+
+FILE: test-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/an_upstream_tarball-0.1.tar.gz",
+ dir = "an_upstream_tarball-0.1",
+}
+build = {
+ type = "builtin",
+ modules = {
+ my_module = "src/my_module.lua"
+ },
+ install = {
+ bin = {
+ "src/my_module.lua"
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build test-1.0-1.rockspec --tree=lua_modules
+
+RM: %{fixtures_dir}/bin/something.lua
+
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/1.0-1/test-1.0-1.rockspec
+
+FILE_CONTENTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/1.0-1/rock_manifest
+--------------------------------------------------------------------------------
+rock_manifest = {
+ bin = {
+ ["my_module.lua"] = "25884dbf5be7114791018a48199d4c04"
+ },
+ lua = {
+ ["my_module.lua"] = "25884dbf5be7114791018a48199d4c04"
+ },
+ ["test-1.0-1.rockspec"] =
+}
+--------------------------------------------------------------------------------
+
+EXISTS: ./lua_modules/bin/my_module.lua%{wrapper_extension}
+
+
+
+================================================================================
+TEST: downgrades directories correctly
+
+FILE: mytest-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "mytest"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/an_upstream_tarball-0.1.tar.gz",
+ dir = "an_upstream_tarball-0.1",
+}
+build = {
+ modules = {
+ ["parent.child.my_module"] = "src/my_module.lua"
+ },
+}
+--------------------------------------------------------------------------------
+
+FILE: mytest-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "mytest"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/an_upstream_tarball-0.1.tar.gz",
+ dir = "an_upstream_tarball-0.1",
+}
+build = {
+ modules = {
+ ["parent.child.my_module"] = "src/my_module.lua"
+ },
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build ./mytest-2.0-1.rockspec
+EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/parent/child/my_module.lua
+
+RUN: luarocks build ./mytest-1.0-1.rockspec
+EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/parent/child/my_module.lua
+
+RUN: luarocks build ./mytest-2.0-1.rockspec
+EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/parent/child/my_module.lua
diff --git a/spec/quick/cmd.q b/spec/quick/cmd.q
new file mode 100644
index 0000000..acde92b
--- /dev/null
+++ b/spec/quick/cmd.q
@@ -0,0 +1,36 @@
+SUITE: luarocks CLI
+
+================================================================================
+TEST: warns but continues if given an invalid version
+
+RUN: luarocks --lua-version 1.0
+
+STDOUT:
+--------------------------------------------------------------------------------
+Version : 1.0
+LUA : (interpreter not found)
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: reports if lua.h header is not found
+
+RUN: luarocks LUA_INCDIR=/bad/dir
+
+STDOUT:
+--------------------------------------------------------------------------------
+LUA_INCDIR : /bad/dir (lua.h not found)
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: reports if Lua library is not found
+
+RUN: luarocks LUA_LIBDIR=/bad/dir
+
+STDOUT:
+--------------------------------------------------------------------------------
+LUA_LIBDIR : /bad/dir (Lua library itself not found)
+--------------------------------------------------------------------------------
diff --git a/spec/quick/config.q b/spec/quick/config.q
new file mode 100644
index 0000000..d623056
--- /dev/null
+++ b/spec/quick/config.q
@@ -0,0 +1,97 @@
+SUITE: luarocks config
+
+================================================================================
+TEST: --system-config shows the path of the system config
+
+FILE: %{testing_lrprefix}/etc/luarocks/config-%{LUA_VERSION}.lua
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+RUN: luarocks config --system-config
+
+STDOUT:
+--------------------------------------------------------------------------------
+%{path(%{testing_lrprefix}/etc/luarocks/config-%{LUA_VERSION}.lua)}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: reports when setting a bad LUA_LIBDIR
+
+RUN: luarocks config variables.LUA_LIBDIR /some/bad/path
+
+LuaRocks writes configuration values as they are given, without auto-conversion
+of slashes for Windows:
+
+STDOUT:
+--------------------------------------------------------------------------------
+Wrote
+variables.LUA_LIBDIR = "/some/bad/path"
+--------------------------------------------------------------------------------
+
+STDERR:
+--------------------------------------------------------------------------------
+Warning: Failed finding the Lua library.
+Tried:
+
+LuaRocks may not work correctly when building C modules using this configuration.
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: reports when setting a bad LUA_INCDIR
+
+RUN: luarocks config variables.LUA_INCDIR /some/bad/path
+
+STDOUT:
+--------------------------------------------------------------------------------
+Wrote
+variables.LUA_INCDIR = "/some/bad/path"
+--------------------------------------------------------------------------------
+
+LuaRocks uses configuration values as they are given, without auto-conversion
+of slashes for Windows:
+
+STDERR:
+--------------------------------------------------------------------------------
+Warning: Failed finding Lua header lua.h (searched at /some/bad/path). You may need to install Lua development headers.
+
+LuaRocks may not work correctly when building C modules using this configuration.
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: rejects setting bad lua_dir
+
+RUN: luarocks config lua_dir /some/bad/dir
+EXIT: 1
+
+STDERR:
+--------------------------------------------------------------------------------
+Lua interpreter not found
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: reports when setting a bad LUA_INCDIR
+
+RUN: luarocks config variables.LUA_INCDIR /some/bad/path
+
+STDOUT:
+--------------------------------------------------------------------------------
+Wrote
+variables.LUA_INCDIR = "/some/bad/path"
+--------------------------------------------------------------------------------
+
+LuaRocks uses configuration values as they are given, without auto-conversion
+of slashes for Windows:
+
+STDERR:
+--------------------------------------------------------------------------------
+Warning: Failed finding Lua header lua.h (searched at /some/bad/path). You may need to install Lua development headers.
+
+LuaRocks may not work correctly when building C modules using this configuration.
+--------------------------------------------------------------------------------
diff --git a/spec/quick/doc.q b/spec/quick/doc.q
new file mode 100644
index 0000000..4c71f83
--- /dev/null
+++ b/spec/quick/doc.q
@@ -0,0 +1,13 @@
+SUITE: luarocks doc
+
+================================================================================
+TEST: --local
+
+RUN: luarocks install --local --only-server=%{fixtures_dir}/a_repo a_rock
+
+RUN: luarocks doc a_rock --local
+
+STDOUT:
+--------------------------------------------------------------------------------
+opening http://www.example.com
+--------------------------------------------------------------------------------
diff --git a/spec/quick/install.q b/spec/quick/install.q
new file mode 100644
index 0000000..e2df428
--- /dev/null
+++ b/spec/quick/install.q
@@ -0,0 +1,688 @@
+SUITE: luarocks install
+
+===============================================================================
+TEST: fails with no flags or arguments
+RUN: luarocks install
+EXIT: 1
+
+
+
+===============================================================================
+TEST: fails with an unknown rock
+RUN: luarocks install aoeuaoeuaoeiaoeuaoeua
+EXIT: 1
+
+
+
+===============================================================================
+TEST: fails with an invalid .rock argument
+RUN: luarocks install "invalid.rock"
+EXIT: 1
+
+
+
+===============================================================================
+TEST: fails with incompatible architecture
+RUN: luarocks install foo-1.0-1.impossible-x86.rock
+EXIT: 1
+STDERR:
+--------------------------------------------------------------------------------
+Incompatible architecture
+--------------------------------------------------------------------------------
+
+
+
+===============================================================================
+TEST: fails if not a zip file
+
+FILE: not_a_zipfile-1.0-1.src.rock
+--------------------------------------------------------------------------------
+I am not a zip file!
+--------------------------------------------------------------------------------
+RUN: luarocks install not_a_zipfile-1.0-1.src.rock
+EXIT: 1
+
+
+
+===============================================================================
+TEST: fails with an invalid patch
+
+FILE: invalid_patch-0.1-1.rockspec
+--------------------------------------------------------------------------------
+package = "invalid_patch"
+version = "0.1-1"
+source = {
+ -- any valid URL
+ url = "https://raw.github.com/keplerproject/luarocks/master/src/luarocks/build.lua"
+}
+description = {
+ summary = "A rockspec with an invalid patch",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ build = "build.lua"
+ },
+ patches = {
+ ["I_am_an_invalid_patch.patch"] =
+[[
+diff -Naur luadoc-3.0.1/src/luadoc/doclet/html.lua luadoc-3.0.1-new/src/luadoc/doclet/html.lua
+--- luadoc-3.0.1/src/luadoc/doclet/html.lua2007-12-21 15:50:48.000000000 -0200
++++ luadoc-3.0.1-new/src/luadoc/doclet/html.lua2008-02-28 01:59:53.000000000 -0300
+@@ -18,6 +18,7 @@
+- gabba gabba gabba
++ gobo gobo gobo
+]]
+ }
+}
+--------------------------------------------------------------------------------
+RUN: luarocks invalid_patch-0.1-1.rockspec
+EXIT: 1
+
+
+
+================================================================================
+TEST: handle versioned modules when installing another version with --keep #268
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-1.0-1.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+RUN: luarocks build myrock-2.0-1.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+RUN: luarocks install ./myrock-2.0-1.all.rock
+
+EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua
+
+RUN: luarocks install ./myrock-1.0-1.all.rock --keep
+
+EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua
+EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/myrock_1_0_1-rock.lua
+
+RUN: luarocks install ./myrock-2.0-1.all.rock
+
+EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua
+NOT_EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/myrock_1_0_1-rock.lua
+
+
+
+================================================================================
+TEST: handle versioned libraries when installing another version with --keep #268
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/c_module.c"
+}
+build = {
+ modules = {
+ c_module = { "c_module.c" }
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/c_module.c"
+}
+build = {
+ modules = {
+ c_module = { "c_module.c" }
+ }
+}
+--------------------------------------------------------------------------------
+FILE: c_module.c
+--------------------------------------------------------------------------------
+#include <lua.h>
+#include <lauxlib.h>
+
+int luaopen_c_module(lua_State* L) {
+ lua_newtable(L);
+ lua_pushinteger(L, 1);
+ lua_setfield(L, -2, "c_module");
+ return 1;
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-1.0-1.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+RUN: luarocks build myrock-2.0-1.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+RUN: luarocks install ./myrock-2.0-1.%{platform}.rock
+
+EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension}
+
+RUN: luarocks install ./myrock-1.0-1.%{platform}.rock --keep
+
+EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension}
+EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/myrock_1_0_1-c_module.%{lib_extension}
+
+RUN: luarocks install ./myrock-2.0-1.%{platform}.rock
+
+EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension}
+NOT_EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/myrock_1_0_1-c_module.%{lib_extension}
+
+
+
+================================================================================
+TEST: installs a package with a bin entry
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" },
+ install = {
+ bin = {
+ ["scripty"] = "rock.lua",
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-1.0-1.rockspec
+EXISTS: %{testing_sys_tree}/bin/scripty%{wrapper_extension}
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+NOT_EXISTS: %{testing_sys_tree}/bin/scripty%{wrapper_extension}
+
+RUN: luarocks install myrock-1.0-1.all.rock
+EXISTS: %{testing_sys_tree}/bin/scripty%{wrapper_extension}
+
+
+
+================================================================================
+TEST: installs a package without its documentation using --no-doc
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "."
+}
+build = {
+ modules = { rock = "rock.lua" },
+ install = {
+ bin = {
+ ["scripty"] = "rock.lua",
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+FILE: doc/something
+--------------------------------------------------------------------------------
+a doc
+--------------------------------------------------------------------------------
+
+RUN: luarocks make
+EXISTS: %{testing_sys_rocks}/myrock/1.0-1/doc/something
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+NOT_EXISTS: %{testing_sys_rocks}/myrock/1.0-1/doc/something
+
+RUN: luarocks install myrock-1.0-1.all.rock
+EXISTS: %{testing_sys_rocks}/myrock/1.0-1/doc/something
+RUN: luarocks remove myrock
+NOT_EXISTS: %{testing_sys_rocks}/myrock/1.0-1/doc/something
+
+RUN: luarocks install myrock-1.0-1.all.rock --no-doc
+NOT_EXISTS: %{testing_sys_rocks}/myrock/1.0-1/doc/something
+
+
+
+================================================================================
+TEST: handle non-Lua files in build.install.lua when upgrading sailorproject/sailor#138
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "."
+}
+build = {
+ modules = {
+ rock = "rock.lua",
+ },
+ install = {
+ lua = {
+ ["sailor.blank-app.htaccess"] = "src/sailor/blank-app/.htaccess",
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-1.0-2.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-2"
+source = {
+ url = "."
+}
+build = {
+ modules = {
+ rock = "rock.lua",
+ },
+ install = {
+ lua = {
+ ["sailor.blank-app.htaccess"] = "src/sailor/blank-app/.htaccess",
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+FILE: src/sailor/blank-app/.htaccess
+--------------------------------------------------------------------------------
+# I am just a file
+--------------------------------------------------------------------------------
+
+Prepare two versions as .rock packages with the same non-Lua asset:
+
+RUN: luarocks make ./myrock-1.0-1.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+RUN: luarocks make ./myrock-1.0-2.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+Now install the first one, and check that the asset was installed, with no "~"
+backup leftover:
+
+RUN: luarocks install myrock-1.0-1.all.rock --no-doc
+
+EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/sailor/blank-app/.htaccess
+NOT_EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/sailor/blank-app/.htaccess~
+
+Then install the second one, and the asset should be replaced, again with no
+"~" backup leftover:
+
+RUN: luarocks install myrock-1.0-2.all.rock --no-doc
+
+EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/sailor/blank-app/.htaccess
+NOT_EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/sailor/blank-app/.htaccess~
+
+
+
+================================================================================
+TEST: do not reinstall when already installed
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-1.0-1.rockspec
+RUN: luarocks pack myrock
+RUN: luarocks remove myrock
+
+RUN: luarocks install ./myrock-1.0-1.all.rock
+
+RUN: luarocks show myrock
+STDOUT:
+--------------------------------------------------------------------------------
+myrock 1.0
+--------------------------------------------------------------------------------
+
+RUN: luarocks install ./myrock-1.0-1.all.rock
+STDOUT:
+--------------------------------------------------------------------------------
+myrock 1.0-1 is already installed
+Use --force to reinstall
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: installation rolls back on failure
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = {
+ ["folder.rock"] = "rock.lua",
+ ["xyz"] = "xyz.lua",
+ },
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+FILE: xyz.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks make --pack-binary-rock ./myrock-1.0-1.rockspec
+
+FILE: %{testing_sys_tree}/share/lua/%{lua_version}/folder
+--------------------------------------------------------------------------------
+a file where a folder should be
+--------------------------------------------------------------------------------
+
+Try to install and fail because the file is in the folder's spot:
+
+RUN: luarocks install ./myrock-1.0-1.all.rock
+EXIT: 1
+
+EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/folder
+
+No leftovers from the failed installation:
+
+NOT_EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/xyz.lua
+
+Now we remove the file...
+
+RM: %{testing_sys_tree}/share/lua/%{lua_version}/folder
+
+Try again and succeed:
+
+RUN: luarocks install ./myrock-1.0-1.all.rock
+
+EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/folder/rock.lua
+EXISTS: %{testing_sys_tree}/share/lua/%{lua_version}/xyz.lua
+
+
+
+================================================================================
+TEST: new install functionality based on #552: break dependencies warning
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: hasdep-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "hasdep"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/hasdep.lua"
+}
+dependencies = {
+ "myrock >= 2.0",
+}
+build = {
+ modules = { hasdep = "hasdep.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+FILE: hasdep.lua
+--------------------------------------------------------------------------------
+return "hasdep"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-2.0-1.rockspec
+RUN: luarocks build hasdep-1.0-1.rockspec
+RUN: luarocks build myrock-1.0-1.rockspec
+
+STDERR:
+--------------------------------------------------------------------------------
+Will not remove myrock 2.0
+Removing it would break dependencies for
+hasdep 1.0
+--------------------------------------------------------------------------------
+
+EXISTS: %{testing_sys_rocks}/myrock/1.0-1
+EXISTS: %{testing_sys_rocks}/myrock/2.0-1
+
+
+
+================================================================================
+TEST: new install functionality based on #552: break dependencies with --force
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: hasdep-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "hasdep"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/hasdep.lua"
+}
+dependencies = {
+ "myrock >= 2.0",
+}
+build = {
+ modules = { hasdep = "hasdep.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+FILE: hasdep.lua
+--------------------------------------------------------------------------------
+return "hasdep"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-2.0-1.rockspec
+RUN: luarocks build hasdep-1.0-1.rockspec
+RUN: luarocks build myrock-1.0-1.rockspec --force
+
+STDERR:
+--------------------------------------------------------------------------------
+The following packages may be broken by this forced removal
+hasdep 1.0
+--------------------------------------------------------------------------------
+
+NOT_EXISTS: %{testing_sys_rocks}/myrock/2.0-1
+EXISTS: %{testing_sys_rocks}/myrock/1.0-1
+
+
+
+================================================================================
+TEST: new install functionality based on #552: break dependencies with --force-fast
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: hasdep-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "hasdep"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/hasdep.lua"
+}
+dependencies = {
+ "myrock >= 2.0",
+}
+build = {
+ modules = { hasdep = "hasdep.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+FILE: hasdep.lua
+--------------------------------------------------------------------------------
+return "hasdep"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-2.0-1.rockspec
+RUN: luarocks build hasdep-1.0-1.rockspec
+RUN: luarocks build myrock-1.0-1.rockspec --force-fast
+
+NOT_STDERR:
+--------------------------------------------------------------------------------
+The following packages may be broken by this forced removal
+hasdep 1.0
+--------------------------------------------------------------------------------
+
+NOT_EXISTS: %{testing_sys_rocks}/myrock/2.0-1
+EXISTS: %{testing_sys_rocks}/myrock/1.0-1
diff --git a/spec/quick/list.q b/spec/quick/list.q
new file mode 100644
index 0000000..a40f37e
--- /dev/null
+++ b/spec/quick/list.q
@@ -0,0 +1,45 @@
+SUITE: luarocks list
+
+================================================================================
+TEST: invalid tree
+
+RUN: luarocks --tree=%{path(/some/invalid/tree)} list
+
+STDOUT:
+--------------------------------------------------------------------------------
+Rocks installed for Lua %{lua_version} in %{path(/some/invalid/tree)}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: --porcelain
+
+FILE: a_rock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "a_rock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/a_rock.lua"
+}
+description = {
+ summary = "An example rockspec",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ modules = {
+ build = "a_rock.lua"
+ },
+}
+--------------------------------------------------------------------------------
+RUN: luarocks build a_rock-1.0-1.rockspec
+
+RUN: luarocks list --porcelain
+
+STDOUT:
+--------------------------------------------------------------------------------
+a_rock 1.0-1 installed %{testing_sys_rocks}
+--------------------------------------------------------------------------------
diff --git a/spec/quick/make.q b/spec/quick/make.q
new file mode 100644
index 0000000..eb3472b
--- /dev/null
+++ b/spec/quick/make.q
@@ -0,0 +1,88 @@
+SUITE: luarocks make
+
+================================================================================
+TEST: overrides luarocks.lock with --pin #pinning
+
+FILE: test-2.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "2.0-1"
+source = {
+ url = "file://%{path(tmpdir)}/test.lua"
+}
+dependencies = {
+ "a_rock >= 0.8"
+}
+build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: test.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+FILE: luarocks.lock
+--------------------------------------------------------------------------------
+return {
+ dependencies = {
+ ["a_rock"] = "1.0-1",
+ }
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks make --only-server=%{fixtures_dir}/a_repo --pin --tree=lua_modules
+
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/2.0-1/test-2.0-1.rockspec
+EXISTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/a_rock/2.0-1/a_rock-2.0-1.rockspec
+
+FILE_CONTENTS: ./lua_modules/lib/luarocks/rocks-%{lua_version}/test/2.0-1/luarocks.lock
+--------------------------------------------------------------------------------
+return {
+ dependencies = {
+ a_rock = "2.0-1",
+ lua = "%{lua_version}-1"
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: running make twice builds twice
+
+FILE: test-2.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "2.0-1"
+source = {
+ url = "file://%{path(tmpdir)}/test.lua"
+}
+build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: test.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks make --only-server=%{fixtures_dir}/a_repo --pin --tree=lua_modules
+STDOUT:
+--------------------------------------------------------------------------------
+test 2.0-1 is now installed
+--------------------------------------------------------------------------------
+
+RUN: luarocks make --only-server=%{fixtures_dir}/a_repo --pin --tree=lua_modules
+STDOUT:
+--------------------------------------------------------------------------------
+test 2.0-1 is now installed
+--------------------------------------------------------------------------------
diff --git a/spec/quick/new_version.q b/spec/quick/new_version.q
new file mode 100644
index 0000000..98426db
--- /dev/null
+++ b/spec/quick/new_version.q
@@ -0,0 +1,213 @@
+SUITE: luarocks new_version
+
+================================================================================
+TEST: fails without a context
+
+RUN: luarocks new_version
+EXIT: 1
+
+
+
+================================================================================
+TEST: fails with invalid arg
+
+RUN: luarocks new_version i_dont_exist
+EXIT: 1
+
+
+
+================================================================================
+TEST: updates a version
+
+FILE: myexample-0.1-1.rockspec
+--------------------------------------------------------------------------------
+package = "myexample"
+version = "0.1-1"
+source = {
+ url = "git+https://localhost/myexample.git",
+ tag = "v0.1"
+}
+description = {
+ summary = "xxx",
+ detailed = "xxx"
+}
+build = {
+ type = "builtin",
+ modules = {
+ foo = "src/foo.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks new_version myexample-0.1-1.rockspec 0.2
+
+FILE_CONTENTS: myexample-0.2-1.rockspec
+--------------------------------------------------------------------------------
+package = "myexample"
+version = "0.2-1"
+source = {
+ url = "git+https://localhost/myexample.git",
+ tag = "v0.2"
+}
+description = {
+ summary = "xxx",
+ detailed = "xxx"
+}
+build = {
+ type = "builtin",
+ modules = {
+ foo = "src/foo.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: updates via tag
+
+FILE: myexample-0.1-1.rockspec
+--------------------------------------------------------------------------------
+package = "myexample"
+version = "0.1-1"
+source = {
+ url = "git+https://localhost/myexample.git",
+ tag = "v0.1"
+}
+description = {
+ summary = "xxx",
+ detailed = "xxx"
+}
+build = {
+ type = "builtin",
+ modules = {
+ foo = "src/foo.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks new_version myexample-0.1-1.rockspec --tag v0.2
+
+FILE_CONTENTS: myexample-0.2-1.rockspec
+--------------------------------------------------------------------------------
+package = "myexample"
+version = "0.2-1"
+source = {
+ url = "git+https://localhost/myexample.git",
+ tag = "v0.2"
+}
+description = {
+ summary = "xxx",
+ detailed = "xxx"
+}
+build = {
+ type = "builtin",
+ modules = {
+ foo = "src/foo.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: updates URL
+
+FILE: myexample-0.1-1.rockspec
+--------------------------------------------------------------------------------
+package = "myexample"
+version = "0.1-1"
+source = {
+ url = "https://localhost/myexample-0.1.tar.gz",
+}
+description = {
+ summary = "xxx",
+ detailed = "xxx"
+}
+build = {
+ type = "builtin",
+ modules = {
+ foo = "src/foo.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks new_version myexample-0.1-1.rockspec 0.2 https://localhost/newpath/myexample-0.2.tar.gz
+
+FILE_CONTENTS: myexample-0.2-1.rockspec
+--------------------------------------------------------------------------------
+package = "myexample"
+version = "0.2-1"
+source = {
+ url = "https://localhost/newpath/myexample-0.2.tar.gz"
+}
+description = {
+ summary = "xxx",
+ detailed = "xxx"
+}
+build = {
+ type = "builtin",
+ modules = {
+ foo = "src/foo.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: updates MD5
+
+FILE: test-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/an_upstream_tarball-0.1.tar.gz",
+ md5 = "dca2ac30ce6c27cbd8dac4dd8f447630",
+}
+build = {
+ type = "builtin",
+ modules = {
+ my_module = "src/my_module.lua"
+ },
+ install = {
+ bin = {
+ "src/my_module.lua"
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks new_version test-1.0-1.rockspec 2.0 file://%{url(%{fixtures_dir})}/busted_project-0.1.tar.gz
+
+FILE_CONTENTS: test-2.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "test"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{fixtures_dir})}/busted_project-0.1.tar.gz",
+ md5 = "adfdfb8f1caa2b1f935a578fb07536eb",
+}
+build = {
+ type = "builtin",
+ modules = {
+ my_module = "src/my_module.lua"
+ },
+ install = {
+ bin = {
+ "src/my_module.lua"
+ }
+ }
+}
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: takes a URL, downloads and bumps revision by default
+
+RUN: luarocks new_version file://%{url(%{fixtures_dir})}/a_rock-1.0-1.rockspec
+
+EXISTS: a_rock-1.0-1.rockspec
+EXISTS: a_rock-1.0-2.rockspec
diff --git a/spec/quick/pack.q b/spec/quick/pack.q
new file mode 100644
index 0000000..ee44a45
--- /dev/null
+++ b/spec/quick/pack.q
@@ -0,0 +1,128 @@
+SUITE: luarocks pack
+
+================================================================================
+TEST: fails no arguments
+
+RUN: luarocks pack
+EXIT: 1
+
+
+
+================================================================================
+TEST: fails with invalid rockspec
+
+RUN: luarocks pack $%{fixtures_dir}/invalid_say-1.3-1.rockspec
+EXIT: 1
+
+
+
+================================================================================
+TEST: fails with rock that is not installed
+
+RUN: luarocks pack notinstalled
+EXIT: 1
+
+
+
+================================================================================
+TEST: fails with non existing path
+
+RUN: luarocks pack /notexists/notinstalled
+EXIT: 1
+
+
+
+================================================================================
+TEST: packs latest version version of rock
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-1.0-1.rockspec
+RUN: luarocks build myrock-2.0-1.rockspec --keep
+RUN: luarocks pack myrock
+
+EXISTS: myrock-2.0-1.all.rock
+
+
+
+================================================================================
+TEST: --sign #gpg
+PENDING: true
+
+FILE: myrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: myrock-2.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+package = "myrock"
+version = "2.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/rock.lua"
+}
+build = {
+ modules = { rock = "rock.lua" }
+}
+--------------------------------------------------------------------------------
+
+FILE: rock.lua
+--------------------------------------------------------------------------------
+return "hello"
+--------------------------------------------------------------------------------
+
+RUN: luarocks build myrock-1.0-1.rockspec
+RUN: luarocks build myrock-2.0-1.rockspec --keep
+RUN: luarocks pack myrock --sign
+
+EXISTS: myrock-2.0-1.all.rock
+EXISTS: myrock-2.0-1.all.rock.asc
+
+
+
+================================================================================
+TEST: packs a namespaced rock #namespaces
+
+RUN: luarocks build a_user/a_rock --server=%{fixtures_dir}/a_repo
+RUN: luarocks build a_rock --keep --server=%{fixtures_dir}/a_repo
+RUN: luarocks pack a_user/a_rock
+
+EXISTS: a_rock-2.0-1.all.rock
diff --git a/spec/quick/path.q b/spec/quick/path.q
new file mode 100644
index 0000000..77fc188
--- /dev/null
+++ b/spec/quick/path.q
@@ -0,0 +1,22 @@
+================================================================================
+TEST: luarocks path: --project-tree
+
+
+RUN: luarocks path --project-tree=foo
+STDOUT:
+--------------------------------------------------------------------------------
+%{path(foo/share/lua/%{lua_version}/?.lua)}
+%{path(foo/share/lua/%{lua_version}/?/init.lua)}
+--------------------------------------------------------------------------------
+
+RUN: luarocks path --project-tree=foo --tree=bar
+NOT_STDOUT:
+--------------------------------------------------------------------------------
+%{path(foo/share/lua/%{lua_version}/?.lua)}
+%{path(foo/share/lua/%{lua_version}/?/init.lua)}
+--------------------------------------------------------------------------------
+STDOUT:
+--------------------------------------------------------------------------------
+%{path(bar/share/lua/%{lua_version}/?.lua)}
+%{path(bar/share/lua/%{lua_version}/?/init.lua)}
+--------------------------------------------------------------------------------
diff --git a/spec/quick/purge.q b/spec/quick/purge.q
new file mode 100644
index 0000000..1fb6129
--- /dev/null
+++ b/spec/quick/purge.q
@@ -0,0 +1,103 @@
+SUITE: luarocks purge
+
+================================================================================
+TEST: needs a --tree argument
+RUN: luarocks purge
+EXIT: 1
+
+================================================================================
+TEST: missing tree
+RUN: luarocks purge --tree=missing-tree
+EXIT: 1
+
+================================================================================
+TEST: missing --tree argument
+RUN: luarocks purge --tree=
+EXIT: 1
+
+
+================================================================================
+TEST: runs
+
+FILE: testrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "testrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/testrock.lua"
+}
+dependencies = {
+ "a_rock >= 0.8"
+}
+build = {
+ type = "builtin",
+ modules = {
+ testrock = "testrock.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: testrock.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build --only-server=%{fixtures_dir}/a_repo testrock-1.0-1.rockspec
+
+EXISTS: %{testing_sys_rocks}/testrock
+EXISTS: %{testing_sys_rocks}/a_rock
+
+RUN: luarocks purge --tree=%{testing_sys_tree}
+
+NOT_EXISTS: %{testing_sys_rocks}/testrock
+NOT_EXISTS: %{testing_sys_rocks}/a_rock
+
+
+
+================================================================================
+TEST: works with missing files
+
+FILE: testrock-1.0-1.rockspec
+--------------------------------------------------------------------------------
+package = "testrock"
+version = "1.0-1"
+source = {
+ url = "file://%{url(%{tmpdir})}/testrock.lua"
+}
+dependencies = {
+ "a_rock >= 0.8"
+}
+build = {
+ type = "builtin",
+ modules = {
+ testrock = "testrock.lua"
+ }
+}
+--------------------------------------------------------------------------------
+
+FILE: testrock.lua
+--------------------------------------------------------------------------------
+return {}
+--------------------------------------------------------------------------------
+
+RUN: luarocks build --only-server=%{fixtures_dir}/a_repo testrock-1.0-1.rockspec
+
+RMDIR: %{testing_sys_tree}/share/lua/%{lua_version}/testrock
+
+RUN: luarocks purge --tree=%{testing_sys_tree}
+
+NOT_EXISTS: %{testing_sys_rocks}/testrock
+NOT_EXISTS: %{testing_sys_rocks}/a_rock
+
+
+
+================================================================================
+TEST: --old-versions
+
+RUN: luarocks install --only-server=%{fixtures_dir}/a_repo a_rock 2.0
+RUN: luarocks install --only-server=%{fixtures_dir}/a_repo a_rock 1.0 --keep
+
+RUN: luarocks purge --old-versions --tree=%{testing_sys_tree}
+
+EXISTS: %{testing_sys_rocks}/a_rock/2.0-1
+NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1
diff --git a/spec/quick/test.q b/spec/quick/test.q
new file mode 100644
index 0000000..cb5ccd7
--- /dev/null
+++ b/spec/quick/test.q
@@ -0,0 +1,51 @@
+================================================================================
+TEST: luarocks test: handle if test.command is not a string
+
+Regression test for #1055.
+
+FILE: example-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+source = {
+ url = "",
+}
+package = "example"
+version = "1.0-1"
+test = {
+ type = "command",
+ command = {"./unit.lua"},
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks test
+EXIT: 1
+STDERR:
+--------------------------------------------------------------------------------
+'command' expects a string
+--------------------------------------------------------------------------------
+
+
+
+================================================================================
+TEST: luarocks test: handle if test.script is not a string
+
+FILE: example-1.0-1.rockspec
+--------------------------------------------------------------------------------
+rockspec_format = "3.0"
+source = {
+ url = "",
+}
+package = "example"
+version = "1.0-1"
+test = {
+ type = "command",
+ script = {"./unit.lua"},
+}
+--------------------------------------------------------------------------------
+
+RUN: luarocks test
+EXIT: 1
+STDERR:
+--------------------------------------------------------------------------------
+'script' expects a string
+--------------------------------------------------------------------------------
diff --git a/spec/quick_spec.lua b/spec/quick_spec.lua
new file mode 100644
index 0000000..c2d8bb5
--- /dev/null
+++ b/spec/quick_spec.lua
@@ -0,0 +1,22 @@
+local lfs = require("lfs")
+local test_env = require("spec.util.test_env")
+local quick = require("spec.util.quick")
+
+describe("quick tests: #quick", function()
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ local spec_quick = test_env.testing_paths.spec_dir .. "/quick"
+ for f in lfs.dir(spec_quick) do
+ if f:match("%.q$") then
+ local tests = quick.compile(spec_quick .. "/" .. f, getfenv and getfenv() or _ENV)
+ for _, t in ipairs(tests) do
+ if not t.pending then
+ it(t.name, t.fn)
+ end
+ end
+ end
+ end
+end)
+
diff --git a/spec/refresh_cache_spec.lua b/spec/refresh_cache_spec.lua
new file mode 100644
index 0000000..73ba9a9
--- /dev/null
+++ b/spec/refresh_cache_spec.lua
@@ -0,0 +1,13 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+
+describe("luarocks-admin refresh_cache #integration", function()
+
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ it("runs #ssh", function()
+ assert.is_true(run.luarocks_admin_bool("--server=testing refresh_cache"))
+ end)
+end)
diff --git a/spec/remove_spec.lua b/spec/remove_spec.lua
new file mode 100644
index 0000000..3bcfbb2
--- /dev/null
+++ b/spec/remove_spec.lua
@@ -0,0 +1,129 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local env_variables = test_env.env_variables
+local V = test_env.V
+local P = test_env.P
+
+local extra_rocks = {
+ "/abelhas-1.1-1.src.rock",
+ "/copas-${COPAS}.src.rock",
+ "/coxpcall-1.16.0-1.src.rock",
+ "/coxpcall-1.16.0-1.rockspec",
+ "/luafilesystem-${LUAFILESYSTEM}.src.rock",
+ "/luafilesystem-${LUAFILESYSTEM_OLD}.src.rock",
+}
+
+describe("luarocks remove #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ describe("basic tests", function()
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("remove"))
+ end)
+
+ it("invalid rock", function()
+ assert.is_false(run.luarocks_bool("remove invalid.rock"))
+ end)
+
+ it("missing rock", function()
+ assert.is_false(run.luarocks_bool("remove missing_rock"))
+ end)
+
+ it("invalid argument", function()
+ assert.is_false(run.luarocks_bool("remove luacov --deps-mode"))
+ end)
+
+ it("built abelhas", function()
+ assert.is_true(run.luarocks_bool("build abelhas 1.1"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/abelhas"))
+ assert.is_true(run.luarocks_bool("remove abelhas 1.1"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/abelhas"))
+ end)
+
+ it("built abelhas with uppercase name", function()
+ assert.is_true(run.luarocks_bool("build abelhas 1.1"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/abelhas"))
+ assert.is_true(run.luarocks_bool("remove Abelhas 1.1"))
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/abelhas"))
+ end)
+ end)
+
+ describe("more complex tests", function()
+ before_each(function()
+ assert.is.truthy(test_env.need_rock("coxpcall"))
+ end)
+
+ it("fail, break dependencies", function()
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/coxpcall"))
+ assert.is_true(run.luarocks_bool("build copas"))
+
+ assert.is_false(run.luarocks_bool("remove coxpcall"))
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/coxpcall"))
+ end)
+
+ it("force", function()
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/coxpcall"))
+ assert.is_true(run.luarocks_bool("build copas"))
+
+ local output = run.luarocks("remove --force coxpcall")
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/coxpcall"))
+ assert.is.truthy(output:find("Checking stability of dependencies"))
+ end)
+
+ it("force fast", function()
+ assert.is.truthy(lfs.attributes(testing_paths.testing_sys_rocks .. "/coxpcall"))
+ assert.is_true(run.luarocks_bool("build copas"))
+
+ local output = run.luarocks("remove --force-fast coxpcall")
+ assert.is.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/coxpcall"))
+ assert.is.falsy(output:find("Checking stability of dependencies"))
+ end)
+
+ it("restores old versions", function()
+ local libdir = P(testing_paths.testing_sys_tree .. "/lib/lua/"..env_variables.LUA_VERSION)
+
+ assert.is_true(run.luarocks_bool("install luafilesystem ${LUAFILESYSTEM_OLD_V}"))
+ assert.is.truthy(lfs.attributes(libdir.."/lfs."..test_env.lib_extension))
+
+ if test_env.TEST_TARGET_OS ~= "windows" then
+ local fd = io.open(libdir.."/lfs."..test_env.lib_extension, "r")
+ assert(fd:read("*a"):match(V"LuaFileSystem ${LUAFILESYSTEM_OLD_V}", 1, true))
+ fd:close()
+ end
+
+ local suffix = (V"${LUAFILESYSTEM_OLD}"):gsub("[%.%-]", "_")
+
+ assert.is_true(run.luarocks_bool("install luafilesystem ${LUAFILESYSTEM_V} --keep"))
+ assert.is.truthy(lfs.attributes(libdir.."/lfs."..test_env.lib_extension))
+ assert.is.truthy(lfs.attributes(libdir.."/luafilesystem_"..suffix.."-lfs."..test_env.lib_extension))
+
+ if test_env.TEST_TARGET_OS ~= "windows" then
+ local fd = io.open(libdir.."/lfs."..test_env.lib_extension, "r")
+ assert(fd:read("*a"):match(V"LuaFileSystem ${LUAFILESYSTEM_V}", 1, true))
+ fd:close()
+ end
+
+ assert.is_true(run.luarocks_bool("remove luafilesystem ${LUAFILESYSTEM_V}"))
+ assert.is.truthy(lfs.attributes(libdir.."/lfs."..test_env.lib_extension))
+
+ if test_env.TEST_TARGET_OS ~= "windows" then
+ local fd = io.open(libdir.."/lfs."..test_env.lib_extension, "r")
+ assert(fd:read("*a"):match(V"LuaFileSystem ${LUAFILESYSTEM_OLD_V}", 1, true))
+ fd:close()
+ end
+ end)
+ end)
+
+ it("#admin remove #ssh", function()
+ assert.is_true(run.luarocks_admin_bool("--server=testing remove coxpcall-1.16.0-1.src.rock"))
+ end)
+
+ it("#admin remove missing", function()
+ assert.is_false(run.luarocks_admin_bool("--server=testing remove"))
+ end)
+end)
diff --git a/spec/search_spec.lua b/spec/search_spec.lua
new file mode 100644
index 0000000..6d71e00
--- /dev/null
+++ b/spec/search_spec.lua
@@ -0,0 +1,33 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+
+local extra_rocks = {
+"/lzlib-0.4.1.53-1.src.rock"
+}
+
+describe("luarocks search #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("search"))
+ end)
+
+ it("zlib", function()
+ assert.is_true(run.luarocks_bool("search zlib"))
+ end)
+
+ it("zlib 1.1", function()
+ assert.is_true(run.luarocks_bool("search zlib 1.1"))
+ end)
+
+ it("missing rock", function()
+ assert.is_true(run.luarocks_bool("search missing_rock"))
+ end)
+
+ it("with flag all", function()
+ assert.is_true(run.luarocks_bool("search --all"))
+ end)
+end)
diff --git a/spec/show_spec.lua b/spec/show_spec.lua
new file mode 100644
index 0000000..cd34b5a
--- /dev/null
+++ b/spec/show_spec.lua
@@ -0,0 +1,105 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+describe("luarocks show #integration", function()
+
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("show"))
+ end)
+
+ describe("basic tests with flags", function()
+ it("invalid", function()
+ assert.is_false(run.luarocks_bool("show invalid"))
+ end)
+
+ it("luacov", function()
+ local output = run.luarocks("show luacov")
+ assert.is.truthy(output:match("LuaCov"))
+ end)
+
+ it("luacov with uppercase name", function()
+ local output = run.luarocks("show LuaCov")
+ assert.is.truthy(output:match("LuaCov"))
+ end)
+
+ it("modules of luacov", function()
+ local output = run.luarocks("show --modules luacov")
+ assert.match("luacov.*luacov.defaults.*luacov.reporter.*luacov.reporter.default.*luacov.runner.*luacov.stats.*luacov.tick", output)
+ end)
+
+ it("--deps", function()
+ assert(run.luarocks_bool("build has_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ local output = run.luarocks("show --deps has_namespaced_dep")
+ assert.match("a_user/a_rock", output)
+ end)
+
+ it("list dependencies", function()
+ assert(run.luarocks_bool("build has_namespaced_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ local output = run.luarocks("show has_namespaced_dep")
+ assert.match("a_user/a_rock.*2.0", output)
+ end)
+
+ it("rockspec of luacov", function()
+ local output = run.luarocks("show --rockspec luacov")
+ assert.is.truthy(output:match("luacov--0.15.0--1.rockspec"))
+ end)
+
+ it("mversion of luacov", function()
+ local output = run.luarocks("show --mversion luacov")
+ assert.is.truthy(output:match("0.15.0--1"))
+ end)
+
+ it("rock tree of luacov", function()
+ local output = run.luarocks("show --rock-tree luacov")
+ end)
+
+ it("rock directory of luacov", function()
+ local output = run.luarocks("show --rock-dir luacov")
+ end)
+
+ it("issues URL of luacov", function()
+ local output = run.luarocks("show --issues luacov")
+ end)
+
+ it("labels of luacov", function()
+ local output = run.luarocks("show --labels luacov")
+ end)
+ end)
+
+ it("old version of luacov", function()
+ run.luarocks("install luacov 0.15.0")
+ run.luarocks_bool("show luacov 0.15.0")
+ end)
+
+ it("can find by substring", function()
+ assert(run.luarocks_bool("install has_build_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.match("a_build_dep", run.luarocks("show has_"))
+ end)
+
+ it("fails when substring matches multiple", function()
+ assert(run.luarocks_bool("install has_build_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert(run.luarocks_bool("install a_build_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.match("multiple installed packages match the name 'dep'", run.luarocks("show dep"))
+ end)
+
+ it("shows #build_dependencies", function()
+ assert(run.luarocks_bool("install has_build_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.match("a_build_dep", run.luarocks("show has_build_dep"))
+ end)
+
+ it("gets #build_dependencies via --build-deps", function()
+ assert(run.luarocks_bool("install has_build_dep --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.match("a_build_dep", run.luarocks("show has_build_dep --build-deps"))
+ end)
+
+ it("shows #namespaces via --rock-namespace", function()
+ assert(run.luarocks_bool("build a_user/a_rock --server=" .. testing_paths.fixtures_dir .. "/a_repo" ))
+ assert.match("a_user", run.luarocks("show a_rock --rock-namespace"))
+ end)
+
+end)
diff --git a/spec/test_spec.lua b/spec/test_spec.lua
new file mode 100644
index 0000000..bc5f047
--- /dev/null
+++ b/spec/test_spec.lua
@@ -0,0 +1,93 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+
+local extra_rocks = {
+ "/busted-2.2.0-1.src.rock",
+ "/lua_cliargs-3.0-1.src.rock",
+ "/luafilesystem-${LUAFILESYSTEM}.src.rock",
+ "/luasystem-0.2.1-0.src.rock",
+ "/dkjson-${DKJSON}.src.rock",
+ "/say-1.4.1-3.src.rock",
+ "/luassert-1.9.0-1.src.rock",
+ "/penlight-1.13.1-1.src.rock",
+ "/lua-term-0.8-1.rockspec",
+ "/mediator_lua-1.1.2-0.rockspec",
+}
+
+describe("luarocks test #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("fails with no flags/arguments", function()
+ finally(function()
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("empty")
+ end)
+ assert(lfs.mkdir("empty"))
+ assert(lfs.chdir("empty"))
+ assert.is_false(run.luarocks_bool("test"))
+ end)
+
+ describe("busted backend", function()
+
+ it("with rockspec, installing busted", function()
+ finally(function()
+ -- delete downloaded and unpacked files
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("busted_project-0.1-1")
+ os.remove("busted_project-0.1-1.src.rock")
+ end)
+
+ -- make luassert
+ assert.is_true(run.luarocks_bool("download --server="..testing_paths.fixtures_repo_dir.." busted_project 0.1-1"))
+ assert.is_true(run.luarocks_bool("unpack busted_project-0.1-1.src.rock"))
+ lfs.chdir("busted_project-0.1-1/busted_project")
+ assert.is_true(run.luarocks_bool("make"))
+ local output = run.luarocks("test")
+ print(output)
+ -- Assert that busted ran, whether successfully or not
+ assert.match("%d+ success.* / %d+ failure.* / %d+ error.* / %d+ pending", output)
+ end)
+
+ it("prepare", function()
+ finally(function()
+ -- delete downloaded and unpacked files
+ lfs.chdir(testing_paths.testrun_dir)
+ test_env.remove_dir("busted_project-0.1-1")
+ os.remove("busted_project-0.1-1.src.rock")
+ end)
+
+ -- make luassert
+ assert.is_true(run.luarocks_bool("download --server="..testing_paths.fixtures_repo_dir.." busted_project 0.1-1"))
+ assert.is_true(run.luarocks_bool("unpack busted_project-0.1-1.src.rock"))
+ lfs.chdir("busted_project-0.1-1/busted_project")
+ assert.is_true(run.luarocks_bool("make"))
+
+ run.luarocks_bool("remove busted")
+ local prepareOutput = run.luarocks_bool("test --prepare")
+ assert.is_true(run.luarocks_bool("show busted"))
+
+ -- Assert that "test --prepare" run successfully
+ assert.is_true(prepareOutput)
+
+ local output = run.luarocks("test")
+ assert.not_match(tostring(prepareOutput), output)
+
+ end)
+ end)
+
+ describe("command backend", function()
+ describe("prepare", function()
+ it("works with non-busted rocks", function()
+ write_file("test.lua", "", finally)
+ assert.is_true(run.luarocks_bool("test --prepare " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec"))
+ end)
+ end)
+ end)
+end)
+
diff --git a/spec/unit/build_spec.lua b/spec/unit/build_spec.lua
new file mode 100644
index 0000000..e8f1394
--- /dev/null
+++ b/spec/unit/build_spec.lua
@@ -0,0 +1,365 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local get_tmp_path = test_env.get_tmp_path
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+local P = test_env.P
+
+test_env.setup_specs()
+local cfg = require("luarocks.core.cfg")
+local deps = require("luarocks.deps")
+local fs = require("luarocks.fs")
+local path = require("luarocks.path")
+local rockspecs = require("luarocks.rockspecs")
+local build_builtin = require("luarocks.build.builtin")
+
+local c_module_source = [[
+ #include <lua.h>
+ #include <lauxlib.h>
+
+ int luaopen_c_module(lua_State* L) {
+ lua_newtable(L);
+ lua_pushinteger(L, 1);
+ lua_setfield(L, -2, "c_module");
+ return 1;
+ }
+]]
+
+describe("LuaRocks build #unit", function()
+ local runner
+
+ lazy_setup(function()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ cfg.init()
+ fs.init()
+ deps.check_lua_incdir(cfg.variables)
+ deps.check_lua_libdir(cfg.variables)
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("build.builtin", function()
+ it("builtin auto installs files in lua subdir", function()
+ test_env.run_in_tmp(function(tmpdir)
+ lfs.mkdir("lua")
+ write_file("lua_module-1.0-1.rockspec", [[
+ package = "lua_module"
+ version = "1.0-1"
+ source = {
+ url = "http://example.com/lua_module"
+ }
+ build = {
+ type = "builtin",
+ modules = {}
+ }
+ ]], finally)
+ write_file("lua/lua_module.lua", "return 123", finally)
+
+ assert.is_true(run.luarocks_bool("build"))
+ assert.match("[\\/]lua_module%.lua", run.luarocks("show lua_module"))
+ end, finally)
+ end)
+
+ describe("builtin.autodetect_modules", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ tmpdir = get_tmp_path()
+ olddir = lfs.currentdir()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+ fs.change_dir(tmpdir)
+ end)
+
+ after_each(function()
+ if olddir then
+ lfs.chdir(olddir)
+ fs.change_dir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ local libs = { "foo1", "foo2" }
+ local incdirs = { "$(FOO1_INCDIR)", "$(FOO2_INCDIR)" }
+ local libdirs = { "$(FOO1_LIBDIR)", "$(FOO2_LIBDIR)" }
+
+ it("returns a table of the modules having as location the current directory", function()
+ write_file("module1.lua", "", finally)
+ write_file("module2.c", "", finally)
+ write_file("module3.c", "int luaopen_my_module()", finally)
+ write_file("test.lua", "", finally)
+ write_file("tests.lua", "", finally)
+
+ local modules = build_builtin.autodetect_modules(libs, incdirs, libdirs)
+ assert.same(modules, {
+ module1 = "module1.lua",
+ module2 = {
+ sources = "module2.c",
+ libraries = libs,
+ incdirs = incdirs,
+ libdirs = libdirs
+ },
+ my_module = {
+ sources = "module3.c",
+ libraries = libs,
+ incdirs = incdirs,
+ libdirs = libdirs
+ }
+ })
+ end)
+
+ local test_with_location = function(location)
+ lfs.mkdir(location)
+ lfs.mkdir(location .. "/dir1")
+ lfs.mkdir(location .. "/dir1/dir2")
+
+ write_file(location .. "/module1.lua", "", finally)
+ write_file(location .. "/dir1/module2.c", "", finally)
+ write_file(location .. "/dir1/dir2/module3.c", "int luaopen_my_module()", finally)
+ write_file(location .. "/test.lua", "", finally)
+ write_file(location .. "/tests.lua", "", finally)
+
+ local modules = build_builtin.autodetect_modules(libs, incdirs, libdirs)
+ assert.same(modules, {
+ module1 = P(location .. "/module1.lua"),
+ ["dir1.module2"] = {
+ sources = P(location .. "/dir1/module2.c"),
+ libraries = libs,
+ incdirs = incdirs,
+ libdirs = libdirs
+ },
+ my_module = {
+ sources = P(location .. "/dir1/dir2/module3.c"),
+ libraries = libs,
+ incdirs = incdirs,
+ libdirs = libdirs
+ }
+ })
+
+ lfs.rmdir(location .. "/dir1/dir2")
+ lfs.rmdir(location .. "/dir1")
+ lfs.rmdir(location)
+ end
+
+ it("returns a table of the modules having as location the src directory", function()
+ test_with_location("src")
+ end)
+
+ it("returns a table of the modules having as location the lua directory", function()
+ test_with_location("lua")
+ end)
+
+ it("returns as second and third argument tables of the bin files and copy directories", function()
+ lfs.mkdir("doc")
+ lfs.mkdir("docs")
+ lfs.mkdir("samples")
+ lfs.mkdir("tests")
+ lfs.mkdir("bin")
+ write_file("bin/binfile", "", finally)
+
+ local _, install, copy_directories = build_builtin.autodetect_modules({}, {}, {})
+ assert.same(install, { bin = { P"bin/binfile" } })
+ assert.same(copy_directories, { "doc", "docs", "samples", "tests" })
+
+ lfs.rmdir("doc")
+ lfs.rmdir("docs")
+ lfs.rmdir("samples")
+ lfs.rmdir("tests")
+ lfs.rmdir("bin")
+ end)
+ end)
+
+ describe("builtin.run", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ tmpdir = get_tmp_path()
+ olddir = lfs.currentdir()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+ fs.change_dir(tmpdir)
+ path.use_tree(lfs.currentdir())
+ end)
+
+ after_each(function()
+ if olddir then
+ lfs.chdir(olddir)
+ fs.change_dir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("returns false if the rockspec has no build modules and its format does not support autoextraction", function()
+ local rockspec = {
+ package = "test",
+ version = "1.0-1",
+ source = {
+ url = "http://example.com/test"
+ },
+ build = {}
+ }
+
+ rockspecs.from_persisted_table("test-1.0-1.rockspec", rockspec)
+ assert.falsy(build_builtin.run(rockspec))
+ rockspec.rockspec_format = "1.0"
+ assert.falsy(build_builtin.run(rockspec))
+ end)
+
+ it("returns false if lua.h could not be found", function()
+ local rockspec = {
+ package = "c_module",
+ version = "1.0-1",
+ source = {
+ url = "http://example.com/c_module"
+ },
+ build = {
+ type = "builtin",
+ modules = {
+ c_module = "c_module.c"
+ }
+ }
+ }
+ write_file("c_module.c", c_module_source, finally)
+
+ rockspecs.from_persisted_table("c_module-1.0-1.rockspec", rockspec)
+ rockspec.variables = { LUA_INCDIR = "invalid" }
+ assert.falsy(build_builtin.run(rockspec))
+ end)
+
+ it("returns false if the build fails", function()
+ local rockspec = {
+ package = "c_module",
+ version = "1.0-1",
+ source = {
+ url = "http://example.com/c_module"
+ },
+ build = {
+ type = "builtin",
+ modules = {
+ c_module = "c_module.c"
+ }
+ }
+ }
+ write_file("c_module.c", c_module_source .. "invalid", finally)
+
+ rockspecs.from_persisted_table("c_module-1.0-1.rockspec", rockspec)
+ assert.falsy(build_builtin.run(rockspec))
+ end)
+
+ it("returns true if the build succeeds with C module", function()
+ local rockspec = {
+ package = "c_module",
+ version = "1.0-1",
+ source = {
+ url = "http://example.com/c_module"
+ },
+ build = {
+ type = "builtin",
+ modules = {
+ c_module = "c_module.c"
+ }
+ }
+ }
+ write_file("c_module.c", c_module_source, finally)
+
+ rockspecs.from_persisted_table("c_module-1.0-1.rockspec", rockspec)
+ assert.truthy(build_builtin.run(rockspec))
+ assert.truthy(lfs.attributes("lib/luarocks/rocks-" .. test_env.lua_version .. "/c_module/1.0-1/lib/c_module." .. test_env.lib_extension))
+ end)
+
+ it("returns true if the build succeeds with Lua module", function()
+ local rockspec = {
+ rockspec_format = "1.0",
+ package = "test",
+ version = "1.0-1",
+ source = {
+ url = "http://example.com/test"
+ },
+ build = {
+ type = "builtin",
+ modules = {
+ test = "test.lua"
+ }
+ }
+ }
+ write_file("test.lua", "return {}", finally)
+
+ rockspecs.from_persisted_table("test-1.0-1.rockspec", rockspec)
+ assert.truthy(build_builtin.run(rockspec))
+ assert.truthy(lfs.attributes("lib/luarocks/rocks-" .. test_env.lua_version .. "/test/1.0-1/lua/test.lua"))
+ end)
+
+ it("automatically extracts the modules and libraries if they are not given and builds against any external dependencies", function()
+ local fdir = testing_paths.fixtures_dir
+ if test_env.TEST_TARGET_OS == "windows" then
+ if test_env.MINGW then
+ os.execute("gcc -shared -o " .. fdir .. "/libfixturedep.dll -Wl,--out-implib," .. fdir .."/libfixturedep.a " .. fdir .. "/fixturedep.c")
+ else
+ os.execute("cl " .. fdir .. "\\fixturedep.c /link /export:fixturedep_fn /out:" .. fdir .. "\\fixturedep.dll /implib:" .. fdir .. "\\fixturedep.lib")
+ end
+ elseif test_env.TEST_TARGET_OS == "linux" then
+ os.execute("gcc -shared -o " .. fdir .. "/libfixturedep.so " .. fdir .. "/fixturedep.c")
+ elseif test_env.TEST_TARGET_OS == "osx" then
+ os.execute("cc -dynamiclib -o " .. fdir .. "/libfixturedep.dylib " .. fdir .. "/fixturedep.c")
+ end
+
+ local rockspec = {
+ rockspec_format = "3.0",
+ package = "c_module",
+ version = "1.0-1",
+ source = {
+ url = "http://example.com/c_module"
+ },
+ external_dependencies = {
+ FIXTUREDEP = {
+ library = "fixturedep"
+ }
+ },
+ build = {
+ type = "builtin"
+ }
+ }
+ write_file("c_module.c", c_module_source, finally)
+
+ rockspecs.from_persisted_table("c_module-1.0-1.rockspec", rockspec)
+ rockspec.variables["FIXTUREDEP_LIBDIR"] = testing_paths.fixtures_dir
+ assert.truthy(build_builtin.run(rockspec))
+ end)
+
+ it("returns false if any external dependency is missing", function()
+ local rockspec = {
+ rockspec_format = "3.0",
+ package = "c_module",
+ version = "1.0-1",
+ source = {
+ url = "https://example.com/c_module"
+ },
+ external_dependencies = {
+ EXTDEP = {
+ library = "missing"
+ }
+ },
+ build = {
+ type = "builtin"
+ }
+ }
+ write_file("c_module.c", c_module_source, finally)
+
+ rockspecs.from_persisted_table("c_module-1.0-1.rockspec", rockspec)
+ rockspec.variables["EXTDEP_INCDIR"] = lfs.currentdir()
+ rockspec.variables["EXTDEP_LIBDIR"] = lfs.currentdir()
+ assert.falsy(build_builtin.run(rockspec))
+ end)
+ end)
+ end)
+end)
diff --git a/spec/unit/deps_spec.lua b/spec/unit/deps_spec.lua
new file mode 100644
index 0000000..3be80b9
--- /dev/null
+++ b/spec/unit/deps_spec.lua
@@ -0,0 +1,143 @@
+local test_env = require("spec.util.test_env")
+local testing_paths = test_env.testing_paths
+
+local cfg = require("luarocks.core.cfg")
+local deps = require("luarocks.deps")
+local fs = require("luarocks.fs")
+
+describe("LuaRocks deps #unit", function()
+ local runner
+
+ lazy_setup(function()
+ cfg.init()
+ fs.init()
+ deps.check_lua_incdir(cfg.variables)
+ deps.check_lua_libdir(cfg.variables)
+
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("deps", function()
+ describe("deps.autodetect_external_dependencies", function()
+ it("returns false if the given build table has no external dependencies", function()
+ local build_table = {
+ type = "builtin"
+ }
+
+ assert.falsy(deps.autodetect_external_dependencies(build_table))
+ end)
+
+ it("returns a table of the external dependencies found in the given build table", function()
+ local build_table = {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = { "foo1", "foo2" },
+ },
+ module2 = {
+ libraries = "foo3"
+ },
+ }
+ }
+
+ local extdeps = deps.autodetect_external_dependencies(build_table)
+ assert.same(extdeps["FOO1"], { library = "foo1" })
+ assert.same(extdeps["FOO2"], { library = "foo2" })
+ assert.same(extdeps["FOO3"], { library = "foo3" })
+ end)
+
+ it("adds proper include and library dirs to the given build table", function()
+ local build_table
+
+ build_table = {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo"
+ }
+ }
+ }
+ deps.autodetect_external_dependencies(build_table)
+ assert.same(build_table, {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ incdirs = { "$(FOO_INCDIR)" },
+ libdirs = { "$(FOO_LIBDIR)" }
+ }
+ }
+ })
+
+ build_table = {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ incdirs = { "INCDIRS" }
+ }
+ }
+ }
+ deps.autodetect_external_dependencies(build_table)
+ assert.same(build_table, {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ incdirs = { "INCDIRS" },
+ libdirs = { "$(FOO_LIBDIR)" }
+ }
+ }
+ })
+
+ build_table = {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ libdirs = { "LIBDIRS" }
+ }
+ }
+ }
+ deps.autodetect_external_dependencies(build_table)
+ assert.same(build_table, {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ incdirs = { "$(FOO_INCDIR)" },
+ libdirs = { "LIBDIRS" }
+ }
+ }
+ })
+
+ build_table = {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ incdirs = { "INCDIRS" },
+ libdirs = { "LIBDIRS" }
+ }
+ }
+ }
+ deps.autodetect_external_dependencies(build_table)
+ assert.same(build_table, {
+ type = "builtin",
+ modules = {
+ module1 = {
+ libraries = "foo",
+ incdirs = { "INCDIRS" },
+ libdirs = { "LIBDIRS" }
+ }
+ }
+ })
+ end)
+ end)
+ end)
+end)
diff --git a/spec/unit/dir_spec.lua b/spec/unit/dir_spec.lua
new file mode 100644
index 0000000..55dd6e0
--- /dev/null
+++ b/spec/unit/dir_spec.lua
@@ -0,0 +1,70 @@
+local test_env = require("spec.util.test_env")
+local testing_paths = test_env.testing_paths
+local P = test_env.P
+
+test_env.setup_specs()
+local dir = require("luarocks.dir")
+
+describe("luarocks.dir #unit", function()
+ local runner
+
+ lazy_setup(function()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("dir.is_basic_protocol", function()
+ it("checks whether the arguments represent a valid protocol and returns the result of the check", function()
+ assert.truthy(dir.is_basic_protocol("http"))
+ assert.truthy(dir.is_basic_protocol("https"))
+ assert.truthy(dir.is_basic_protocol("ftp"))
+ assert.truthy(dir.is_basic_protocol("file"))
+ assert.falsy(dir.is_basic_protocol("git"))
+ assert.falsy(dir.is_basic_protocol("git+https"))
+ assert.falsy(dir.is_basic_protocol("invalid"))
+ end)
+ end)
+
+ describe("dir.deduce_base_dir", function()
+ it("deduces the base dir from archives", function()
+ assert.are.same("v0.3", dir.deduce_base_dir("https://example.com/hishamhm/lua-compat-5.2/archive/v0.3.zip"))
+ assert.are.same("lua-compat-5.2", dir.deduce_base_dir("https://example.com/hishamhm/lua-compat-5.2.zip"))
+ assert.are.same("lua-compat-5.2", dir.deduce_base_dir("https://example.com/hishamhm/lua-compat-5.2.tar.gz"))
+ assert.are.same("lua-compat-5.2", dir.deduce_base_dir("https://example.com/hishamhm/lua-compat-5.2.tar.bz2"))
+ end)
+ it("returns the basename when not given an archive", function()
+ assert.are.same("parser.moon", dir.deduce_base_dir("git://example.com/Cirru/parser.moon"))
+ assert.are.same("v0.3", dir.deduce_base_dir("https://example.com/hishamhm/lua-compat-5.2/archive/v0.3"))
+ end)
+ end)
+
+ describe("dir.normalize", function()
+ it("converts backslashes and removes trailing slashes", function()
+ assert.are.same(P"/foo/ovo", dir.normalize("\\foo\\ovo\\"))
+ assert.are.same(P"c:/some/dir", dir.normalize("c:\\..\\some\\foo\\..\\dir"))
+ assert.are.same("http://example.com/foo/ovo", dir.normalize("http://example.com/foo\\ovo\\"))
+ end)
+ it("strips unneeded /../ and /./", function()
+ assert.are.same(P"/some/dir/file.txt", dir.normalize("/../../../some/./foo/bar/.././../dir/bla/../file.txt"))
+ assert.are.same(P"/some/dir/file.txt", dir.normalize("/../../../some/./foo/bar/.././../dir/bla/../file.txt"))
+ assert.are.same(P"/some/dir", dir.normalize("/../../../some/./foo/bar/.././../dir/./some/subdir/../.."))
+ assert.are.same(P"/some/dir", dir.normalize("/../../../some/./foo/bar/.././../dir/./."))
+ end)
+ it("respects relative paths", function()
+ assert.are.same(P".", dir.normalize("."))
+ assert.are.same(P"boo", dir.normalize("./boo"))
+ assert.are.same(P"/boo", dir.normalize("/./boo"))
+ assert.are.same(P"../../../../boo", dir.normalize("../../../hello/world/../../../boo"))
+ end)
+ it("respects root directory", function()
+ assert.are.same(P"/", dir.normalize("/"))
+ assert.are.same(P"/", dir.normalize("/////"))
+ assert.are.same(P"/", dir.normalize("/a/b/.././../c/./../../"))
+ end)
+ end)
+
+end)
diff --git a/spec/unit/fetch_spec.lua b/spec/unit/fetch_spec.lua
new file mode 100644
index 0000000..bea50d7
--- /dev/null
+++ b/spec/unit/fetch_spec.lua
@@ -0,0 +1,486 @@
+local test_env = require("spec.util.test_env")
+
+test_env.setup_specs()
+local cfg = require("luarocks.core.cfg")
+local fetch = require("luarocks.fetch")
+local fs = require("luarocks.fs")
+local dir = require("luarocks.dir")
+local path = require("luarocks.path")
+local rockspecs = require("luarocks.rockspecs")
+local lfs = require("lfs")
+local get_tmp_path = test_env.get_tmp_path
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+local P = test_env.P
+
+describe("luarocks fetch #unit", function()
+ local are_same_files = function(file1, file2)
+ return file1 == file2 or lfs.attributes(file1).ino == lfs.attributes(file2).ino
+ end
+
+ local runner
+
+ lazy_setup(function()
+ cfg.init()
+ fs.init()
+
+ -- mock network access
+ fs.download = function(url, destfile)
+ local mockfile = P(url:gsub("http://localhost:8080/file", testing_paths.fixtures_dir))
+ if not destfile then
+ destfile = dir.base_name(mockfile)
+ end
+ destfile = fs.absolute_name(destfile)
+
+ local fdr = io.open(mockfile, "rb")
+ if not fdr then
+ return nil, "mock failed opening for reading"
+ end
+
+ local fdw = io.open(destfile, "wb")
+ if not fdr then
+ return nil, "mock failed opening for writing"
+ end
+
+ local data = fdr:read("*a")
+ if not data then
+ return nil, "mock failed reading"
+ end
+
+ local ok = fdw:write(data)
+ if not ok then
+ return nil, "mock failed writing"
+ end
+
+ fdr:close()
+ fdw:close()
+
+ return true, destfile
+ end
+
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+
+ describe("fetch.fetch_url", function()
+
+ it("fetches the url argument and returns the absolute path of the fetched file", function()
+ test_env.run_in_tmp(function()
+ local fetchedfile, err = fetch.fetch_url("http://localhost:8080/file/a_rock.lua")
+ assert(fetchedfile, err)
+ assert.truthy(are_same_files(fetchedfile, lfs.currentdir() .. "/a_rock.lua"))
+ local fd = assert(io.open(fetchedfile, "r"))
+ local fetchedcontent = assert(fd:read("*a"))
+ fd:close()
+ fd = assert(io.open(testing_paths.fixtures_dir .. "/a_rock.lua", "r"))
+ local filecontent = assert(fd:read("*a"))
+ fd:close()
+ assert.same(fetchedcontent, filecontent)
+ end, finally)
+ end)
+
+ it("returns the absolute path of the filename argument if the url represents a file", function()
+ test_env.run_in_tmp(function()
+ write_file("test.lua", "return {}")
+
+ local file, err = fetch.fetch_url("file://test.lua")
+ assert.truthy(file, err)
+ assert.truthy(are_same_files(file, lfs.currentdir() .. "/test.lua"))
+ fs.pop_dir()
+ end, finally)
+ end)
+
+ it("fails if local path is invalid and returns a helpful hint for relative paths", function()
+ test_env.run_in_tmp(function()
+ local ok, err = fetch.fetch_url("file://boo.lua")
+ assert.falsy(ok)
+ assert.match("note that given path in rockspec is not absolute: file://boo.lua", err)
+ end, finally)
+ end)
+
+ it("returns false and does nothing if the url argument contains a nonexistent file", function()
+ assert.falsy(fetch.fetch_url("http://localhost:8080/file/nonexistent"))
+ end)
+
+ it("returns false and does nothing if the url argument is invalid", function()
+ assert.falsy(fetch.fetch_url("invalid://url", "file"))
+ end)
+ end)
+
+ describe("fetch.fetch_url_at_temp_dir", function()
+
+ it("returns the absolute path and the parent directory of the file specified by the url", function()
+ test_env.run_in_tmp(function(tmpdir)
+ local tmpfile = tmpdir .. "/tmpfile"
+ assert(io.open(tmpfile, "w"))
+ local pathname, dirname = fetch.fetch_url_at_temp_dir("file://" .. tmpfile, "test")
+ assert.truthy(are_same_files(tmpfile, pathname))
+ assert.truthy(are_same_files(tmpdir, dirname))
+ end, finally)
+ end)
+
+ it("returns true and fetches the url into a temporary dir", function()
+ test_env.run_in_tmp(function()
+ local fetchedfile, tmpdir = fetch.fetch_url_at_temp_dir("http://localhost:8080/file/a_rock.lua", "test")
+ assert(fetchedfile, tmpdir)
+ assert.truthy(are_same_files(fetchedfile, tmpdir .. "/a_rock.lua"))
+ local fd = assert(io.open(fetchedfile, "r"))
+ local fetchedcontent = assert(fd:read("*a"))
+ fd:close()
+ fd = assert(io.open(testing_paths.fixtures_dir .. "/a_rock.lua", "r"))
+ local filecontent = assert(fd:read("*a"))
+ fd:close()
+ assert.same(fetchedcontent, filecontent)
+ end, finally)
+ end)
+
+ it("returns true and fetches the url into a temporary dir with custom filename", function()
+ test_env.run_in_tmp(function()
+ local fetchedfile, tmpdir = fetch.fetch_url_at_temp_dir("http://localhost:8080/file/a_rock.lua", "test", "my_a_rock.lua")
+ assert(fetchedfile, tmpdir)
+ assert.truthy(are_same_files(fetchedfile, tmpdir .. "/my_a_rock.lua"))
+ assert.truthy(string.find(tmpdir, "test"))
+ local fd = assert(io.open(fetchedfile, "r"))
+ local fetchedcontent = assert(fd:read("*a"))
+ fd:close()
+ fd = assert(io.open(testing_paths.fixtures_dir .. "/a_rock.lua", "r"))
+ local filecontent = assert(fd:read("*a"))
+ fd:close()
+ assert.same(fetchedcontent, filecontent)
+ end, finally)
+ end)
+
+ it("returns false and does nothing if the file specified in the url is nonexistent", function()
+ assert.falsy(fetch.fetch_url_at_temp_dir("file://nonexistent", "test"))
+ assert.falsy(fetch.fetch_url_at_temp_dir("http://localhost:8080/file/nonexistent", "test"))
+ end)
+
+ it("returns false and does nothing if the url is invalid", function()
+ assert.falsy(fetch.fetch_url_at_temp_dir("url://invalid", "test"))
+ end)
+ end)
+
+ describe("fetch.find_base_dir", function()
+ it("extracts the archive given by the file argument and returns the inferred and the actual root directory in the archive", function()
+ test_env.run_in_tmp(function()
+ local url = "http://localhost:8080/file/an_upstream_tarball-0.1.tar.gz"
+ local file, tmpdir = assert(fetch.fetch_url_at_temp_dir(url, "test"))
+ local inferreddir, founddir = fetch.find_base_dir(file, tmpdir, url)
+ assert.truthy(are_same_files(inferreddir, founddir))
+ assert.truthy(lfs.attributes(tmpdir .. "/" .. founddir))
+ end, finally)
+ end)
+
+ it("extracts the archive given by the file argument with given base directory and returns the inferred and the actual root directory in the archive", function()
+ test_env.run_in_tmp(function()
+ local url = "http://localhost:8080/file/an_upstream_tarball-0.1.tar.gz"
+ local file, tmpdir = assert(fetch.fetch_url_at_temp_dir(url, "test"))
+ local inferreddir, founddir = fetch.find_base_dir(file, tmpdir, url, "basedir")
+ assert.truthy(are_same_files(inferreddir, "basedir"))
+ assert.truthy(are_same_files(founddir, "an_upstream_tarball-0.1"))
+ assert.truthy(lfs.attributes(tmpdir .. "/" .. founddir))
+ end, finally)
+ end)
+
+ it("returns false and does nothing if the temporary directory doesn't exist", function()
+ assert.falsy(fetch.find_base_dir("file", "nonexistent", "url"))
+ end)
+ end)
+
+ describe("fetch.fetch_and_unpack_rock", function()
+
+ it("unpacks the rock file from the url and returns its resulting temporary parent directory", function()
+ test_env.run_in_tmp(function()
+ local tmpdir = fetch.fetch_and_unpack_rock("http://localhost:8080/file/a_rock-1.0-1.src.rock")
+ assert.truthy(string.find(tmpdir, "a_rock%-1%.0%-1"))
+ assert.truthy(lfs.attributes(tmpdir .. "/a_rock-1.0-1.rockspec"))
+ assert.truthy(lfs.attributes(tmpdir .. "/a_rock.lua"))
+ end, finally)
+ end)
+
+ it("unpacks the rock file from the url with custom unpacking directory", function()
+ test_env.run_in_tmp(function()
+ local tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ local resultingdir = fetch.fetch_and_unpack_rock("http://localhost:8080/file/a_rock-1.0-1.src.rock", tmpdir)
+ assert.truthy(are_same_files(resultingdir, tmpdir))
+ assert.truthy(lfs.attributes(resultingdir .. "/a_rock-1.0-1.rockspec"))
+ assert.truthy(lfs.attributes(resultingdir .. "/a_rock.lua"))
+ end, finally)
+ end)
+
+ it("does nothing if the url doesn't represent a rock file", function()
+ assert.falsy(pcall(fetch.fetch_and_unpack_rock, "http://localhost:8080/file/a_rock.lua"))
+ end)
+
+ it("does nothing if the rock file url is invalid", function()
+ assert.falsy(pcall(fetch.fetch_and_unpack_rock, "url://invalid"))
+ end)
+
+ it("does nothing if the rock file url represents a nonexistent file", function()
+ assert.falsy(pcall(fetch.fetch_and_unpack_rock, "url://invalid"))
+ assert.falsy(pcall(fetch.fetch_and_unpack_rock, "http://localhost:8080/file/nonexistent"))
+ end)
+ end)
+
+ describe("fetch.load_local_rockspec", function()
+ it("returns a table representing the rockspec from the given file skipping some checks if the quick argument is enabled", function()
+ test_env.run_in_tmp(function()
+ local rockspec = fetch.load_local_rockspec(testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec", true)
+ assert.same(rockspec.name, "a_rock")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.source.url, "http://localhost:8080/file/a_rock.lua")
+ assert.same(rockspec.description, { summary = "An example rockspec" })
+
+ write_file("missing_mandatory_field-1.0-1.rockspec", [[
+ package="missing_mandatory_field"
+ version="1.0-1"
+ source = {
+ url = "http://example.com/foo.tar.gz"
+ }
+ ]])
+ rockspec = fetch.load_local_rockspec("missing_mandatory_field-1.0-1.rockspec", true)
+ assert.same(rockspec.name, "missing_mandatory_field")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.source.url, "http://example.com/foo.tar.gz")
+
+ write_file("unknown_field-1.0-1.rockspec", [[
+ package="unknown_field"
+ version="1.0-1"
+ source = {
+ url = "http://example.com/foo.tar.gz"
+ }
+ unknown="foo"
+ ]])
+ rockspec = fetch.load_local_rockspec("unknown_field-1.0-1.rockspec", true)
+ assert.same(rockspec.name, "unknown_field")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.source.url, "http://example.com/foo.tar.gz")
+
+ -- The previous calls fail if the detailed checking is done
+ path.use_tree(testing_paths.testing_tree)
+ assert.falsy(fetch.load_local_rockspec("missing_mandatory_field-1.0-1.rockspec"))
+ assert.falsy(fetch.load_local_rockspec("unknown_field-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("returns a table representing the rockspec from the given file", function()
+ test_env.run_in_tmp(function()
+ path.use_tree(testing_paths.testing_tree)
+ local rockspec = fetch.load_local_rockspec(testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec")
+ assert.same(rockspec.name, "a_rock")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.description, { summary = "An example rockspec" })
+ assert.same(rockspec.source.url, "http://localhost:8080/file/a_rock.lua")
+ end, finally)
+ end)
+
+ it("returns false if the rockspec in invalid", function()
+ assert.falsy(fetch.load_local_rockspec(testing_paths.fixtures_dir .. "/invalid_say-1.3-1.rockspec"))
+ end)
+
+ it("returns false if the rockspec version is not supported", function()
+ assert.falsy(fetch.load_local_rockspec("invalid_version.rockspec"))
+ end)
+
+ it("returns false if the rockspec doesn't pass the type checking", function()
+ test_env.run_in_tmp(function()
+ write_file("type_mismatch_string-1.0-1.rockspec", [[
+ package="type_mismatch_version"
+ version=1.0
+ ]])
+ assert.falsy(fetch.load_local_rockspec("type_mismatch_string-1.0-1.rockspec"))
+ end, finally)
+ end)
+
+ it("returns false if the rockspec file name is not right", function()
+ test_env.run_in_tmp(function()
+ write_file("invalid_rockspec_name.rockspec", [[
+ package="invalid_rockspec_name"
+ version="1.0-1"
+ source = {
+ url = "http://example.com/foo.tar.gz"
+ }
+ build = {
+
+ }
+ ]])
+ assert.falsy(fetch.load_local_rockspec("invalid_rockspec_name.rockspec"))
+ end, finally)
+ end)
+
+ it("returns false if the version in the rockspec file name doesn't match the version declared in the rockspec", function()
+ test_env.run_in_tmp(function()
+ write_file("inconsistent_versions-1.0-1.rockspec", [[
+ package="inconsistent_versions"
+ version="1.0-2"
+ source = {
+ url = "http://example.com/foo.tar.gz"
+ }
+ build = {
+
+ }
+ ]])
+ assert.falsy(fetch.load_local_rockspec("inconsistent_versions-1.0-1.rockspec"))
+ end, finally)
+ end)
+ end)
+
+ describe("fetch.load_rockspec", function()
+
+ it("returns a table containing the requested rockspec by downloading it into a temporary directory", function()
+ test_env.run_in_tmp(function()
+ path.use_tree(testing_paths.testing_tree)
+ local rockspec = fetch.load_rockspec("http://localhost:8080/file/a_rock-1.0-1.rockspec")
+ assert.same(rockspec.name, "a_rock")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.description, { summary = "An example rockspec" })
+ assert.same(rockspec.source.url, "http://localhost:8080/file/a_rock.lua")
+ rockspec = fetch.load_rockspec(testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec")
+ assert.same(rockspec.name, "a_rock")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.description, { summary = "An example rockspec" })
+ assert.same(rockspec.source.url, "http://localhost:8080/file/a_rock.lua")
+ end, finally)
+ end)
+
+ it("returns a table containing the requested rockspec by downloading it into a given directory", function()
+ test_env.run_in_tmp(function()
+ local tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+
+ path.use_tree(testing_paths.testing_tree)
+ local rockspec = fetch.load_rockspec("http://localhost:8080/file/a_rock-1.0-1.rockspec", tmpdir)
+ assert.same(rockspec.name, "a_rock")
+ assert.same(rockspec.version, "1.0-1")
+ assert.same(rockspec.description, { summary = "An example rockspec" })
+ assert.same(rockspec.source.url, "http://localhost:8080/file/a_rock.lua")
+ assert.truthy(lfs.attributes(tmpdir .. "/a_rock-1.0-1.rockspec"))
+
+ lfs.rmdir(tmpdir)
+ end, finally)
+ end)
+
+ it("returns false if the given download directory doesn't exist", function()
+ assert.falsy(fetch.load_rockspec("http://localhost:8080/file/a_rock-1.0-1.rockspec", "nonexistent"))
+ end)
+
+ it("returns false if the given filename is not a valid rockspec name", function()
+ assert.falsy(fetch.load_rockspec("http://localhost:8080/file/a_rock.lua"))
+ end)
+ end)
+
+ describe("fetch.get_sources", function()
+
+ it("downloads the sources for building a rock and returns the resulting source filename and its parent directory", function()
+ test_env.run_in_tmp(function()
+ local rockspec = assert(fetch.load_rockspec("http://localhost:8080/file/a_rock-1.0-1.rockspec"))
+ local file, dirname = fetch.get_sources(rockspec, false)
+ assert.truthy(are_same_files(dirname .. "/a_rock.lua", file))
+ end, finally)
+ end)
+
+ it("downloads the sources for building a rock into a given directory and returns the resulting source filename and its parent directory", function()
+ test_env.run_in_tmp(function()
+ local tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ local rockspec = assert(fetch.load_rockspec("http://localhost:8080/file/a_rock-1.0-1.rockspec"))
+ local file, dirname = fetch.get_sources(rockspec, false, tmpdir)
+ assert.truthy(are_same_files(tmpdir, dirname))
+ assert.truthy(are_same_files(dirname .. "/a_rock.lua", file))
+ lfs.rmdir(tmpdir)
+ end, finally)
+ end)
+
+ it("downloads the sources for building a rock, extracts the downloaded tarball and returns the resulting source filename and its parent directory", function()
+ test_env.run_in_tmp(function()
+ local rockspec = assert(fetch.load_rockspec("http://localhost:8080/file/busted_project-0.1-1.rockspec"))
+ local file, dirname = fetch.get_sources(rockspec, true)
+ assert.truthy(are_same_files(dirname .. "/busted_project-0.1.tar.gz", file))
+ assert.truthy(lfs.attributes(dirname .. "/busted_project"))
+ assert.truthy(lfs.attributes(dirname .. "/busted_project/sum.lua"))
+ assert.truthy(lfs.attributes(dirname .. "/busted_project/spec/sum_spec.lua"))
+ end, finally)
+ end)
+
+ it("returns false and does nothing if the destination directory doesn't exist", function()
+ test_env.run_in_tmp(function()
+ local rockspec = assert(fetch.load_rockspec("http://localhost:8080/file/a_rock-1.0-1.rockspec"))
+ assert.falsy(fetch.get_sources(rockspec, false, "nonexistent"))
+ end, finally)
+ end)
+
+ it("returns false and does nothing if the rockspec source url is invalid", function()
+ test_env.run_in_tmp(function(tmpdir)
+ write_file(tmpdir .. "/invalid_url-1.0-1.rockspec", [[
+ package="invalid_url"
+ version="1.0-1"
+ source = {
+ url = "http://localhost:8080/file/nonexistent"
+ }
+ build = {
+
+ }
+ ]])
+ local rockspec = assert(fetch.load_rockspec(tmpdir .. "/invalid_url-1.0-1.rockspec"))
+ assert.falsy(fetch.get_sources(rockspec, false))
+ end, finally)
+ end)
+
+ it("returns false and does nothing if the downloaded rockspec has an invalid md5 checksum", function()
+ test_env.run_in_tmp(function()
+ write_file("invalid_checksum-1.0-1.rockspec", [[
+ package="invalid_checksum"
+ version="1.0-1"
+ source = {
+ url = "http://localhost:8080/file/a_rock.lua",
+ md5 = "invalid"
+ }
+ build = {
+
+ }
+ ]])
+ local rockspec = assert(fetch.load_rockspec("invalid_checksum-1.0-1.rockspec"))
+ assert.falsy(fetch.get_sources(rockspec, false))
+ end, finally)
+ end)
+ end)
+
+ describe("fetch_sources #unix #git", function()
+ local git_repo = require("spec.util.git_repo")
+
+ local git
+
+ setup(function()
+ git = git_repo.start()
+ end)
+
+ teardown(function()
+ if git then
+ git:stop()
+ end
+ end)
+
+ it("from #git", function()
+ local rockspec, err = rockspecs.from_persisted_table("testrock-dev-1.rockspec", {
+ rockspec_format = "3.0",
+ package = "testrock",
+ version = "dev-1",
+ source = {
+ url = "git://localhost/testrock",
+ },
+ }, nil)
+ assert.falsy(err)
+ local pathname, tmpdir = fetch.fetch_sources(rockspec, false)
+ assert.are.same("testrock", pathname)
+ assert.match("luarocks_testrock%-dev%-1%-", tmpdir)
+ assert.match("^%d%d%d%d%d%d%d%d.%d%d%d%d%d%d.%x+$", tostring(rockspec.source.identifier))
+ end)
+ end)
+
+end)
diff --git a/spec/unit/fs_spec.lua b/spec/unit/fs_spec.lua
new file mode 100644
index 0000000..c2a842b
--- /dev/null
+++ b/spec/unit/fs_spec.lua
@@ -0,0 +1,1595 @@
+local test_env = require("spec.util.test_env")
+
+test_env.setup_specs()
+local fs = require("luarocks.fs")
+local path = require("luarocks.path")
+local cfg = require("luarocks.core.cfg")
+local lfs = require("lfs")
+local is_win = test_env.TEST_TARGET_OS == "windows"
+local posix_ok = pcall(require, "posix")
+local testing_paths = test_env.testing_paths
+local get_tmp_path = test_env.get_tmp_path
+local write_file = test_env.write_file
+local P = test_env.P
+
+-- A chdir that works in both full and minimal mode, setting
+-- both the real process current dir and the LuaRocks internal stack in minimal mode
+local function chdir(d)
+ lfs.chdir(d)
+ fs.change_dir(d)
+end
+
+describe("luarocks.fs #unit", function()
+ local exists_file = function(path)
+ local ok, err, code = os.rename(path, path)
+ if not ok and code == 13 then
+ return true
+ end
+ return ok
+ end
+
+ local create_file = function(path, content)
+ local fd = assert(io.open(path, "w"))
+ if not content then
+ content = "foo"
+ end
+ assert(fd:write(content))
+ fd:close()
+ end
+
+ local make_unreadable = function(path)
+ if is_win then
+ fs.execute("icacls " .. fs.Q(path) .. " /inheritance:d /deny \"%USERNAME%\":(R)")
+ else
+ fs.execute("chmod -r " .. fs.Q(path))
+ end
+ end
+
+ local make_unwritable = function(path)
+ if is_win then
+ fs.execute("icacls " .. fs.Q(path) .. " /inheritance:d /deny \"%USERNAME%\":(W,M)")
+ else
+ fs.execute("chmod -w " .. fs.Q(path))
+ end
+ end
+
+ local make_unexecutable = function(path)
+ if is_win then
+ fs.execute("icacls " .. fs.Q(path) .. " /inheritance:d /deny \"%USERNAME%\":(X)")
+ else
+ fs.execute("chmod -x " .. fs.Q(path))
+ end
+ end
+
+ local runner
+
+ lazy_setup(function()
+ cfg.init()
+ fs.init()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("fs.Q", function()
+ it("simple argument", function()
+ assert.are.same(is_win and '"foo"' or "'foo'", fs.Q("foo"))
+ end)
+
+ it("argument with quotes", function()
+ assert.are.same(is_win and [["it's \"quoting\""]] or [['it'\''s "quoting"']], fs.Q([[it's "quoting"]]))
+ end)
+
+ it("argument with special characters", function()
+ assert.are.same(is_win and [["\\"%" \\\\" \\\\\\"]] or [['\% \\" \\\']], fs.Q([[\% \\" \\\]]))
+ end)
+ end)
+
+ describe("fs.absolute_name", function()
+ it("unchanged if already absolute", function()
+ if is_win then
+ assert.are.same(P"c:\\foo\\bar", fs.absolute_name("\"c:\\foo\\bar\""))
+ assert.are.same(P"c:\\foo\\bar", fs.absolute_name("c:\\foo\\bar"))
+ assert.are.same(P"d:\\foo\\bar", fs.absolute_name("d:\\foo\\bar"))
+ assert.are.same(P"\\foo\\bar", fs.absolute_name("\\foo\\bar"))
+ else
+ assert.are.same(P"/foo/bar", fs.absolute_name("/foo/bar"))
+ end
+ end)
+
+ it("converts to absolute if relative", function()
+ local cur = fs.current_dir()
+ if is_win then
+ assert.are.same(P(cur .. "/foo\\bar"), fs.absolute_name("\"foo\\bar\""))
+ assert.are.same(P(cur .. "/foo\\bar"), fs.absolute_name("foo\\bar"))
+ else
+ assert.are.same(P(cur .. "/foo/bar"), fs.absolute_name("foo/bar"))
+ end
+ end)
+
+ it("converts a relative to specified base if given", function()
+ if is_win then
+ assert.are.same(P"c:\\bla/foo\\bar", fs.absolute_name("\"foo\\bar\"", "c:\\bla"))
+ assert.are.same(P"c:\\bla/foo\\bar", fs.absolute_name("foo/bar", "c:\\bla"))
+ assert.are.same(P"c:\\bla/foo\\bar", fs.absolute_name("foo\\bar", "c:\\bla\\"))
+ else
+ assert.are.same(P"/bla/foo/bar", fs.absolute_name("foo/bar", "/bla"))
+ assert.are.same(P"/bla/foo/bar", fs.absolute_name("foo/bar", "/bla/"))
+ end
+ end)
+ end)
+
+ describe("fs.execute_string", function()
+ local tmpdir
+
+ after_each(function()
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns the status code and runs the command given in the argument", function()
+ tmpdir = get_tmp_path()
+ assert.truthy(fs.execute_string("mkdir " .. fs.Q(tmpdir)))
+ assert.truthy(fs.is_dir(tmpdir))
+ assert.falsy(fs.execute_string("invalidcommand"))
+ end)
+ end)
+
+ describe("fs.dir_iterator", function()
+ local tmpfile1
+ local tmpfile2
+ local tmpdir
+ local intdir
+
+ after_each(function()
+ if tmpfile1 then
+ os.remove(tmpfile1)
+ tmpfile1 = nil
+ end
+ if tmpfile2 then
+ os.remove(tmpfile2)
+ tmpfile2 = nil
+ end
+ if intdir then
+ lfs.rmdir(intdir)
+ intdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("yields all files and directories in the directory given as argument during the iterations", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ tmpfile1 = tmpdir .. "/file1"
+ create_file(tmpfile1)
+ tmpfile2 = tmpdir .. "/file2"
+ create_file(tmpfile2)
+ intdir = tmpdir .. "/intdir"
+ lfs.mkdir(intdir)
+ local dirTable = {}
+ local dirCount = 0
+ local crt = coroutine.create(fs.dir_iterator)
+ while coroutine.status(crt) ~= "dead" do
+ local ok, val = coroutine.resume(crt, tmpdir)
+ if ok and val ~= nil then
+ dirTable[val] = true
+ dirCount = dirCount + 1
+ end
+ end
+ assert.same(dirCount, 3)
+ assert.is_not.same(dirTable["file1"], nil)
+ assert.is_not.same(dirTable["file2"], nil)
+ assert.is_not.same(dirTable["intdir"], nil)
+ dirCount = 0
+ crt = coroutine.create(fs.dir_iterator)
+ while coroutine.status(crt) ~= "dead" do
+ local ok, val = coroutine.resume(crt, intdir)
+ if ok and val ~= nil then
+ dirCount = dirCount + 1
+ end
+ end
+ assert.same(dirCount, 0)
+ end)
+
+ it("does nothing if the argument is a file", function()
+ tmpfile1 = get_tmp_path()
+ create_file(tmpfile1)
+ local crt = coroutine.create(fs.dir_iterator)
+ while coroutine.status(crt) ~= "dead" do
+ local ok, val = coroutine.resume(crt, tmpfile1)
+ assert.falsy(ok and res)
+ end
+ end)
+
+ it("does nothing if the argument is invalid", function()
+ local crt = coroutine.create(fs.dir_iterator)
+ while coroutine.status(crt) ~= "dead" do
+ local ok, val = coroutine.resume(crt, "/nonexistent")
+ assert.falsy(ok and res)
+ end
+ end)
+ end)
+
+ describe("fs.is_writable", function()
+ local tmpfile
+ local tmpdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true if the file given as argument is writable", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ assert.truthy(fs.is_writable(tmpfile))
+ end)
+
+ it("returns true if the directory given as argument is writable", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.is_writable(tmpdir))
+ tmpfile = tmpdir .. "/internalfile"
+ create_file(tmpfile)
+ make_unwritable(tmpfile)
+ assert.truthy(fs.is_writable(tmpdir))
+ end)
+
+ it("returns false if the file given as argument is not writable", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ make_unwritable(tmpfile)
+ assert.falsy(fs.is_writable(tmpfile))
+ end)
+
+ it("returns false if the directory given as argument is not writable", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ make_unwritable(tmpdir)
+ assert.falsy(fs.is_writable(tmpdir))
+ end)
+
+ it("returns false if the file or directory given as argument does not exist", function()
+ assert.falsy(fs.is_writable("/nonexistent"))
+ end)
+ end)
+
+ describe("fs.set_time #unix", function()
+ local tmpfile
+ local tmpdir
+ local intdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if intdir then
+ os.remove(intdir)
+ intdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true and modifies the access time of the file given as argument", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ local newtime = os.time() - 100
+ assert.truthy(fs.set_time(tmpfile, newtime))
+ assert.same(lfs.attributes(tmpfile, "access"), newtime)
+ assert.same(lfs.attributes(tmpfile, "modification"), newtime)
+ end)
+
+ it("returns true and modifies the access time of the directory given as argument", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ tmpfile = tmpdir .. "/internalfile"
+ create_file(tmpfile)
+ local newtime = os.time() - 100
+ assert.truthy(fs.set_time(tmpdir, newtime))
+ assert.same(lfs.attributes(tmpdir, "access"), newtime)
+ assert.same(lfs.attributes(tmpdir, "modification"), newtime)
+ assert.is_not.same(lfs.attributes(tmpfile, "access"), newtime)
+ assert.is_not.same(lfs.attributes(tmpfile, "modification"), newtime)
+ end)
+
+ it("returns false and does nothing if the file or directory given as arguments doesn't exist", function()
+ assert.falsy(fs.set_time("/nonexistent"))
+ end)
+ end)
+
+ describe("fs.set_permissions", function()
+ local readfile
+ local execfile
+ local tmpdir
+
+ after_each(function()
+ if readfile then
+ os.remove(readfile)
+ readfile = nil
+ end
+ if execfile then
+ os.remove(execfile)
+ execfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true and sets the permissions of the argument accordingly", function()
+ readfile = get_tmp_path()
+ create_file(readfile)
+ make_unreadable(readfile)
+ assert.falsy(io.open(readfile, "r"))
+ assert.truthy(fs.set_permissions(readfile, "read", "user"))
+ assert.truthy(io.open(readfile, "r"))
+
+ if is_win then
+ execfile = get_tmp_path() .. ".exe"
+ create_file(execfile)
+ else
+ execfile = get_tmp_path() .. ".sh"
+ create_file(execfile, "#!/bin/bash")
+ end
+ make_unexecutable(execfile)
+ local fd = assert(io.popen(execfile .. " 2>&1"))
+ local result = assert(fd:read("*a"))
+ assert.truthy(result:match("denied"))
+ fd:close()
+ assert.truthy(fs.set_permissions(execfile, "exec", "user"))
+ fd = assert(io.popen(execfile .. " 2>&1"))
+ result = assert(fd:read("*a"))
+ assert.falsy(result:match("denied"))
+ fd:close()
+
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ make_unexecutable(tmpdir)
+ fd = assert(io.popen("cd " .. fs.Q(tmpdir) .. " 2>&1"))
+ result = assert(fd:read("*a"))
+ assert.truthy(result:match("denied") or result:match("can't cd"))
+ fd:close()
+ assert.truthy(fs.set_permissions(tmpdir, "exec", "user"))
+ fd = assert(io.popen("cd " .. fs.Q(tmpdir) .. " 2>&1"))
+ result = assert(fd:read("*a"))
+ assert.falsy(result:match("denied") or result:match("can't cd"))
+ fd:close()
+ end)
+
+ it("returns false and does nothing if the argument is nonexistent", function()
+ assert.falsy(fs.set_permissions("/nonexistent", "read", "user"))
+ end)
+ end)
+
+ describe("fs.is_file", function()
+ local tmpfile
+ local tmpdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true when the argument is a file", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ assert.same(true, fs.is_file(tmpfile))
+ end)
+
+ it("returns false when the argument does not exist", function()
+ assert.same(false, fs.is_file("/nonexistent"))
+ end)
+
+ it("returns false when the argument exists but is not a file", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.same(false, fs.is_file("/nonexistent"))
+ end)
+
+ it("#unix returns false when the argument is a symlink to a directory", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ local linkname = tmpdir .. "/symlink"
+ finally(function() os.remove(linkname) end)
+ lfs.link(tmpdir, linkname, true)
+ assert.falsy(fs.is_file(linkname))
+ end)
+
+ it("#unix returns true when the argument is a symlink to a file", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ local linkname = tmpfile .. "_symlink"
+ finally(function() os.remove(linkname) end)
+ lfs.link(tmpfile, linkname, true)
+ assert.truthy(fs.is_file(linkname))
+ end)
+ end)
+
+ describe("fs.is_dir", function()
+ local tmpfile
+ local tmpdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true when the argument is a directory", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.is_dir(tmpdir))
+ end)
+
+ it("returns false when the argument is a file", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ assert.falsy(fs.is_dir(tmpfile))
+ end)
+
+ it("#unix returns true when the argument is a symlink to a directory", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ local linkname = tmpdir .. "/symlink"
+ finally(function() os.remove(linkname) end)
+ lfs.link(tmpdir, linkname, true)
+ assert.truthy(fs.is_dir(linkname))
+ end)
+
+ it("#unix returns false when the argument is a symlink to a file", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ local linkname = tmpfile .. "_symlink"
+ finally(function() os.remove(linkname) end)
+ lfs.link(tmpfile, linkname, true)
+ assert.falsy(fs.is_dir(linkname))
+ end)
+
+ it("returns false when the argument does not exist", function()
+ assert.falsy(fs.is_dir("/nonexistent"))
+ end)
+ end)
+
+ describe("fs.exists", function()
+ local tmpfile
+ local tmpdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true when the argument is a file", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ assert.truthy(fs.exists(tmpfile))
+ end)
+
+ it("returns true when the argument is a directory", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.exists(tmpdir))
+ end)
+
+ it("returns false when the argument does not exist", function()
+ assert.falsy(fs.exists("/nonexistent"))
+ end)
+ end)
+
+ describe("fs.current_dir", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ end)
+
+ after_each(function()
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ if olddir then
+ chdir(olddir)
+ olddir = nil
+ end
+ end)
+
+ it("returns the current working directory", function()
+ local currentdir = lfs.currentdir()
+ assert.same(currentdir, fs.current_dir())
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.change_dir(tmpdir))
+ if is_win then
+ assert.same(tmpdir, fs.current_dir())
+ else
+ assert.same(lfs.attributes(tmpdir).ino, lfs.attributes((fs.current_dir())).ino)
+ end
+ end)
+ end)
+
+ describe("fs.change_dir", function()
+ local tmpfile
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ end)
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ if olddir then
+ chdir(olddir)
+ olddir = nil
+ end
+ end)
+
+ it("returns true and changes the current working directory if the argument is a directory", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.change_dir(tmpdir))
+ if is_win then
+ assert.same(tmpdir, fs.current_dir())
+ else
+ assert.same(lfs.attributes(tmpdir).ino, lfs.attributes(fs.current_dir()).ino)
+ end
+ end)
+
+ it("returns false and does nothing when the argument is a file", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ assert.falsy(fs.change_dir(tmpfile))
+ assert.same(olddir, lfs.currentdir())
+ end)
+
+ it("returns false and does nothing when the argument does not exist", function()
+ assert.falsy(fs.change_dir("/nonexistent"))
+ assert.same(olddir, lfs.currentdir())
+ end)
+ end)
+
+ describe("fs.change_dir_to_root", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ end)
+
+ after_each(function()
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ if olddir then
+ chdir(olddir)
+ end
+ end)
+
+ it("returns true and changes the current directory to root if the current directory is valid", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.change_dir(tmpdir))
+ assert.truthy(fs.change_dir_to_root())
+ if is_win then
+ local curr_dir = fs.current_dir()
+ assert.truthy(curr_dir == "C:\\" or curr_dir == P"/")
+ else
+ assert.same(P"/", fs.current_dir())
+ end
+ end)
+
+ it("returns false and does nothing if the current directory is not valid #unix", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ chdir(tmpdir)
+ lfs.rmdir(tmpdir)
+ assert.falsy(fs.change_dir_to_root())
+ assert.is_not.same("/", lfs.currentdir())
+ end)
+ end)
+
+ describe("fs.pop_dir", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ end)
+
+ after_each(function()
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ if olddir then
+ chdir(olddir)
+ end
+ end)
+
+ it("returns true and changes the current directory to the previous one in the dir stack if the dir stack is not empty", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ assert.truthy(fs.change_dir(tmpdir))
+ assert.truthy(fs.pop_dir())
+ assert.same(olddir, lfs.currentdir())
+ end)
+ end)
+
+ describe("fs.make_dir", function()
+ local tmpfile
+ local tmpdir
+ local intdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if intdir then
+ lfs.rmdir(intdir)
+ intdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true and creates the directory specified by the argument", function()
+ tmpdir = get_tmp_path()
+ assert.truthy(fs.make_dir(tmpdir))
+ assert.same("directory", lfs.attributes(tmpdir, "mode"))
+ end)
+
+ it("returns true and creates the directory path specified by the argument", function()
+ tmpdir = get_tmp_path()
+ intdir = "/internaldir"
+ local dirpath = tmpdir .. intdir
+ assert.truthy(fs.make_dir(dirpath))
+ assert.same("directory", lfs.attributes(tmpdir, "mode"))
+ assert.same("directory", lfs.attributes(dirpath, "mode"))
+ end)
+
+ it("returns false and does nothing if the argument is not valid (file in the path)", function()
+ tmpfile = get_tmp_path()
+ local fd = assert(io.open(tmpfile, "w"))
+ assert(fd:write("foo"))
+ fd:close()
+ intdir = "/internaldir"
+ local dirpath = tmpfile .. intdir
+ assert.falsy(fs.make_dir(dirpath))
+ end)
+
+ it("returns false and does nothing if the argument already exists", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile)
+ assert.falsy(fs.make_dir(tmpfile))
+ end)
+ end)
+
+ describe("fs.remove_dir_if_empty", function()
+ local tmpfile
+ local tmpdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("removes the directory specified by the argument if it is empty", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ fs.remove_dir_if_empty(tmpdir)
+ assert.falsy(exists_file(tmpdir))
+ end)
+
+ it("does nothing if the directory specified by the argument is not empty", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ tmpfile = "/internalfile"
+ local filepath = tmpdir .. tmpfile
+ create_file(filepath)
+ fs.remove_dir_if_empty(tmpdir)
+ assert.truthy(exists_file(tmpdir))
+ end)
+ end)
+
+ describe("fs.remove_dir_tree_if_empty", function()
+ local tmpfile
+ local tmpdir
+ local intdir
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ if intdir then
+ lfs.rmdir(intdir)
+ intdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("removes the directory path specified by the argument if it is empty", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ fs.remove_dir_tree_if_empty(tmpdir)
+ assert.falsy(exists_file(tmpdir))
+ end)
+
+ it("does nothing if the directory path specified by the argument is not empty", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ intdir = "/internaldir"
+ local dirpath = tmpdir .. intdir
+ lfs.mkdir(dirpath)
+ tmpfile = "/internalfile"
+ local filepath = dirpath .. tmpfile
+ fs.remove_dir_tree_if_empty(tmpdir)
+ assert.truthy(exists_file(dirpath))
+ assert.truthy(exists_file(tmpdir))
+ end)
+ end)
+
+ describe("fs.list_dir", function()
+ local intfile1
+ local intfile2
+ local intdir
+ local tmpdir
+
+ before_each(function()
+ if intfile1 then
+ os.remove(intfile1)
+ intfile1 = nil
+ end
+ if intfile2 then
+ os.remove(intfile2)
+ intfile2 = nil
+ end
+ if intdir then
+ lfs.rmdir(intdir)
+ intdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns a table with the contents of the given directory", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ intfile1 = tmpdir .. "/intfile1"
+ create_file(intfile1)
+ intdir = tmpdir .. "/intdir"
+ lfs.mkdir(intdir)
+ intfile2 = intdir .. "/intfile2"
+ create_file(intfile2)
+ local result = fs.list_dir(tmpdir)
+ assert.same(#result, 2)
+ assert.truthy(result[1] == "intfile1" or result[1] == "intdir")
+ assert.truthy(result[2] == "intfile1" or result[2] == "intdir")
+ assert.is_not.same(result[1], result[2])
+ end)
+
+ it("returns an empty table if the argument is a file", function()
+ intfile1 = get_tmp_path()
+ create_file(intfile1)
+ local result = fs.list_dir(intfile1)
+ assert.same(#result, 0)
+ end)
+
+ it("does nothing if the argument is nonexistent", function()
+ assert.same(fs.list_dir("/nonexistent"), {})
+ end)
+
+ it("does nothing if the argument doesn't have the proper permissions", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ make_unreadable(tmpdir)
+ assert.same(fs.list_dir(tmpdir), {})
+ end)
+ end)
+
+ describe("fs.copy", function()
+ local srcfile
+ local dstfile
+ local tmpdir
+
+ after_each(function()
+ if srcfile then
+ os.remove(srcfile)
+ srcfile = nil
+ end
+ if dstfile then
+ os.remove(dstfile)
+ dstfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true and copies the contents and the permissions of the source file to the destination file", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile, srccontent)
+ dstfile = get_tmp_path()
+ assert.truthy(fs.copy(srcfile, dstfile))
+ local fd = assert(io.open(dstfile, "r"))
+ local dstcontent = fd:read("*a")
+ assert.same("foo", dstcontent)
+ if posix_ok then
+ assert.same(lfs.attributes(srcfile, "permissions"), lfs.attributes(dstfile, "permissions"))
+ end
+ end)
+
+ it("returns true and copies contents of the source file to the destination file with custom permissions", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile, srccontent)
+ dstfile = get_tmp_path()
+ assert.truthy(fs.copy(srcfile, dstfile, "exec"))
+ local fd = assert(io.open(dstfile, "r"))
+ local dstcontent = fd:read("*a")
+ assert.same("foo", dstcontent)
+ end)
+
+ it("returns false and does nothing if the source file does not exist", function()
+ srcfile = get_tmp_path()
+ dstfile = get_tmp_path()
+ local ok, err = fs.copy(srcfile, dstfile, nil)
+ assert.falsy(ok)
+ assert.not_match("are the same file", err)
+ assert.falsy(exists_file(dstfile))
+ end)
+
+ it("returns false and does nothing if the source file doesn't have the proper permissions", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile)
+ make_unreadable(srcfile)
+ dstfile = get_tmp_path()
+ assert.falsy(fs.copy(srcfile, dstfile, nil))
+ assert.falsy(exists_file(dstfile))
+ end)
+
+ it("returns false and does nothing if the destination file directory doesn't have the proper permissions", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile)
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ make_unwritable(tmpdir)
+ dstfile = tmpdir .. "/dstfile"
+ assert.falsy(fs.copy(srcfile, dstfile, nil))
+ assert(fs.set_permissions(tmpdir, "exec", "all"))
+ assert.falsy(exists_file(dstfile))
+ end)
+ end)
+
+ describe("fs.copy_contents", function()
+ local srcfile
+ local dstfile
+ local srcintdir
+ local dstintdir
+ local srcdir
+ local dstdir
+
+ after_each(function()
+ if srcfile then
+ os.remove(srcfile)
+ srcfile = nil
+ end
+ if dstfile then
+ os.remove(dstfile)
+ dstfile = nil
+ end
+ if srcintdir then
+ lfs.rmdir(srcintdir)
+ srcintdir = nil
+ end
+ if dstintdir then
+ lfs.rmdir(dstintdir)
+ dstintdir = nil
+ end
+ if srcdir then
+ lfs.rmdir(srcdir)
+ srcdir = nil
+ end
+ if dstdir then
+ lfs.rmdir(dstdir)
+ dstdir = nil
+ end
+ end)
+
+ local create_dir_tree = function()
+ srcdir = get_tmp_path()
+ lfs.mkdir(srcdir)
+ srcintdir = srcdir .. "/internaldir"
+ lfs.mkdir(srcintdir)
+ srcfile = srcintdir .. "/internalfile"
+ create_file(srcfile)
+ dstdir = get_tmp_path()
+ end
+
+ it("returns true and copies the contents (with their permissions) of the source dir to the destination dir", function()
+ create_dir_tree()
+ assert.truthy(fs.copy_contents(srcdir, dstdir))
+ assert.truthy(exists_file(dstdir))
+ dstintdir = dstdir .. "/internaldir"
+ assert.truthy(exists_file(dstintdir))
+ dstfile = dstdir .. "/internaldir/internalfile"
+ local fd = assert(io.open(dstfile, "r"))
+ local dstfilecontent = fd:read("*a")
+ assert.same("foo", dstfilecontent)
+ if posix_ok then
+ assert.same(lfs.attributes(srcfile, "permissions"), lfs.attributes(dstfile, "permissions"))
+ end
+ end)
+
+ it("returns true and copies the contents of the source dir to the destination dir with custom permissions", function()
+ create_dir_tree()
+ assert.truthy(fs.copy_contents(srcdir, dstdir, "read"))
+ assert.truthy(exists_file(dstdir))
+ dstintdir = dstdir .. "/internaldir"
+ assert.truthy(exists_file(dstintdir))
+ dstfile = dstdir .. "/internaldir/internalfile"
+ local fd = assert(io.open(dstfile, "r"))
+ local dstfilecontent = fd:read("*a")
+ assert.same("foo", dstfilecontent)
+ end)
+
+ it("returns false and does nothing if the source dir doesn't exist", function()
+ srcdir = get_tmp_path()
+ dstdir = get_tmp_path()
+ assert.falsy(fs.copy_contents(srcdir, dstdir))
+ assert.falsy(exists_file(dstdir))
+ end)
+
+ it("returns false if the source argument is a file", function()
+ srcdir = get_tmp_path()
+ create_file(srcdir)
+ dstdir = get_tmp_path()
+ assert.falsy(fs.copy_contents(srcdir, dstdir))
+ assert.falsy(exists_file(dstdir))
+ end)
+
+ it("returns false and does nothing if the source dir doesn't have the proper permissions", function()
+ create_dir_tree()
+ make_unreadable(srcdir)
+ assert.falsy(fs.copy_contents(srcdir, dstdir))
+ assert.falsy(exists_file(dstdir .. "/internaldir"))
+ assert.falsy(exists_file(dstdir .. "/internalfile"))
+ end)
+ end)
+
+ describe("fs.find", function()
+ local tmpdir
+ local intdir
+ local intfile1
+ local intfile2
+
+ after_each(function()
+ if intfile1 then
+ os.remove(intfile1)
+ intfile1 = nil
+ end
+ if intfile2 then
+ os.remove(intfile2)
+ intfile2 = nil
+ end
+ if intdir then
+ lfs.rmdir(intdir)
+ intdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ local create_dir_tree = function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ intfile1 = tmpdir .. "/intfile1"
+ create_file(intfile1)
+ intdir = tmpdir .. "/intdir"
+ lfs.mkdir(intdir)
+ intfile2 = intdir .. "/intfile2"
+ create_file(intfile2)
+ end
+
+ it("returns a table of all the contents in the directory given as argument", function()
+ create_dir_tree()
+ local contents = {}
+ local count = 0
+ for _, file in pairs(fs.find(tmpdir)) do
+ contents[file] = true
+ count = count + 1
+ end
+ assert.same(count, 3)
+ assert.is_not.same(contents[tmpdir], true)
+ assert.same(contents[P"intfile1"], true)
+ assert.same(contents[P"intdir"], true)
+ assert.same(contents[P"intdir/intfile2"], true)
+ end)
+
+ it("uses the current working directory if the argument is nil", function()
+ create_dir_tree()
+ local olddir = fs.current_dir()
+ fs.change_dir(intdir)
+ local contents = {}
+ local count = 0
+ for _, file in pairs(fs.find()) do
+ contents[file] = true
+ count = count + 1
+ end
+ assert.same(count, 1)
+ assert.is_not.same(contents["intfile1"], true)
+ assert.is_not.same(contents["intdir"], true)
+ assert.same(contents["intfile2"], true)
+ fs.change_dir(olddir)
+ end)
+
+ it("returns an empty table if the argument is nonexistent", function()
+ local contents = fs.find("/nonexistent")
+ local count = 0
+ for _, file in pairs(contents) do
+ count = count + 1
+ end
+ assert.same(count, 0)
+ end)
+
+ it("returns an empty table if the argument is a file", function()
+ intfile1 = get_tmp_path()
+ create_file(intfile1)
+ local contents = fs.find(intfile1)
+ local count = 0
+ for _, file in pairs(contents) do
+ count = count + 1
+ end
+ assert.same(count, 0)
+ end)
+
+ it("does nothing if the argument doesn't have the proper permissions", function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ make_unreadable(tmpdir)
+ assert.same(fs.find(tmpdir), {})
+ end)
+ end)
+
+ describe("fs.move", function()
+ local srcfile
+ local dstfile
+ local tmpdir
+
+ after_each(function()
+ if srcfile then
+ os.remove(srcfile)
+ srcfile = nil
+ end
+ if dstfile then
+ os.remove(dstfile)
+ dstfile = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ it("returns true and moves the source (together with its permissions) to the destination", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile)
+ dstfile = get_tmp_path()
+ local oldperms = lfs.attributes(srcfile, "permissions")
+ assert.truthy(fs.move(srcfile, dstfile))
+ assert.truthy(fs.exists(dstfile))
+ assert.falsy(fs.exists(srcfile))
+ local fd = assert(io.open(dstfile, "r"))
+ local dstcontents = assert(fd:read("*a"))
+ assert.same(dstcontents, "foo")
+ if posix_ok then
+ assert.same(oldperms, lfs.attributes(dstfile, "permissions"))
+ end
+ end)
+
+ it("returns true and moves the source (with custom permissions) to the destination", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile)
+ dstfile = get_tmp_path()
+ assert.truthy(fs.move(srcfile, dstfile, "read"))
+ assert.truthy(fs.exists(dstfile))
+ assert.falsy(fs.exists(srcfile))
+ local fd = assert(io.open(dstfile, "r"))
+ local dstcontents = assert(fd:read("*a"))
+ assert.same(dstcontents, "foo")
+ end)
+
+ it("returns false and does nothing if the source doesn't exist", function()
+ dstfile = get_tmp_path()
+ assert.falsy(fs.move("/nonexistent", dstfile))
+ assert.falsy(fs.exists(dstfile))
+ end)
+
+ it("returns false and does nothing if the destination already exists", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile)
+ dstfile = get_tmp_path()
+ create_file(dstfile, "bar")
+ assert.falsy(fs.move(srcfile, dstfile))
+ assert.truthy(fs.exists(srcfile))
+ local fd = assert(io.open(dstfile, "r"))
+ local dstcontents = assert(fd:read("*a"))
+ assert.same(dstcontents, "bar")
+ end)
+
+ it("returns false and does nothing if the destination path doesn't have the proper permissions", function()
+ srcfile = get_tmp_path()
+ create_file(srcfile)
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ make_unwritable(tmpdir)
+ assert.falsy(fs.move(srcfile, tmpdir .. "/dstfile"))
+ assert.falsy(fs.exists(tmpdir .. "/dstfile"))
+ end)
+ end)
+
+ describe("fs.is_lua", function()
+ local tmpfile
+
+ after_each(function()
+ if tmpfile then
+ os.remove(tmpfile)
+ tmpfile = nil
+ end
+ end)
+
+ it("returns true if the argument is a valid lua script", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile, "print(\"foo\")")
+ assert.truthy(fs.is_lua(tmpfile))
+ end)
+
+ it("returns true if the argument is a valid lua script with shebang", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile, "#!/usr/bin/env lua\n\nprint(\"foo\")")
+ assert.truthy(fs.is_lua(tmpfile))
+ end)
+
+ it("returns false if the argument is not a valid lua script", function()
+ tmpfile = os.tmpname()
+ create_file(tmpfile)
+ assert.falsy(fs.is_lua(tmpfile))
+ end)
+
+ it("returns false if the argument is a valid lua script but doesn't have the proper permissions", function()
+ tmpfile = get_tmp_path()
+ create_file(tmpfile, "print(\"foo\")")
+ make_unreadable(tmpfile)
+ assert.falsy(fs.is_lua(tmpfile))
+ end)
+ end)
+
+ describe("fs.delete", function()
+ local tmpfile1
+ local tmpfile2
+ local tmpintdir
+ local tmpdir
+
+ after_each(function()
+ if tmpfile1 then
+ os.remove(tmpfile1)
+ tmpfile1 = nil
+ end
+ if tmpfile2 then
+ os.remove(tmpfile2)
+ tmpfile2 = nil
+ end
+ if tmpintdir then
+ lfs.rmdir(tmpintdir)
+ tmpintdir = nil
+ end
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ tmpdir = nil
+ end
+ end)
+
+ local create_dir_tree = function()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ tmpintdir = tmpdir .. "/internaldir"
+ lfs.mkdir(tmpintdir)
+ tmpfile1 = tmpdir .. "/internalfile1"
+ create_file(tmpfile1)
+ tmpfile2 = tmpdir .. "/internalfile2"
+ create_file(tmpfile2)
+ end
+
+ it("deletes the file specified by the argument", function()
+ tmpfile1 = get_tmp_path()
+ tmpfile2 = get_tmp_path()
+ fs.delete(tmpfile1)
+ fs.delete(tmpfile2)
+ assert.falsy(exists_file(tmpfile1))
+ assert.falsy(exists_file(tmpfile2))
+ end)
+
+ it("deletes the contents of the directory specified by the argument", function()
+ create_dir_tree()
+ fs.delete(tmpdir)
+ assert.falsy(exists_file(tmpfile2))
+ assert.falsy(exists_file(tmpintdir))
+ assert.falsy(exists_file(tmpfile1))
+ assert.falsy(exists_file(tmpdir))
+ end)
+ end)
+
+ describe("fs.zip", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ chdir(tmpdir)
+
+ write_file("file1", "content1", finally)
+ write_file("file2", "content2", finally)
+ lfs.mkdir("dir")
+ write_file("dir/file3", "content3", finally)
+ end)
+
+ after_each(function()
+ if olddir then
+ chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir .. "/dir")
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("returns true and creates a zip archive of the given files", function()
+ assert.truthy(fs.zip("archive.zip", "file1", "file2", "dir"))
+ assert.truthy(exists_file("archive.zip"))
+ end)
+
+ it("returns false and does nothing if the files specified in the arguments are invalid", function()
+ assert.falsy(fs.zip("archive.zip", "nonexistent"))
+ assert.falsy(exists_file("nonexistent"))
+ end)
+ end)
+
+ describe("fs.bunzip2", function()
+
+ it("uncompresses a .bz2 file", function()
+ local input = testing_paths.fixtures_dir .. "/abc.bz2"
+ local output = os.tmpname()
+ assert.truthy(fs.bunzip2(input, output))
+ local fd = io.open(output, "r")
+ local content = fd:read("*a")
+ fd:close()
+ assert.same(300000, #content)
+ local abc = ("a"):rep(100000)..("b"):rep(100000)..("c"):rep(100000)
+ assert.same(abc, content)
+ end)
+
+ end)
+
+ describe("fs.unzip", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ chdir(tmpdir)
+
+ write_file("file1", "content1", finally)
+ write_file("file2", "content2", finally)
+ lfs.mkdir("dir")
+ write_file("dir/file3", "content3", finally)
+ end)
+
+ after_each(function()
+ if olddir then
+ chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir .. "/dir")
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("returns true and unzips the given zip archive", function()
+ assert.truthy(fs.zip("archive.zip", "file1", "file2", "dir"))
+ os.remove("file1")
+ os.remove("file2")
+ lfs.rmdir("dir")
+
+ assert.truthy(fs.unzip("archive.zip"))
+ assert.truthy(exists_file("file1"))
+ assert.truthy(exists_file("file2"))
+ assert.truthy(exists_file("dir/file3"))
+
+ local fd
+
+ fd = assert(io.open("file1", "r"))
+ assert.same(fd:read("*a"), "content1")
+ fd:close()
+
+ fd = assert(io.open("file2", "r"))
+ assert.same(fd:read("*a"), "content2")
+ fd:close()
+
+ fd = assert(io.open("dir/file3", "r"))
+ assert.same(fd:read("*a"), "content3")
+ fd:close()
+ end)
+
+ it("does nothing if the given archive is invalid", function()
+ assert.falsy(fs.unzip("archive.zip"))
+ end)
+ end)
+
+ describe("fs.wrap_script", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ chdir(tmpdir)
+ end)
+
+ after_each(function()
+ if olddir then
+ chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("produces a wrapper for a Lua script", function()
+ write_file("my_script", "io.write('Hello ' .. arg[1])", finally)
+ path.use_tree(testing_paths.testing_tree)
+ local wrapper_name = fs.absolute_name("wrapper") .. test_env.wrapper_extension
+ fs.wrap_script("my_script", wrapper_name, "one", nil, nil, "World")
+ local pd = assert(io.popen(wrapper_name))
+ local data = pd:read("*a")
+ pd:close()
+ assert.same("Hello World", data)
+ end)
+ end)
+
+ describe("fs.copy_binary", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ chdir(tmpdir)
+
+ write_file("test.exe", "", finally)
+ end)
+
+ after_each(function()
+ if olddir then
+ chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("returns true and copies the given binary file to the file specified in the dest argument", function()
+ assert.truthy(fs.copy_binary("test.exe", lfs.currentdir() .. "/copy.exe"))
+ assert.truthy(exists_file("copy.exe"))
+ if is_win then
+ assert.truthy(exists_file("test.lua"))
+ local fd = assert(io.open("test.lua", "r"))
+ local content = assert(fd:read("*a"))
+ assert.truthy(content:find("package.path", 1, true))
+ assert.truthy(content:find("package.cpath", 1, true))
+ fd:close()
+ end
+ end)
+
+ it("returns false and does nothing if the source file is invalid", function()
+ assert.falsy(fs.copy_binary("invalid.exe", "copy.exe"))
+ end)
+ end)
+
+ describe("fs.modules", function()
+ local tmpdir
+ local olddir
+ local oldpath
+
+ before_each(function()
+ olddir = lfs.currentdir()
+ tmpdir = get_tmp_path()
+ lfs.mkdir(tmpdir)
+ chdir(tmpdir)
+ lfs.mkdir("lib")
+ write_file("lib/module1.lua", "", finally)
+ write_file("lib/module2.lua", "", finally)
+ write_file("lib/module1.LuA", "", finally)
+ write_file("lib/non_lua", "", finally)
+ lfs.mkdir("lib/internal")
+ write_file("lib/internal/module11.lua", "", finally)
+ write_file("lib/internal/module22.lua", "", finally)
+
+ oldpath = package.path
+ package.path = package.path .. tmpdir .. "/?.lua;"
+ end)
+
+ after_each(function()
+ if olddir then
+ chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir .. "/lib/internal")
+ lfs.rmdir(tmpdir .. "/lib")
+ lfs.rmdir(tmpdir)
+ end
+ end
+ if oldpath then
+ package.path = oldpath
+ end
+ end)
+
+ it("returns a table of the lua modules at a specific require path", function()
+ local result
+
+ result = fs.modules("lib")
+ assert.same(#result, 2)
+ assert.truthy(result[1] == "module1" or result[2] == "module1")
+ assert.truthy(result[1] == "module2" or result[2] == "module2")
+
+ result = fs.modules("lib.internal")
+ assert.same(#result, 2)
+ assert.truthy(result[1] == "module11" or result[2] == "module11")
+ assert.truthy(result[1] == "module22" or result[2] == "module22")
+ end)
+
+ it("returns an empty table if the modules couldn't be found in package.path", function()
+ package.path = ""
+ assert.same(fs.modules("lib"), {})
+ end)
+ end)
+
+ describe("#unix fs._unix_rwx_to_number", function()
+
+ it("converts permissions in rwx notation to numeric ones", function()
+ assert.same(tonumber("0644", 8), fs._unix_rwx_to_number("rw-r--r--"))
+ assert.same(tonumber("0755", 8), fs._unix_rwx_to_number("rwxr-xr-x"))
+ assert.same(tonumber("0000", 8), fs._unix_rwx_to_number("---------"))
+ assert.same(tonumber("0777", 8), fs._unix_rwx_to_number("rwxrwxrwx"))
+ assert.same(tonumber("0700", 8), fs._unix_rwx_to_number("rwx------"))
+ assert.same(tonumber("0600", 8), fs._unix_rwx_to_number("rw-------"))
+ end)
+
+ it("produces a negated mask if asked to", function()
+ assert.same(tonumber("0133", 8), fs._unix_rwx_to_number("rw-r--r--", true))
+ assert.same(tonumber("0022", 8), fs._unix_rwx_to_number("rwxr-xr-x", true))
+ assert.same(tonumber("0777", 8), fs._unix_rwx_to_number("---------", true))
+ assert.same(tonumber("0000", 8), fs._unix_rwx_to_number("rwxrwxrwx", true))
+ assert.same(tonumber("0077", 8), fs._unix_rwx_to_number("rwx------", true))
+ assert.same(tonumber("0177", 8), fs._unix_rwx_to_number("rw-------", true))
+ end)
+ end)
+
+ describe("fs.execute_env", function()
+ local tmpname
+ local tmplua
+ local LUA = "lua"
+
+ local function readfile(pathname)
+ local file = assert(io.open(pathname, "rb"))
+ local data = file:read "*a"
+ file:close()
+ return data
+ end
+
+ lazy_setup(function()
+ tmpname = os.tmpname()
+
+ tmplua = os.tmpname()
+ local f = assert(io.open(tmplua, 'wb'))
+ f:write [[
+ local out = io.open((...), 'wb')
+ out:write(os.getenv 'FOO')
+ out:close()
+ ]]
+ f:close()
+ LUA = test_env.testing_paths.lua
+ end)
+
+ after_each(function()
+ os.remove(tmpname)
+ end)
+
+ lazy_teardown(function()
+ os.remove(tmpname)
+ end)
+
+ it("passes variables w/o spaces correctly", function()
+ fs.execute_env({
+ FOO = "BAR",
+ }, LUA, tmplua, tmpname)
+ local data = readfile(tmpname)
+ assert.same("BAR", data)
+ end)
+
+ it("passes variables w/ spaces correctly", function()
+ fs.execute_env({
+ FOO = "BAR with spaces",
+ }, LUA, tmplua, tmpname)
+ local data = readfile(tmpname)
+ assert.same("BAR with spaces", data)
+ end)
+ end)
+
+end)
diff --git a/spec/unit/fun_spec.lua b/spec/unit/fun_spec.lua
new file mode 100644
index 0000000..bffb60d
--- /dev/null
+++ b/spec/unit/fun_spec.lua
@@ -0,0 +1,128 @@
+local test_env = require("spec.util.test_env")
+local testing_paths = test_env.testing_paths
+
+local fun = require("luarocks.fun")
+
+describe("luarocks.fun #unit", function()
+ local runner
+
+ lazy_setup(function()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("fun.concat", function()
+ it("returns the concatenation of the two tables given as arguments", function()
+ local t1, t2
+
+ t1 = {1, 2, 3}
+ t2 = {4, 5, 6}
+ assert.same(fun.concat(t1, t2), {1, 2, 3, 4, 5, 6})
+ assert.same(fun.concat(t2, t1), {4, 5, 6, 1, 2, 3})
+ t1 = {1, 2, 3}
+ t2 = {}
+ assert.same(fun.concat(t1, t2), {1, 2, 3})
+ assert.same(fun.concat(t2, t1), {1, 2, 3})
+ t1 = {}
+ t2 = {}
+ assert.same(fun.concat(t1, t2), {})
+ end)
+ end)
+
+ describe("fun.contains", function()
+ it("checks whether a table contains a given value", function()
+ local t
+
+ t = {1, 2, 3}
+ assert.truthy(fun.contains(t, 1))
+ assert.falsy(fun.contains(t, 4))
+ t = {}
+ assert.falsy(fun.contains(t, 1))
+ end)
+ end)
+
+ local addOne = function(x) return x + 1 end
+
+ describe("fun.map", function()
+ it("applies a function to each element in the given table and returns the results in a new table", function()
+ local t
+
+ t = {1, 2, 3}
+ assert.same(fun.map(t, addOne), {2, 3, 4})
+ t = {}
+ assert.same(fun.map(t, addOne), {})
+ end)
+ end)
+
+ describe("fun.traverse", function()
+ it("recursively applies a function to each element in a given table and returns the results in a new table", function()
+ local t
+
+ t = {1, 2, {3, 4, {5, 6}}}
+ assert.same(fun.traverse(t, addOne), {2, 3, {4, 5, {6, 7}}})
+ t = {1, 2, {}, {1, {}, 2}}
+ assert.same(fun.traverse(t, addOne), {2, 3, {}, {2, {}, 3}})
+ end)
+ end)
+
+ describe("fun.filter", function()
+ it("filters the elements in the given table and returns the result in a new table", function()
+ local t
+
+ t = {1, 2, "a", "b", 3}
+ assert.same(fun.filter(t, function(x) return type(x) == "number" end), {1, 2, 3})
+ t = {2, 4, 7, 8}
+ assert.same(fun.filter(t, function(x) return x % 2 == 0 end), {2, 4, 8})
+ end)
+ end)
+
+ describe("fun.reverse_in", function()
+ it("reverses the elements in the given table and returns the result in a new table", function()
+ local t
+
+ t = {1, 2, 3, 4}
+ assert.same(fun.reverse_in(t), {4, 3, 2, 1})
+ t = {"a", "b", "c"}
+ assert.same(fun.reverse_in(t), {"c", "b", "a"})
+ end)
+ end)
+
+ describe("fun.sort_in", function()
+ it("sorts the elements in the given table and returns the result in a new table", function()
+ local t
+
+ t = {4, 2, 3, 1}
+ assert.same(fun.sort_in(t), {1, 2, 3, 4})
+ t = {"d", "a", "c", "b"}
+ assert.same(fun.sort_in(t), {"a", "b", "c", "d"})
+ end)
+ end)
+
+ describe("fun.flip", function()
+ it("returns a function behaving as the one given in the argument but with the arguments interchanged", function()
+ local a, b = fun.flip(function(a, b) return a, b end)(5, 6)
+ assert.same(a, 6)
+ assert.same(b, 5)
+ end)
+ end)
+
+ describe("fun.partial", function()
+ it("partially applies the given arguments to the given function and returns it", function()
+ local addOne = fun.partial(function(x, y) return x + y end, 1)
+ assert.same(addOne(1), 2)
+ assert.same(addOne(2), 3)
+
+ local addTwo = fun.partial(function(x, y, z) return x + y + z end, 1, 1)
+ assert.same(addTwo(1), 3)
+ assert.same(addTwo(2), 4)
+
+ local addThree = fun.partial(function(x, y, z, t, u) return x + y + z + t + u end, 1, 1, 1)
+ assert.same(addThree(1, 1), 5)
+ assert.same(addThree(1, 2), 6)
+ end)
+ end)
+end)
diff --git a/spec/unit/loader_spec.lua b/spec/unit/loader_spec.lua
new file mode 100644
index 0000000..cde3059
--- /dev/null
+++ b/spec/unit/loader_spec.lua
@@ -0,0 +1,18 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+
+test_env.setup_specs()
+
+describe("luarocks.loader", function()
+ describe("#unit", function()
+ it("starts", function()
+ assert(run.lua_bool([[-e "require 'luarocks.loader'; print(package.loaded['luarocks.loaded'])"]]))
+ end)
+
+ describe("which", function()
+ it("finds modules using package.path", function()
+ assert(run.lua_bool([[-e "loader = require 'luarocks.loader'; local x,y,z,p = loader.which('luarocks.loader', 'p'); assert(p == 'p')"]]))
+ end)
+ end)
+ end)
+end)
diff --git a/spec/unit/persist_spec.lua b/spec/unit/persist_spec.lua
new file mode 100644
index 0000000..ed78345
--- /dev/null
+++ b/spec/unit/persist_spec.lua
@@ -0,0 +1,74 @@
+local test_env = require("spec.util.test_env")
+local testing_paths = test_env.testing_paths
+
+local persist = require("luarocks.persist")
+
+describe("luarocks.persist #unit", function()
+ local runner
+
+ lazy_setup(function()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("persist.save_from_table_to_string", function()
+ it("simple table", function()
+ assert.are.same([[
+bar = 1234
+foo = "string"
+]], persist.save_from_table_to_string({foo = "string", bar = 1234}))
+ end)
+
+ it("nested tables", function()
+ assert.are.same([[
+bar = {
+ baz = "string"
+}
+foo = {
+ 1, 2, 3, 4
+}
+]], persist.save_from_table_to_string({foo = {1, 2, 3, 4}, bar = {baz = "string"}}))
+ end)
+
+ it("table with a keyword key (#947)", function()
+ assert.are.same([[
+bar = {
+ ["function"] = "foo"
+}
+]], persist.save_from_table_to_string({bar = {["function"] = "foo"}}))
+ end)
+
+ it("strings with quotes", function()
+ assert.are.same([[
+bar = "a \\backslash?"
+foo = "a \"quote\"?"
+]], persist.save_from_table_to_string({foo = 'a "quote"?', bar = 'a \\backslash?'}))
+ end)
+
+ it("multiline strings", function()
+ assert.are.same([===[
+bar = [==[
+]]
+]=]]==]
+foo = [[
+First line
+Second line]]
+]===], persist.save_from_table_to_string({foo = "First line\nSecond line", bar = "]]\n]=]"}))
+ end)
+
+ it("multiline strings ending with brackets", function()
+ assert.are.same([===[
+bar = [==[
+]]
+]=]==]
+foo = [=[
+First line
+Second line [1]]=]
+]===], persist.save_from_table_to_string({foo = "First line\nSecond line [1]", bar = "]]\n]="}))
+ end)
+ end)
+end)
diff --git a/spec/unit/rockspecs_spec.lua b/spec/unit/rockspecs_spec.lua
new file mode 100644
index 0000000..7eb033c
--- /dev/null
+++ b/spec/unit/rockspecs_spec.lua
@@ -0,0 +1,126 @@
+
+local rockspecs = require("luarocks.rockspecs")
+local cfg = require("luarocks.core.cfg")
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+
+describe("luarocks.rockspecs #unit", function()
+
+ lazy_setup(function()
+ cfg.init()
+ end)
+
+ it("auto adds a build dependency for non-vendored build types", function()
+ local filename = "test-1.0-1.rockspec"
+ local rockspec = {
+ package = "test",
+ source = {
+ url = "",
+ },
+ build = {
+ type = "foo"
+ },
+ }
+ local globals = {}
+ local quick = true
+
+ local out = rockspecs.from_persisted_table(filename, rockspec, globals, quick)
+
+ assert(rockspec == out)
+ assert.same(rockspec.build_dependencies, {
+ { name = "luarocks-build-foo", constraints = {} },
+ })
+ end)
+
+ it("does not add a build dependency for non-vendored build type if it's already ther", function()
+ local filename = "test-1.0-1.rockspec"
+ local rockspec = {
+ package = "test",
+ source = {
+ url = "",
+ },
+ build_dependencies = {
+ "luarocks-build-cpp >= 1.0",
+ },
+ build = {
+ type = "cpp"
+ },
+ }
+ local globals = {}
+ local quick = true
+
+ local out = rockspecs.from_persisted_table(filename, rockspec, globals, quick)
+
+ assert(rockspec == out)
+
+ assert.same(rockspec.build_dependencies, {
+ { name = "luarocks-build-cpp", constraints = { { op = ">=", version = { string = "1.0", 1, 0 } } } },
+ })
+ end)
+
+ it("does not add a build dependency for 'none' build type", function()
+ local filename = "test-1.0-1.rockspec"
+ local rockspec = {
+ package = "test",
+ source = {
+ url = "",
+ },
+ build = {
+ type = "none"
+ },
+ }
+ local globals = {}
+ local quick = true
+
+ local out = rockspecs.from_persisted_table(filename, rockspec, globals, quick)
+
+ assert(rockspec == out)
+ assert.same(rockspec.build_dependencies, {})
+ end)
+
+ it("does not add a build dependency for 'module' build type", function()
+ local filename = "test-1.0-1.rockspec"
+ local rockspec = {
+ package = "test",
+ source = {
+ url = "",
+ },
+ build = {
+ type = "none"
+ },
+ }
+ local globals = {}
+ local quick = true
+
+ local out = rockspecs.from_persisted_table(filename, rockspec, globals, quick)
+
+ assert(rockspec == out)
+ assert.same(rockspec.build_dependencies, {})
+ end)
+
+ for d in lfs.dir(test_env.testing_paths.src_dir .. "/luarocks/build") do
+ local name = d:match("(.*)%.lua")
+ if name then
+ it("does not add a build dependency for vendored '" .. name .. "' type", function()
+ local filename = "test-1.0-1.rockspec"
+ local rockspec = {
+ package = "test",
+ source = {
+ url = "",
+ },
+ build = {
+ type = name
+ },
+ }
+ local globals = {}
+ local quick = true
+
+ local out = rockspecs.from_persisted_table(filename, rockspec, globals, quick)
+
+ assert(rockspec == out)
+ assert.same(rockspec.build_dependencies, {})
+ end)
+ end
+ end
+
+end)
diff --git a/spec/unit/sysdetect_spec.lua b/spec/unit/sysdetect_spec.lua
new file mode 100644
index 0000000..d3b1695
--- /dev/null
+++ b/spec/unit/sysdetect_spec.lua
@@ -0,0 +1,79 @@
+
+local sysdetect = require("luarocks.core.sysdetect")
+local lfs = require("lfs")
+
+describe("luarocks.core.sysdetect #unix #unit", function()
+
+ lazy_setup(function()
+ os.execute([=[
+ [ -e binary-samples ] || {
+ git clone --depth=1 https://github.com/hishamhm/binary-samples
+ ( cd binary-samples && git pull )
+ }
+ ]=])
+ end)
+
+ local files = {
+ ["."] = "ignore",
+ [".."] = "ignore",
+ ["README.md"] = "ignore",
+ [".git"] = "ignore",
+ ["MIT_LICENSE"] = "ignore",
+ ["anti-disassembler"] = "ignore",
+ ["elf-Linux-lib-x64.so"] = "ignore",
+ ["elf-Linux-lib-x86.so"] = "ignore",
+
+ ["elf-Linux-x64-bash"] = {"linux", "x86_64"},
+ ["elf-Linux-ia64-bash"] = {"linux", "ia_64"},
+ ["MachO-OSX-ppc-and-i386-bash"] = {"macosx", "x86"},
+ ["MachO-OSX-ppc-openssl-1.0.1h"] = {"macosx", "ppc"},
+ ["MachO-iOS-armv7-armv7s-arm64-Helloworld"] = {"macosx", "arm"},
+ ["pe-Windows-x64-cmd"] = {"windows", "x86_64"},
+ ["MachO-iOS-armv7s-Helloworld"] = {"macosx", "arm"},
+ ["elf-Linux-SparcV8-bash"] = {"linux", "sparcv8"},
+ ["elf-HPUX-ia64-bash"] = {"hpux", "ia_64"},
+ ["MachO-OSX-x64-ls"] = {"macosx", "x86_64"},
+ ["pe-Windows-ARMv7-Thumb2LE-HelloWorld"] = {"windows", "armv7l"},
+ ["elf-ARMv6-static-gofmt"] = {"sysv", "arm"},
+ ["elf-Linux-s390-bash"] = {"linux", "s390"},
+ ["elf-Linux-Alpha-bash"] = {"linux", "alpha"},
+ ["elf-Linux-hppa-bash"] = {"linux", "hppa"},
+ ["elf-Linux-x86_64-static-sln"] = {"linux", "x86_64"},
+ ["elf-Linux-Mips4-bash"] = {"linux", "mips"},
+ ["elf-ARMv6-dynamic-go"] = {"linux", "arm"},
+ ["elf-Linux-SuperH4-bash"] = {"linux", "superh"},
+ ["elf-Linux-x86-bash"] = {"linux", "x86"},
+ ["elf-Linux-PowerPC-bash"] = {"linux", "ppc"},
+ ["libSystem.B.dylib"] = {"macosx", "x86_64"},
+ ["MachO-iOS-arm1176JZFS-bash"] = {"macosx", "arm"},
+ ["pe-Windows-x86-cmd"] = {"windows", "x86"},
+ ["elf-Linux-ARMv7-ls"] = {"linux", "arm"},
+ ["elf-Linux-ARM64-bash"] = {"linux", "aarch64"},
+ ["MachO-OSX-x86-ls"] = {"macosx", "x86"},
+ ["elf-solaris-sparc-ls"] = {"solaris", "sparc"},
+ ["elf-solaris-x86-ls"] = {"solaris", "x86"},
+ ["pe-mingw32-strip.exe"] = {"windows", "x86"},
+ ["elf-OpenBSD-x86_64-sh"] = {"openbsd", "x86_64"},
+ ["elf-NetBSD-x86_64-echo"] = {"netbsd", "x86_64"},
+ ["elf-FreeBSD-x86_64-echo"] = {"freebsd", "x86_64"},
+ ["elf-Haiku-GCC2-ls"] = {"haiku", "x86"},
+ ["elf-Haiku-GCC7-WebPositive"] = {"haiku", "x86"},
+ ["pe-cygwin-ls.exe"] = {"cygwin", "x86"},
+ ["elf-DragonFly-x86_64-less"] = {"dragonfly", "x86_64"},
+
+ }
+
+ describe("detect_file", function()
+ it("detects system and processor", function()
+ for f in lfs.dir("binary-samples") do
+ if files[f] ~= "ignore" then
+ assert.table(files[f], "unknown binary " .. f)
+ local expected_s, expected_p = files[f][1], files[f][2]
+ local s, p = sysdetect.detect_file("binary-samples/" .. f)
+ assert.same(expected_s, s, "bad system for " .. f)
+ assert.same(expected_p, p, "bad processor for " .. f)
+ end
+ end
+ end)
+ end)
+end)
diff --git a/spec/unit/test_spec.lua b/spec/unit/test_spec.lua
new file mode 100644
index 0000000..4a31777
--- /dev/null
+++ b/spec/unit/test_spec.lua
@@ -0,0 +1,173 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local get_tmp_path = test_env.get_tmp_path
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+
+local fs = require("luarocks.fs")
+local cfg = require("luarocks.core.cfg")
+local path = require("luarocks.path")
+local test = require("luarocks.test")
+local test_busted = require("luarocks.test.busted")
+local test_command = require("luarocks.test.command")
+
+describe("LuaRocks test #unit", function()
+ local runner
+
+ lazy_setup(function()
+ cfg.init()
+ fs.init()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ local tmpdir
+ local olddir
+
+ local create_tmp_dir = function()
+ tmpdir = get_tmp_path()
+ olddir = lfs.currentdir()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+ fs.change_dir(tmpdir)
+ end
+
+ local destroy_tmp_dir = function()
+ if olddir then
+ lfs.chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end
+
+ describe("test.command", function()
+ describe("command.detect_type", function()
+ before_each(function()
+ create_tmp_dir()
+ end)
+
+ after_each(function()
+ destroy_tmp_dir()
+ end)
+
+ it("returns true if test.lua exists", function()
+ write_file("test.lua", "", finally)
+ assert.truthy(test_command.detect_type())
+ end)
+
+ it("returns false if test.lua doesn't exist", function()
+ assert.falsy(test_command.detect_type())
+ end)
+ end)
+
+ describe("command.run_tests", function()
+ before_each(function()
+ create_tmp_dir()
+ end)
+
+ after_each(function()
+ destroy_tmp_dir()
+ end)
+
+ it("returns the result of the executed tests", function()
+ write_file("test.lua", "assert(1==1)", finally)
+ assert.truthy(test_command.run_tests(nil, {}))
+
+ write_file("test.lua", "assert(1==2)", finally)
+ assert.falsy(test_command.run_tests(nil, {}))
+ end)
+
+ it("returns the result of the executed tests with custom arguments and test command", function()
+ write_file("test.lua", "assert(1==1)", finally)
+
+ local test = {
+ script = "test.lua",
+ flags = {
+ arg1 = "1",
+ arg2 = "2"
+ },
+ command = fs.Q(testing_paths.lua)
+ }
+ assert.truthy(test_command.run_tests(test, {}))
+ end)
+
+ it("returns false and does nothing if the test script doesn't exist", function()
+ assert.falsy(test_command.run_tests(nil, {}))
+ end)
+ end)
+ end)
+
+ describe("test.busted", function()
+ describe("busted.detect_type", function()
+ before_each(function()
+ create_tmp_dir()
+ end)
+
+ after_each(function()
+ destroy_tmp_dir()
+ end)
+
+ it("returns true if .busted exists", function()
+ write_file(".busted", "", finally)
+ assert.truthy(test_busted.detect_type())
+ end)
+
+ it("returns false if .busted doesn't exist", function()
+ assert.falsy(test_busted.detect_type())
+ end)
+ end)
+
+ describe("busted.run_tests", function()
+ before_each(function()
+ path.use_tree(testing_paths.testing_sys_tree)
+ create_tmp_dir()
+ end)
+
+ after_each(function()
+ destroy_tmp_dir()
+ end)
+
+ pending("returns the result of the executed tests", function()
+ -- FIXME: busted issue
+ write_file("test_spec.lua", "assert(1==1)", finally)
+ assert.truthy(test_busted.run_tests(nil, {}))
+
+ write_file("test_spec.lua", "assert(1==2)", finally)
+ assert.falsy(test_busted.run_tests())
+ end)
+ end)
+ end)
+
+ describe("test", function()
+ describe("test.run_test_suite", function()
+ before_each(function()
+ create_tmp_dir()
+ end)
+
+ after_each(function()
+ destroy_tmp_dir()
+ end)
+
+ it("returns false if the given rockspec cannot be loaded", function()
+ assert.falsy(test.run_test_suite("invalid", nil, {}))
+ end)
+
+ it("returns false if no test type was detected", function()
+ assert.falsy(test.run_test_suite({ package = "test" }, nil, {}))
+ end)
+
+ it("returns the result of executing the tests specified in the given rockspec", function()
+ write_file("test.lua", "assert(1==1)", finally)
+ assert.truthy(test.run_test_suite({ test_dependencies = {} }, nil, {}))
+
+ write_file("test.lua", "assert(1==2)", finally)
+ assert.falsy(test.run_test_suite({ test_dependencies = {} }, nil, {}))
+ end)
+ end)
+ end)
+end)
diff --git a/spec/unit/tools_spec.lua b/spec/unit/tools_spec.lua
new file mode 100644
index 0000000..5b85c86
--- /dev/null
+++ b/spec/unit/tools_spec.lua
@@ -0,0 +1,251 @@
+local test_env = require("spec.util.test_env")
+local get_tmp_path = test_env.get_tmp_path
+local testing_paths = test_env.testing_paths
+local write_file = test_env.write_file
+
+local fs = require("luarocks.fs")
+local cfg = require("luarocks.core.cfg")
+local patch = require("luarocks.tools.patch")
+
+local lao =
+[[The Nameless is the origin of Heaven and Earth;
+The named is the mother of all things.
+
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their outcome.
+The two are the same,
+But after they are produced,
+ they have different names.
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!]]
+
+local tzu =
+[[The Way that can be told of is not the eternal Way;
+The name that can be named is not the eternal name.
+The Nameless is the origin of Heaven and Earth;
+The Named is the mother of all things.
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their outcome.
+The two are the same,
+But after they are produced,
+ they have different names.]]
+
+local valid_patch1 =
+[[--- lao 2002-02-21 23:30:39.942229878 -0800
++++ tzu 2002-02-21 23:30:50.442260588 -0800
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@ -9,3 +8,6 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
++The door of all subtleties!]]
+
+local valid_patch2 =
+[[--- /dev/null 1969-02-21 23:30:39.942229878 -0800
++++ tzu 2002-02-21 23:30:50.442260588 -0800
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@ -9,3 +8,6 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
++The door of all subtleties!]]
+
+local invalid_patch1 =
+[[--- lao 2002-02-21 23:30:39.942229878 -0800
++++ tzu 2002-02-21 23:30:50.442260588 -0800
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
+--- Extra
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+--- Extra
+@@ -9,3 +8,7 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
++The door of all subtleties!]]
+
+local invalid_patch2 =
+[[--- lao 2002-02-21 23:30:39.942229878 -0800
++++ tzu 2002-02-21 23:30:50.442260588 -0800
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@ -9,3 +8,6 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
+? ...
++The door of all subtleties!]]
+
+local invalid_patch3 =
+[[--- lao 2002-02-21 23:30:39.942229878 -0800
++++ tzu 2002-02-21 23:30:50.442260588 -0800
+@@ -1,7 +1,6 @@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@ -9,3 +8,6 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
+? ...
++The door of all subtleties!]]
+
+describe("Luarocks patch test #unit", function()
+ local runner
+
+ lazy_setup(function()
+ cfg.init()
+ fs.init()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("patch.read_patch", function()
+ it("returns a table with the patch file info and the result of parsing the file", function()
+ local t, result
+
+ write_file("test.patch", valid_patch1, finally)
+ t, result = patch.read_patch("test.patch")
+ assert.truthy(result)
+ assert.truthy(t)
+
+ write_file("test.patch", invalid_patch1, finally)
+ t, result = patch.read_patch("test.patch")
+ assert.falsy(result)
+ assert.truthy(t)
+
+ write_file("test.patch", invalid_patch2, finally)
+ t, result = patch.read_patch("test.patch")
+ assert.falsy(result)
+ assert.truthy(t)
+
+ write_file("test.patch", invalid_patch3, finally)
+ t, result = patch.read_patch("test.patch")
+ assert.falsy(result)
+ assert.truthy(t)
+ end)
+ end)
+
+ describe("patch.apply_patch", function()
+ local tmpdir
+ local olddir
+
+ before_each(function()
+ tmpdir = get_tmp_path()
+ olddir = lfs.currentdir()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+
+ write_file("lao", tzu, finally)
+ write_file("tzu", lao, finally)
+ end)
+
+ after_each(function()
+ if olddir then
+ lfs.chdir(olddir)
+ if tmpdir then
+ lfs.rmdir(tmpdir)
+ end
+ end
+ end)
+
+ it("applies the given patch and returns the result of patching", function()
+ write_file("test.patch", valid_patch1, finally)
+ local p = patch.read_patch("test.patch")
+ local result = patch.apply_patch(p)
+ assert.truthy(result)
+ end)
+
+ it("applies the given patch with custom arguments and returns the result of patching", function()
+ write_file("test.patch", valid_patch2, finally)
+ local p = patch.read_patch("test.patch")
+ local result = patch.apply_patch(p, nil, true)
+ assert.truthy(result)
+ end)
+
+ it("fails if the patch file is invalid", function()
+ write_file("test.patch", invalid_patch1, finally)
+ local p = patch.read_patch("test.patch")
+ local result = pcall(patch.apply_patch, p)
+ assert.falsy(result)
+ end)
+
+ it("returns false if the files from the patch doesn't exist", function()
+ os.remove("lao")
+ os.remove("tzu")
+
+ write_file("test.patch", valid_patch1, finally)
+ local p = patch.read_patch("test.patch")
+ local result = patch.apply_patch(p)
+ assert.falsy(result)
+ end)
+
+ it("returns false if the target file was already patched", function()
+ write_file("test.patch", valid_patch1, finally)
+ local p = patch.read_patch("test.patch")
+ local result = patch.apply_patch(p)
+ assert.truthy(result)
+
+ result = patch.apply_patch(p)
+ assert.falsy(result)
+ end)
+ end)
+end)
diff --git a/spec/unit/util_spec.lua b/spec/unit/util_spec.lua
new file mode 100644
index 0000000..8b234b2
--- /dev/null
+++ b/spec/unit/util_spec.lua
@@ -0,0 +1,160 @@
+local test_env = require("spec.util.test_env")
+local testing_paths = test_env.testing_paths
+local P = test_env.P
+
+local util = require("luarocks.util")
+local core_util = require("luarocks.core.util")
+
+describe("luarocks.util #unit", function()
+ local runner
+
+ lazy_setup(function()
+ runner = require("luacov.runner")
+ runner.init(testing_paths.testrun_dir .. "/luacov.config")
+ end)
+
+ lazy_teardown(function()
+ runner.save_stats()
+ end)
+
+ describe("util.variable_substitutions", function()
+ it("replaces variables", function()
+ local t = {
+ ["hello"] = "$(KIND) world",
+ }
+ util.variable_substitutions(t, {
+ ["KIND"] = "happy",
+ })
+ assert.are.same({
+ ["hello"] = "happy world",
+ }, t)
+ end)
+
+ it("missing variables are empty", function()
+ local t = {
+ ["hello"] = "$(KIND) world",
+ }
+ util.variable_substitutions(t, {
+ })
+ assert.are.same({
+ ["hello"] = " world",
+ }, t)
+ end)
+ end)
+
+ describe("util.sortedpairs", function()
+ local function collect(iter, state, var)
+ local collected = {}
+
+ while true do
+ local returns = {iter(state, var)}
+
+ if returns[1] == nil then
+ return collected
+ else
+ table.insert(collected, returns)
+ var = returns[1]
+ end
+ end
+ end
+
+ it("default sort", function()
+ assert.are.same({}, collect(util.sortedpairs({})))
+ assert.are.same({
+ {1, "v1"},
+ {2, "v2"},
+ {3, "v3"},
+ {"bar", "v5"},
+ {"foo", "v4"}
+ }, collect(util.sortedpairs({"v1", "v2", "v3", foo = "v4", bar = "v5"})))
+ end)
+
+ it("sort by function", function()
+ local function compare(a, b) return a > b end
+ assert.are.same({}, collect(util.sortedpairs({}, compare)))
+ assert.are.same({
+ {3, "v3"},
+ {2, "v2"},
+ {1, "v1"}
+ }, collect(util.sortedpairs({"v1", "v2", "v3"}, compare)))
+ end)
+
+ it("sort by priority table", function()
+ assert.are.same({}, collect(util.sortedpairs({}, {"k1", "k2"})))
+ assert.are.same({
+ {"k3", "v3"},
+ {"k2", "v2", {"sub order"}},
+ {"k1", "v1"},
+ {"k4", "v4"},
+ {"k5", "v5"},
+ }, collect(util.sortedpairs({
+ k1 = "v1", k2 = "v2", k3 = "v3", k4 = "v4", k5 = "v5"
+ }, {"k3", {"k2", {"sub order"}}, "k1"})))
+ end)
+ end)
+
+ describe("core.util.show_table", function()
+ it("returns a pretty-printed string containing the representation of the given table", function()
+ local result
+
+ local t1 = {1, 2, 3}
+ result = core_util.show_table(t1)
+ assert.truthy(result:find("[1] = 1", 1, true))
+ assert.truthy(result:find("[2] = 2", 1, true))
+ assert.truthy(result:find("[3] = 3", 1, true))
+
+ local t2 = {a = 1, b = 2, c = 3}
+ result = core_util.show_table(t2)
+ assert.truthy(result:find("[\"a\"] = 1", 1, true))
+ assert.truthy(result:find("[\"b\"] = 2", 1, true))
+ assert.truthy(result:find("[\"c\"] = 3", 1, true))
+
+ local t3 = {a = 1, b = "2", c = {3}}
+ result = core_util.show_table(t3)
+ assert.truthy(result:find("[\"a\"] = 1", 1, true))
+ assert.truthy(result:find("[\"b\"] = \"2\"", 1, true))
+ assert.truthy(result:find("[\"c\"] = {", 1, true))
+ assert.truthy(result:find("[1] = 3", 1, true))
+
+ local t4 = {a = 1, b = {c = 2, d = {e = "4"}}}
+ result = core_util.show_table(t4)
+ assert.truthy(result:find("[\"a\"] = 1", 1, true))
+ assert.truthy(result:find("[\"b\"] = {", 1, true))
+ assert.truthy(result:find("[\"c\"] = 2", 1, true))
+ assert.truthy(result:find("[\"d\"] = {", 1, true))
+ assert.truthy(result:find("[\"e\"] = \"4\"", 1, true))
+ end)
+ end)
+
+ describe("core.util.cleanup_path", function()
+ it("does not change order of existing items of prepended path", function()
+ local sys_path = P'/usr/local/bin;/usr/bin'
+ local lr_path = P'/home/user/.luarocks/bin;/usr/bin'
+ local path = lr_path .. ';' .. sys_path
+
+ local result = core_util.cleanup_path(path, ';', '5.3', false)
+ assert.are.equal(P'/home/user/.luarocks/bin;/usr/local/bin;/usr/bin', result)
+ end)
+
+ it("does not change order of existing items of appended path", function()
+ local sys_path = P'/usr/local/bin;/usr/bin'
+ local lr_path = P'/home/user/.luarocks/bin;/usr/bin'
+ local path = sys_path .. ';' .. lr_path
+
+ local result = core_util.cleanup_path(path, ';', '5.3', true)
+ assert.are.equal(P'/usr/local/bin;/usr/bin;/home/user/.luarocks/bin', result)
+ end)
+
+ it("rewrites versions that do not match the provided version", function()
+ local expected = P'a/b/lua/5.3/?.lua;a/b/c/lua/5.3/?.lua'
+ local result = core_util.cleanup_path(P'a/b/lua/5.2/?.lua;a/b/c/lua/5.3/?.lua', ';', '5.3')
+ assert.are.equal(expected, result)
+ end)
+
+ it("does not rewrite versions for which the provided version is a substring", function()
+ local expected = P'a/b/lua/5.3/?.lua;a/b/c/lua/5.3.4/?.lua'
+ local result = core_util.cleanup_path(P'a/b/lua/5.2/?.lua;a/b/c/lua/5.3.4/?.lua', ';', '5.3')
+ assert.are.equal(expected, result)
+ end)
+ end)
+end)
diff --git a/spec/unpack_spec.lua b/spec/unpack_spec.lua
new file mode 100644
index 0000000..59f7eb0
--- /dev/null
+++ b/spec/unpack_spec.lua
@@ -0,0 +1,69 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+local extra_rocks = {
+ "/cprint-${CPRINT}.src.rock",
+ "/cprint-${CPRINT}.rockspec",
+ "/luazip-1.2.4-1.rockspec"
+}
+
+describe("luarocks unpack #integration", function()
+
+ before_each(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ describe("basic fail tests", function()
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("unpack"))
+ end)
+
+ it("with invalid rockspec", function()
+ assert.is_false(run.luarocks_bool("unpack invalid.rockspec"))
+ end)
+
+ it("with invalid patch", function()
+ assert.is_false(run.luarocks_bool("unpack " .. testing_paths.fixtures_dir .. "/invalid_patch-0.1-1.rockspec"))
+ end)
+ end)
+
+ describe("more complex tests", function()
+ it("download", function()
+ assert.is_true(run.luarocks_bool("unpack cprint"))
+ test_env.remove_dir("cprint-${CPRINT}")
+ end)
+
+ it("src", function()
+ assert.is_true(run.luarocks_bool("download --source cprint"))
+ assert.is_true(run.luarocks_bool("unpack cprint-${CPRINT}.src.rock"))
+ os.remove("cprint-${CPRINT}.src.rock")
+ test_env.remove_dir("cprint-${CPRINT}")
+ end)
+
+ it("src", function()
+ assert.is_true(run.luarocks_bool("download --rockspec cprint"))
+ assert.is_true(run.luarocks_bool("unpack cprint-${CPRINT}.rockspec"))
+ os.remove("cprint-${CPRINT}.rockspec")
+ os.remove("lua-cprint")
+ test_env.remove_dir("cprint-${CPRINT}")
+ end)
+
+ -- #595 luarocks unpack of a git:// rockspec fails to copy the rockspec
+ it("git:// rockspec", function()
+ assert.is_true(run.luarocks_bool("download --rockspec luazip"))
+ assert.is_true(run.luarocks_bool("unpack luazip-1.2.4-1.rockspec"))
+ assert.is_truthy(lfs.attributes("luazip-1.2.4-1/luazip/luazip-1.2.4-1.rockspec"))
+ test_env.remove_dir("luazip-1.2.4-1")
+ end)
+
+ it("binary", function()
+ assert.is_true(run.luarocks_bool("build cprint"))
+ assert.is_true(run.luarocks_bool("pack cprint"))
+ assert.is_true(run.luarocks_bool("unpack cprint-${CPRINT}." .. test_env.platform .. ".rock"))
+ test_env.remove_dir("cprint-${CPRINT}")
+ os.remove("cprint-${CPRINT}." .. test_env.platform .. ".rock")
+ end)
+ end)
+end)
diff --git a/spec/upload_spec.lua b/spec/upload_spec.lua
new file mode 100644
index 0000000..cc0b606
--- /dev/null
+++ b/spec/upload_spec.lua
@@ -0,0 +1,63 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local testing_paths = test_env.testing_paths
+
+describe("luarocks upload #integration", function()
+
+ describe("general tests", function()
+ before_each(function()
+ test_env.setup_specs(nil)
+ end)
+
+ it("with no flags/arguments", function()
+ assert.is_false(run.luarocks_bool("upload"))
+ end)
+
+ it("invalid rockspec", function()
+ assert.is_false(run.luarocks_bool("upload invalid.rockspec"))
+ end)
+
+ it("api key invalid", function()
+ assert.is_false(run.luarocks_bool("upload --api-key=invalid invalid.rockspec"))
+ end)
+
+ it("api key invalid and skip-pack", function()
+ assert.is_false(run.luarocks_bool("upload --api-key=\"invalid\" --skip-pack " .. testing_paths.testing_server .. "/luasocket-${LUASOCKET}.rockspec"))
+ end)
+
+ it("force #unix", function()
+ assert.is_false(run.luarocks_bool("upload --api-key=\"invalid\" --force " .. testing_paths.testing_server .. "/luasocket-${LUASOCKET}.rockspec"))
+ end)
+ end)
+
+ describe("tests with Xavante server #mock", function()
+ lazy_setup(function()
+ test_env.setup_specs(nil, "mock")
+ test_env.mock_server_init()
+ end)
+
+ lazy_teardown(test_env.mock_server_done)
+
+ it("rockspec with api-key", function()
+ assert.is_true(run.luarocks_bool("upload " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec " .. test_env.openssl_dirs .. " --api-key=123", {LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/luarocks_site.lua"}))
+ end)
+
+ it("#gpg rockspec with --sign", function()
+ os.remove(testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec.asc")
+ os.remove(testing_paths.testrun_dir .. "/a_rock-1.0-1.src.rock.asc")
+ print(run.luarocks("upload " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec " .. test_env.openssl_dirs .. " --api-key=123 --sign", {LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/luarocks_site.lua"}))
+ end)
+
+ it("with .rockspec and .src.rock", function()
+ assert.is_true(run.luarocks_bool("upload " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.src.rock " .. test_env.openssl_dirs, {LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/luarocks_site.lua"}))
+ end)
+
+ it("with arguments .src.rock and .rockspec out of order", function()
+ assert.is_false(run.luarocks_bool("upload " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.src.rock " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec " .. test_env.openssl_dirs, {LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/luarocks_site.lua"}))
+ end)
+
+ it("rockspec with api-key and skip-pack", function()
+ assert.is_true(run.luarocks_bool("upload --skip-pack " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec " .. test_env.openssl_dirs .. " --api-key=123", {LUAROCKS_CONFIG = testing_paths.testrun_dir .. "/luarocks_site.lua"}))
+ end)
+ end)
+end)
diff --git a/spec/util/git_repo.lua b/spec/util/git_repo.lua
new file mode 100644
index 0000000..b3ddd9e
--- /dev/null
+++ b/spec/util/git_repo.lua
@@ -0,0 +1,108 @@
+local git_repo = {}
+
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+
+local files = {
+----------------------------------------
+["testrock-dev-1.rockspec"] = [[
+package = "testrock"
+version = "dev-1"
+source = {
+ url = "git://localhost:20000/testrock"
+}
+description = {
+ homepage = "https://localhost",
+ license = "MIT"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ testrock = "testrock.lua"
+ }
+}
+]],
+----------------------------------------
+["testrock.lua"] = [[
+local testrock = {}
+
+function testrock.say()
+ return "Hello, world!"
+end
+
+return testrock
+]],
+----------------------------------------
+["foo.c"] = [[
+#include <lua.h>
+int luaopen_foo(lua_State* L) {
+ lua_pushnumber(L, 42);
+ return 1;
+}
+]],
+----------------------------------------
+["test.lua"] = [[
+print("this should be ignored!")
+]],
+}
+
+local function write_file(filename, contents)
+ local fd = assert(io.open(filename, "w"))
+ assert(fd:write(contents))
+ fd:close()
+end
+
+local function handling(args)
+ local pok, ret = pcall(args.try)
+ if not pok then
+ pok, ret = pcall(args.catch, ret)
+ end
+ args.finally()
+ if not pok then
+ error(ret)
+ end
+ return ret
+end
+
+function git_repo.start()
+ local dir = lfs.currentdir()
+ return handling {
+ try = function()
+ local pidfile = os.tmpname()
+ local basedir = test_env.testing_paths.testrun_dir .. "/git_repo"
+ local repodir = basedir .. "/testrock"
+ test_env.remove_dir(basedir)
+ lfs.mkdir(basedir)
+ lfs.mkdir(repodir)
+ lfs.chdir(repodir)
+ assert(test_env.execute("git init"))
+ for name, contents in pairs(files) do
+ write_file(name, contents)
+ test_env.execute("git add " .. name)
+ end
+ assert(test_env.execute("git commit -a -m 'initial commit'"))
+ assert(test_env.execute("git branch test-branch"))
+ print("git daemon --reuseaddr --pid-file="..pidfile.." --base-path="..basedir.." --export-all "..repodir.." &")
+ assert(test_env.execute("git daemon --reuseaddr --pid-file="..pidfile.." --base-path="..basedir.." --export-all "..repodir.." &"))
+ assert(test_env.execute("sleep 0.1; netstat -ln | grep '0.0.0.0:9418 .* LISTEN'"))
+ return {
+ stop = function()
+ local fd = io.open(pidfile)
+ local pid = fd:read("*a")
+ fd:close()
+ assert(test_env.execute("kill -HUP " .. pid))
+ test_env.remove_dir(basedir)
+ end
+ }
+ end,
+ catch = function(err)
+ error(err)
+ end,
+ finally = function()
+ lfs.chdir(dir)
+ end,
+ }
+end
+
+return git_repo
diff --git a/spec/util/mock-server.lua b/spec/util/mock-server.lua
new file mode 100644
index 0000000..1b09cd6
--- /dev/null
+++ b/spec/util/mock-server.lua
@@ -0,0 +1,98 @@
+#!/usr/bin/env lua
+
+--- A simple LuaRocks mock-server for testing.
+local restserver = require("restserver")
+local server = restserver:new():port(8080)
+
+server:add_resource("api/tool_version", {
+ {
+ method = "GET",
+ path = "/",
+ produces = "application/json",
+ handler = function(query)
+ local json = { version = query.current }
+ return restserver.response():status(200):entity(json)
+ end
+ }
+})
+
+server:add_resource("api/1/{id:[0-9]+}/status", {
+ {
+ method = "GET",
+ path = "/",
+ produces = "application/json",
+ handler = function(query)
+ local json = { user_id = "123", created_at = "29.1.1993" }
+ return restserver.response():status(200):entity(json)
+ end
+ }
+})
+
+server:add_resource("/api/1/{id:[0-9]+}/check_rockspec", {
+ {
+ method = "GET",
+ path = "/",
+ produces = "application/json",
+ handler = function(query)
+ local json = {}
+ return restserver.response():status(200):entity(json)
+ end
+ }
+})
+
+server:add_resource("/api/1/{id:[0-9]+}/upload", {
+ {
+ method = "POST",
+ path = "/",
+ produces = "application/json",
+ handler = function(query)
+ local json = {module = "luasocket", version = {id = "1.0"}, module_url = "http://localhost/luasocket", manifests = "root", is_new = "is_new"}
+ return restserver.response():status(200):entity(json)
+ end
+ }
+})
+
+server:add_resource("/api/1/{id:[0-9]+}/upload_rock/{id:[0-9]+}", {
+ {
+ method = "POST",
+ path = "/",
+ produces = "application/json",
+ handler = function(query)
+ local json = {"rock","module_url"}
+ return restserver.response():status(200):entity(json)
+ end
+ }
+})
+
+server:add_resource("/file/{name:[^/]+}", {
+ {
+ method = "GET",
+ path = "/",
+ produces = "text/plain",
+ handler = function(query, name)
+ local basedir = arg[1] or "./spec/fixtures"
+ local fd = io.open(basedir .. "/" .. name, "rb")
+ if not fd then
+ return restserver.response():status(404)
+ end
+ local data = fd:read("*a")
+ fd:close()
+ return restserver.response():status(200):entity(data)
+ end
+ }
+})
+
+-- SHUTDOWN this mock-server
+server:add_resource("/shutdown", {
+ {
+ method = "GET",
+ path = "/",
+ handler = function(query)
+ os.exit()
+ return restserver.response():status(200):entity()
+ end
+ }
+})
+
+-- This loads the restserver.xavante plugin
+server:enable("restserver.xavante"):start()
diff --git a/spec/util/quick.lua b/spec/util/quick.lua
new file mode 100644
index 0000000..a525aa9
--- /dev/null
+++ b/spec/util/quick.lua
@@ -0,0 +1,472 @@
+local quick = {}
+
+local dir_sep = package.config:sub(1, 1)
+
+local cfg, dir, fs, versions
+local initialized = false
+
+local function initialize()
+ if initialized then
+ return
+ end
+ initialized = true
+
+ cfg = require("luarocks.core.cfg")
+ dir = require("luarocks.dir")
+ fs = require("luarocks.fs")
+ versions = require("spec.util.versions")
+ cfg.init()
+ fs.init()
+end
+
+local function native_slash(pathname)
+ return (pathname:gsub("[/\\]", dir_sep))
+end
+
+local function parse_cmd(line)
+ local cmd, arg = line:match("^%s*([A-Z_]+):%s*(.*)%s*$")
+ return cmd, arg
+end
+
+local function is_blank(line)
+ return not not line:match("^%s*$")
+end
+
+local function is_hr(line)
+ return not not line:match("^%-%-%-%-%-")
+end
+
+local function parse(filename)
+ local fd = assert(io.open(filename, "rb"))
+ local input = assert(fd:read("*a"))
+ fd:close()
+
+ initialize()
+
+ local tests = {}
+
+ local cur_line = 0
+ local cur_suite = ""
+ local cur_test
+ local cur_op
+ local cur_block
+ local cur_block_name
+ local stack = { "start" }
+
+ local function start_test(arg)
+ cur_test = {
+ name = cur_suite .. arg,
+ ops = {},
+ }
+ cur_op = nil
+ table.insert(tests, cur_test)
+ table.insert(stack, "test")
+ end
+
+ local function fail(msg)
+ io.stderr:write("Error reading " .. filename .. ":" .. cur_line .. ": " .. msg .. "\n")
+ os.exit(1)
+ end
+
+ local function bool_arg(cmd, cur, field, arg)
+ if arg ~= "true" and arg ~= "false" then
+ fail(cmd .. " argument must be 'true' or 'false'")
+ end
+ cur[field] = (arg == "true")
+ end
+
+ local function block_start_arg(cmd, cur, field)
+ if not cur or cur.op ~= "RUN" then
+ fail(cmd .. " must be given in the context of a RUN")
+ end
+ if cur[field] then
+ fail(cmd .. " was already declared")
+ end
+
+ cur[field] = {
+ data = {}
+ }
+ cur_block = cur[field]
+ cur_block_name = cmd
+ table.insert(stack, "block start")
+ end
+
+ local test_env = require("spec.util.test_env")
+ local function expand_vars(line)
+ if not line then
+ return nil
+ end
+ return (line:gsub("%%%b{}", function(var)
+ var = var:sub(3, -2)
+ local fn, fnarg = var:match("^%s*([a-z_]+)%s*%(%s*([^)]+)%s*%)%s*$")
+
+ local value
+ if var == "tmpdir" then
+ value = "%{tmpdir}"
+ elseif var == "url(%{tmpdir})" then
+ value = "%{url(%{tmpdir})}"
+ elseif fn == "url" then
+ value = expand_vars(fnarg)
+ value = value:gsub("\\", "/")
+ elseif fn == "path" then
+ value = expand_vars(fnarg)
+ value = value:gsub("[/\\]", dir_sep)
+ elseif fn == "version" then
+ value = versions[fnarg:lower()] or ""
+ elseif fn == "version_" then
+ value = (versions[fnarg:lower()] or ""):gsub("[%.%-]", "_")
+ else
+ value = test_env.testing_paths[var]
+ or test_env.env_variables[var]
+ or test_env[var]
+ or ""
+ end
+
+ return value
+ end))
+ end
+
+ if input:sub(#input, #input) ~= "\n" then
+ input = input .. "\n"
+ end
+
+ for line in input:gmatch("([^\r\n]*)\r?\n?") do
+ cur_line = cur_line + 1
+
+ local state = stack[#stack]
+ if state == "start" then
+ local cmd, arg = parse_cmd(line)
+ if cmd == "TEST" then
+ start_test(arg)
+ elseif cmd == "SUITE" then
+ cur_suite = arg .. ": "
+ elseif cmd then
+ fail("expected TEST, got " .. cmd)
+ elseif is_blank(line) then
+ -- skip blank lines and arbitrary text,
+ -- which is interpreted as a comment
+ end
+ elseif state == "test" then
+ local cmd, arg = parse_cmd(line)
+ arg = expand_vars(arg)
+ if cmd == "FILE" then
+ cur_op = {
+ op = "FILE",
+ name = arg,
+ data = {},
+ }
+ table.insert(cur_test.ops, cur_op)
+ cur_block = cur_op
+ cur_block_name = "FILE"
+ table.insert(stack, "block start")
+ elseif cmd == "FILE_CONTENTS" then
+ cur_op = {
+ op = "FILE_CONTENTS",
+ name = arg,
+ data = {},
+ }
+ table.insert(cur_test.ops, cur_op)
+ cur_block = cur_op
+ cur_block_name = "FILE_CONTENTS"
+ table.insert(stack, "block start")
+ elseif cmd == "RUN" then
+ local program, args = arg:match("([^ ]+)%s*(.*)$")
+ if not program then
+ fail("expected a program argument in RUN")
+ end
+
+ cur_op = {
+ op = "RUN",
+ exit = 0,
+ exit_line = cur_line,
+ line = cur_line,
+ program = program,
+ args = args,
+ }
+ table.insert(cur_test.ops, cur_op)
+ elseif cmd == "EXISTS" then
+ cur_op = {
+ op = "EXISTS",
+ name = dir.normalize(arg),
+ line = cur_line,
+ }
+ table.insert(cur_test.ops, cur_op)
+ elseif cmd == "NOT_EXISTS" then
+ cur_op = {
+ op = "NOT_EXISTS",
+ name = dir.normalize(arg),
+ line = cur_line,
+ }
+ table.insert(cur_test.ops, cur_op)
+ elseif cmd == "MKDIR" then
+ cur_op = {
+ op = "MKDIR",
+ name = dir.normalize(arg),
+ line = cur_line,
+ }
+ table.insert(cur_test.ops, cur_op)
+ elseif cmd == "RMDIR" then
+ cur_op = {
+ op = "RMDIR",
+ name = dir.normalize(arg),
+ line = cur_line,
+ }
+ table.insert(cur_test.ops, cur_op)
+ elseif cmd == "RM" then
+ cur_op = {
+ op = "RM",
+ name = dir.normalize(arg),
+ line = cur_line,
+ }
+ table.insert(cur_test.ops, cur_op)
+ elseif cmd == "EXIT" then
+ if not cur_op or cur_op.op ~= "RUN" then
+ fail("EXIT must be given in the context of a RUN")
+ end
+
+ local code = tonumber(arg)
+ if not code and not (code >= 0 and code <= 128) then
+ fail("EXIT code must be a number in the range 0-128, got " .. arg)
+ end
+
+ cur_op.exit = code
+ cur_op.exit_line = cur_line
+ elseif cmd == "VERBOSE" then
+ if not cur_op or cur_op.op ~= "RUN" then
+ fail("VERBOSE must be given in the context of a RUN")
+ end
+
+ bool_arg("VERBOSE", cur_op, "verbose", arg)
+ elseif cmd == "STDERR" then
+ block_start_arg("STDERR", cur_op, "stderr")
+ elseif cmd == "NOT_STDERR" then
+ block_start_arg("NOT_STDERR", cur_op, "not_stderr")
+ elseif cmd == "STDOUT" then
+ block_start_arg("STDOUT", cur_op, "stdout")
+ elseif cmd == "NOT_STDOUT" then
+ block_start_arg("NOT_STDOUT", cur_op, "not_stdout")
+ elseif cmd == "PENDING" then
+ bool_arg("PENDING", cur_test, "pending", arg)
+ elseif cmd == "TEST" then
+ table.remove(stack)
+ start_test(arg)
+ elseif cmd then
+ fail("expected a command, got " .. cmd)
+ else
+ -- skip blank lines and arbitrary text,
+ -- which is interpreted as a comment
+ end
+ elseif state == "block start" then
+ local cmd, arg = parse_cmd(line)
+ if is_blank(line) then
+ -- skip
+ elseif is_hr(line) then
+ stack[#stack] = "block data"
+ cur_block.start = cur_line
+ elseif cmd == "PLAIN" then
+ bool_arg("PLAIN", cur_block, "plain", arg)
+ else
+ fail("expected '-----' to start " .. cur_block_name .. " block")
+ end
+ elseif state == "block data" then
+ if is_hr(line) then
+ cur_block = nil
+ table.remove(stack)
+ else
+ if not cur_block.plain then
+ line = expand_vars(line)
+ end
+ table.insert(cur_block.data, line)
+ end
+ end
+ end
+
+ return tests
+end
+
+local function check_output(write, block, block_name, data_var)
+ if block then
+ local is_positive = not block_name:match("NOT")
+ local err_msg = is_positive and "did not match" or "did match unwanted output"
+
+ write([=[ do ]=])
+ write([=[ local block_at = 1 ]=])
+ write([=[ local s, e, line, ok ]=])
+ for i, line in ipairs(block.data) do
+ write(([=[ line = %q ]=]):format(line))
+ write(([=[ s, e = string.find(%s, line, block_at, true) ]=]):format(data_var))
+ write(is_positive and ([=[ ok = s; if e then block_at = e + 1 end ]=]):format(i)
+ or ([=[ ok = not s ]=]))
+ write(([=[ assert(ok, error_message(%d, "%s %s: " .. line, %s)) ]=]):format(block.start + i, block_name, err_msg, data_var))
+ end
+ write([=[ end ]=])
+ end
+end
+
+function quick.compile(filename, env)
+ local tests = parse(filename)
+
+-- local dev_null = (package.config:sub(1, 1) == "/")
+-- and "/dev/null"
+-- or "NUL"
+
+ local cmd_helpers = {
+ ["luarocks"] = "luarocks_cmd",
+ ["luarocks-admin"] = "luarocks_admin_cmd",
+ }
+
+ for tn, t in ipairs(tests) do
+ local code = {}
+ local function write(...)
+ table.insert(code, table.concat({...}))
+ end
+
+ write(([=[ ]=]))
+ write(([=[ -- **************************************** ]=]))
+ write(([=[ -- %s ]=]):format(t.name))
+ write(([=[ -- **************************************** ]=]))
+ write(([=[ ]=]))
+
+ write([=[ local test_env = require("spec.util.test_env") ]=])
+ write([=[ local lfs = require("lfs") ]=])
+ write([=[ local fs = require("lfs") ]=])
+ write([=[ local dir_sep = package.config:sub(1, 1) ]=])
+ write([=[ local coverage = " -e \"require('luacov.runner')([[" .. test_env.testing_paths.testrun_dir .. dir_sep .. "luacov.config]])\" " ]=])
+ write([=[ local luarocks_cmd = test_env.execute_helper(test_env.Q(test_env.testing_paths.lua) .. coverage .. " " .. test_env.testing_paths.src_dir .. "/bin/luarocks", false, test_env.env_variables):sub(1, -5) ]=])
+ write([=[ local luarocks_admin_cmd = test_env.execute_helper(test_env.Q(test_env.testing_paths.lua) .. coverage .. " " .. test_env.testing_paths.src_dir .. "/bin/luarocks-admin", false, test_env.env_variables):sub(1, -5) ]=])
+
+ write([=[ local function make_dir(dirname) ]=])
+ write([=[ local bits = {} ]=])
+ write([=[ if dirname:sub(1, 1) == dir_sep then bits[1] = "" end ]=])
+ write([=[ local ok, err ]=])
+ write([=[ for p in dirname:gmatch("[^" .. dir_sep .. "]+") do ]=])
+ write([=[ table.insert(bits, p) ]=])
+ write([=[ ok, err = lfs.mkdir(table.concat(bits, dir_sep)) ]=])
+ write([=[ end ]=])
+ write([=[ local exists = (lfs.attributes(dirname) or {}).mode == "directory" ]=])
+ write([=[ return exists, (not exists) and err ]=])
+ write([=[ end ]=])
+
+ write(([=[ local function error_message(line, msg, input) ]=]))
+ write(([=[ local out = {"\n\n", %q, ":", line, ": ", msg} ]=]):format(filename))
+ write(([=[ if input then ]=]))
+ write(([=[ if input:match("\n") then ]=]))
+ write(([=[ table.insert(out, "\n") ]=]))
+ write(([=[ table.insert(out, ("-"):rep(40)) ]=]))
+ write(([=[ table.insert(out, "\n") ]=]))
+ write(([=[ table.insert(out, input) ]=]))
+ write(([=[ table.insert(out, ("-"):rep(40)) ]=]))
+ write(([=[ table.insert(out, "\n") ]=]))
+ write(([=[ else ]=]))
+ write(([=[ table.insert(out, ": ") ]=]))
+ write(([=[ table.insert(out, input) ]=]))
+ write(([=[ end ]=]))
+ write(([=[ end ]=]))
+ write(([=[ return table.concat(out) ]=]))
+ write(([=[ end ]=]))
+
+ write([=[ return function() ]=])
+ write([=[ test_env.run_in_tmp(function(tmpdir) ]=])
+ write([=[ local function handle_tmpdir(s) ]=])
+ write([=[ return (s:gsub("%%{url%(%%{tmpdir}%)}", (tmpdir:gsub("\\", "/"))) ]=])
+ write([=[ :gsub("%%{tmpdir}", (tmpdir:gsub("[\\/]", dir_sep)))) ]=])
+ write([=[ end ]=])
+ write([=[ local ok, err ]=])
+ for _, op in ipairs(t.ops) do
+ if op.name then
+ op.name = native_slash(op.name)
+ write(([=[ local name = handle_tmpdir(%q) ]=]):format(op.name))
+ end
+ if op.op == "FILE" then
+ if op.name:match("[\\/]") then
+ write(([=[ make_dir(handle_tmpdir(%q)) ]=]):format(dir.dir_name(op.name)))
+ end
+ write([=[ test_env.write_file(name, handle_tmpdir([=====[ ]=])
+ for _, line in ipairs(op.data) do
+ write(line)
+ end
+ write([=[ ]=====]), finally) ]=])
+ elseif op.op == "EXISTS" then
+ write(([=[ ok, err = lfs.attributes(name) ]=]))
+ write(([=[ assert.truthy(ok, error_message(%d, "EXISTS failed: " .. name .. " - " .. (err or "") )) ]=]):format(op.line))
+ elseif op.op == "NOT_EXISTS" then
+ write(([=[ assert.falsy(lfs.attributes(name), error_message(%d, "NOT_EXISTS failed: " .. name .. " exists" )) ]=]):format(op.line))
+ elseif op.op == "MKDIR" then
+ write(([=[ ok, err = make_dir(name) ]=]))
+ write(([=[ assert.truthy((lfs.attributes(name) or {}).mode == "directory", error_message(%d, "MKDIR failed: " .. name .. " - " .. (err or "") )) ]=]):format(op.line))
+ elseif op.op == "RMDIR" then
+ write(([=[ ok, err = test_env.remove_dir(name) ]=]))
+ write(([=[ assert.falsy((lfs.attributes(name) or {}).mode == "directory", error_message(%d, "MKDIR failed: " .. name .. " - " .. (err or "") )) ]=]):format(op.line))
+ elseif op.op == "RM" then
+ write(([=[ ok, err = os.remove(name) ]=]))
+ write(([=[ assert.falsy((lfs.attributes(name) or {}).mode == "file", error_message(%d, "RM failed: " .. name .. " - " .. (err or "") )) ]=]):format(op.line))
+ elseif op.op == "FILE_CONTENTS" then
+ write(([=[ do ]=]))
+ write(([=[ local fd_file = assert(io.open(name, "rb")) ]=]))
+ write(([=[ local file_data = fd_file:read("*a") ]=]))
+ write(([=[ fd_file:close() ]=]))
+ write([=[ local block_at = 1 ]=])
+ write([=[ local s, e, line ]=])
+ for i, line in ipairs(op.data) do
+ write(([=[ line = %q ]=]):format(line))
+ write(([=[ s, e = string.find(file_data, line, 1, true) ]=]))
+ write(([=[ assert(s, error_message(%d, "FILE_CONTENTS " .. name .. " did not match: " .. line, file_data)) ]=]):format(op.start + i))
+ write(([=[ block_at = e + 1 ]=]):format(i))
+ end
+ write([=[ end ]=])
+ elseif op.op == "RUN" then
+ local cmd_helper = cmd_helpers[op.program] or ("%q"):format(op.program)
+ local redirs = " 1>stdout.txt 2>stderr.txt "
+ write(([=[ local ok, _, code = os.execute(%s .. " " .. %q .. %q) ]=]):format(cmd_helper, op.args, redirs))
+ write([=[ if type(ok) == "number" then code = (ok >= 256 and ok / 256 or ok) end ]=])
+
+ write([=[ local fd_stderr = assert(io.open("stderr.txt", "rb")) ]=])
+ write([=[ local stderr_data = fd_stderr:read("*a") ]=])
+ write([=[ fd_stderr:close() ]=])
+
+ write([=[ if stderr_data:match("please report") then ]=])
+ write(([=[ assert(false, error_message(%d, "RUN crashed: ", stderr_data)) ]=]):format(op.line))
+ write([=[ end ]=])
+
+ if op.stdout or op.not_stdout or op.verbose then
+ write([=[ local fd_stdout = assert(io.open("stdout.txt", "rb")) ]=])
+ write([=[ local stdout_data = fd_stdout:read("*a") ]=])
+ write([=[ fd_stdout:close() ]=])
+ end
+
+ if op.verbose then
+ write([=[ print() ]=])
+ write([=[ print("STDOUT: --" .. ("-"):rep(70)) ]=])
+ write([=[ print(stdout_data) ]=])
+ write([=[ print("STDERR: --" .. ("-"):rep(70)) ]=])
+ write([=[ print(stderr_data) ]=])
+ write([=[ print(("-"):rep(80)) ]=])
+ write([=[ print() ]=])
+ end
+
+ check_output(write, op.stdout, "STDOUT", "stdout_data")
+ check_output(write, op.stderr, "STDERR", "stderr_data")
+
+ check_output(write, op.not_stdout, "NOT_STDOUT", "stdout_data")
+ check_output(write, op.not_stderr, "NOT_STDERR", "stderr_data")
+
+ if op.exit then
+ write(([=[ assert.same(%d, code, error_message(%d, "EXIT did not match: " .. %d, stderr_data)) ]=]):format(op.exit, op.exit_line, op.exit))
+ end
+ end
+ end
+ write([=[ end, finally) ]=])
+ write([=[ end ]=])
+
+ local program = table.concat(code, "\n")
+ local chunk = assert(load(program, "@" .. filename .. ":[TEST " .. tn .. "]", "t", env or _ENV))
+ if env and setfenv then
+ setfenv(chunk, env)
+ end
+ t.fn = chunk()
+ end
+
+ return tests
+end
+
+return quick
diff --git a/spec/util/test_env.lua b/spec/util/test_env.lua
new file mode 100644
index 0000000..92fb193
--- /dev/null
+++ b/spec/util/test_env.lua
@@ -0,0 +1,1187 @@
+local test_env = {}
+
+local lfs = require("lfs")
+local versions = require("spec.util.versions")
+
+local help_message = [[
+LuaRocks test-suite
+
+INFORMATION
+ New test-suite for LuaRocks project, using unit testing framework Busted.
+REQUIREMENTS
+ Be sure sshd is running on your system, or use '--exclude-tags=ssh',
+ to not execute tests which require sshd.
+USAGE
+ busted [-Xhelper <arguments>]
+ARGUMENTS
+ env=<type> Set type of environment to use ("minimal" or "full",
+ default: "minimal").
+ noreset Don't reset environment after each test
+ clean Remove existing testing environment.
+ ci Add if running on Unix CI.
+ appveyor Add if running on Appveyor.
+ os=<type> Set OS ("linux", "osx", or "windows").
+ lua_dir=<path> Path of Lua installation (default "/usr/local")
+ lua=<lua> Name of the interpreter, may be full path (default "lua")
+]]
+
+local function help()
+ print(help_message)
+ os.exit(1)
+end
+
+local function title(str)
+ print()
+ print(("-"):rep(#str))
+ print(str)
+ print(("-"):rep(#str))
+end
+
+local dir_sep = package.config:sub(1, 1)
+local function P(p)
+ return (p:gsub("/", dir_sep))
+end
+
+local function dir_path(...)
+ return P((table.concat({ ... }, "/"):gsub("\\", "/"):gsub("/+", "/")))
+end
+
+local function C(...)
+ return table.concat({...}, " ")
+end
+
+--- Quote argument for shell processing. Fixes paths on Windows.
+-- Adds double quotes and escapes. Based on function in fs/win32.lua.
+-- @param arg string: Unquoted argument.
+-- @return string: Quoted argument.
+local function Q(arg)
+ if test_env.TEST_TARGET_OS == "windows" then
+ local drive_letter = "[%.a-zA-Z]?:?[\\/]"
+ -- Quote DIR for Windows
+ if arg:match("^"..drive_letter) then
+ arg = P(arg)
+ end
+
+ if arg == "\\" then
+ return '\\' -- CHDIR needs special handling for root dir
+ end
+
+ return '"' .. arg .. '"'
+ else
+ return "'" .. arg:gsub("'", "'\\''") .. "'"
+ end
+end
+
+local function V(str)
+ return (str:gsub("${([^}]-)}", function(name)
+ name = name:lower()
+ local prefix, suffix = name:match("^(.*)_(.)$")
+ if suffix then
+ name = prefix
+ local d = assert(versions[name])
+ local v, r = d:match("^([^-]*)%-(%d*)$")
+ if suffix == "d" then
+ return d
+ elseif suffix == "v" then
+ return v
+ elseif suffix == "r" then
+ return r
+ else
+ print("Test error: invalid suffix " .. suffix .. " in variable " .. name)
+ os.exit(1)
+ end
+ else
+ if not versions[name] then
+ print("Test error: no version definition for " .. name)
+ os.exit(1)
+ end
+ return versions[name]
+ end
+ end))
+end
+
+local function tool(name)
+ if test_env.TEST_TARGET_OS == "windows" then
+ return Q(dir_path(test_env.testing_paths.win_tools, name .. ".exe"))
+ else
+ return name
+ end
+end
+
+local os_remove = os.remove
+os.remove = function(f) -- luacheck: ignore
+ return os_remove(V(f))
+end
+
+local os_rename = os.rename
+os.rename = function(a, b) -- luacheck: ignore
+ return os_rename(V(a), V(b))
+end
+
+-- Monkeypatch incorrect tmpname's on some Lua distributions for Windows
+local os_tmpname = os.tmpname
+os.tmpname = function() -- luacheck:ignore
+ local name = os_tmpname()
+ if name:sub(1, 1) == '\\' then
+ name = os.getenv "TEMP"..name
+ end
+ return name
+end
+
+local lfs_chdir = lfs.chdir
+lfs.chdir = function(d) -- luacheck: ignore
+ return lfs_chdir(V(d))
+end
+
+local lfs_attributes = lfs.attributes
+lfs.attributes = function(f, ...) -- luacheck: ignore
+ return lfs_attributes(V(f), ...)
+end
+
+local function exists(path)
+ return lfs.attributes(path, "mode") ~= nil
+end
+
+function test_env.file_if_exists(path)
+ return lfs.attributes(path, "mode") and path
+end
+
+function test_env.quiet(command)
+ if not test_env.VERBOSE then
+ if test_env.TEST_TARGET_OS == "windows" then
+ return command .. " 1> NUL 2> NUL"
+ else
+ return command .. " 1> /dev/null 2> /dev/null"
+ end
+ else
+ return command
+ end
+end
+
+function test_env.copy(source, destination)
+ source = V(source)
+ destination = V(destination)
+
+ local r_source, r_destination, err
+ r_source, err = io.open(source, "r")
+ if err then
+ print(debug.traceback())
+ os.exit(1)
+ end
+
+ r_destination, err = io.open(destination, "w")
+ if err then
+ print(debug.traceback())
+ os.exit(1)
+ end
+
+ while true do
+ local block = r_source:read(8192)
+ if not block then break end
+ r_destination:write(block)
+ end
+
+ r_source:close()
+ r_destination:close()
+end
+
+function test_env.get_tmp_path()
+ local path = os.tmpname()
+ if test_env.TEST_TARGET_OS == "windows" and not path:find(":") then
+ path = dir_path(os.getenv("TEMP"), path)
+ end
+ os.remove(path)
+ return path
+end
+
+--- Helper function that runs the given function inside
+-- a temporary directory, isolating it
+-- @param f function: the function to be run
+function test_env.run_in_tmp(f, finally)
+ local olddir = lfs.currentdir()
+ local tmpdir = test_env.get_tmp_path()
+ lfs.mkdir(tmpdir)
+ lfs.chdir(tmpdir)
+
+ if not finally then
+ error("run_in_tmp needs a finally argument")
+ end
+
+ -- for unit tests, so that current dir known by luarocks.fs (when running with non-lfs)
+ -- is synchronized with actual lfs (system) current dir
+ local fs = require("luarocks.fs")
+ if not fs.change_dir then
+ local cfg = require("luarocks.core.cfg")
+ cfg.init()
+ fs.init()
+ end
+ fs.change_dir(tmpdir)
+
+ local lr_config = test_env.env_variables.LUAROCKS_CONFIG
+
+ test_env.copy(lr_config, lr_config .. ".bak")
+
+ finally(function()
+ test_env.copy(lr_config .. ".bak", lr_config)
+ lfs.chdir(olddir)
+ lfs.rmdir(tmpdir)
+ fs.change_dir(olddir)
+ end)
+
+ f(tmpdir)
+end
+
+--- Helper function for execute_bool and execute_output
+-- @param command string: command to execute
+-- @param print_command boolean: print command if 'true'
+-- @param env_variables table: table of environment variables to export {FOO="bar", BAR="foo"}
+-- @return final_command string: concatenated command to execution
+function test_env.execute_helper(command, print_command, env_variables)
+ local final_command = ""
+
+ if print_command then
+ print("[EXECUTING]: " .. command)
+ end
+
+ local unset_variables = {
+ "LUA_PATH",
+ "LUA_CPATH",
+ "LUA_PATH_5_2",
+ "LUA_CPATH_5_2",
+ "LUA_PATH_5_3",
+ "LUA_CPATH_5_3",
+ "LUAROCKS_SYSCONFDIR",
+ }
+
+ if env_variables then
+ if test_env.TEST_TARGET_OS == "windows" then
+ for _, k in ipairs(unset_variables) do
+ final_command = final_command .. "set " .. k .. "=&"
+ end
+ for k,v in pairs(env_variables) do
+ final_command = final_command .. "set " .. k .. "=" .. v .. "&"
+ end
+ final_command = final_command:sub(1, -2) .. "&"
+ else
+ for _, k in ipairs(unset_variables) do
+ final_command = final_command .. "unset " .. k .. "; "
+ end
+ final_command = final_command .. "export "
+ for k,v in pairs(env_variables) do
+ final_command = final_command .. k .. "='" .. v .. "' "
+ end
+ -- remove last space and add ';' to separate exporting variables from command
+ final_command = final_command:sub(1, -2) .. "; "
+ end
+ end
+
+ final_command = final_command .. command .. " 2>&1"
+
+ return final_command
+end
+
+function test_env.execute(cmd)
+ local ok = os.execute(cmd)
+ return (ok == true or ok == 0) -- normalize Lua 5.1 output to boolean
+end
+
+--- Execute command and returns true/false
+-- @return true/false boolean: status of the command execution
+local function execute_bool(command, print_command, env_variables)
+ command = test_env.execute_helper(command, print_command, env_variables)
+
+ local redirect_filename
+ local redirect = ""
+ if print_command ~= nil then
+ redirect_filename = dir_path(test_env.testing_paths.luarocks_tmp, "output.txt")
+ redirect = " > " .. redirect_filename
+ os.remove(redirect_filename)
+ end
+ local ok = test_env.execute(command .. redirect)
+ if redirect ~= "" then
+ if not ok or test_env.VERBOSE then
+ local fd = io.open(redirect_filename, "r")
+ if fd then
+ print(fd:read("*a"))
+ fd:close()
+ end
+ end
+ os.remove(redirect_filename)
+ end
+ return ok
+end
+
+--- Execute command and returns output of command
+-- @return output string: output the command execution
+local function execute_output(command, print_command, env_variables)
+ command = test_env.execute_helper(command, print_command, env_variables)
+
+ local file = assert(io.popen(command))
+ local output = file:read('*all')
+ file:close()
+ return (output:gsub("\r\n", "\n"):gsub("\n$", "")) -- remove final newline
+end
+
+--- Set test_env.LUA_V or test_env.LUAJIT_V based
+-- on version of Lua used to run this script.
+function test_env.set_lua_version()
+ if _G.jit then
+ test_env.LUAJIT_V = _G.jit.version:match("(2%.%d)%.%d")
+ test_env.lua_version = "5.1"
+ else
+ test_env.LUA_V = _VERSION:match("5%.%d")
+ test_env.lua_version = test_env.LUA_V
+ end
+end
+
+--- Set all arguments from input into global variables
+function test_env.set_args()
+ -- if at least Lua/LuaJIT version argument was found on input start to parse other arguments to env. variables
+ test_env.TYPE_TEST_ENV = "minimal"
+ test_env.RESET_ENV = true
+
+ for _, argument in ipairs(arg) do
+ if argument:find("^env=") then
+ test_env.TYPE_TEST_ENV = argument:match("^env=(.*)$")
+ elseif argument == "noreset" then
+ test_env.RESET_ENV = false
+ elseif argument == "clean" then
+ test_env.TEST_ENV_CLEAN = true
+ elseif argument == "verbose" then
+ test_env.VERBOSE = true
+ elseif argument == "ci" then
+ test_env.CI = true
+ elseif argument == "appveyor" then
+ test_env.APPVEYOR = true
+ elseif argument:find("^os=") then
+ test_env.TEST_TARGET_OS = argument:match("^os=(.*)$")
+ elseif argument == "mingw" then
+ test_env.MINGW = true
+ elseif argument == "vs" then
+ test_env.MINGW = false
+ elseif argument:find("^lua_dir=") then
+ test_env.LUA_DIR = argument:match("^lua_dir=(.*)$")
+ elseif argument:find("^lua=") then
+ test_env.LUA = argument:match("^lua=(.*)$")
+ else
+ help()
+ end
+ end
+
+ if not test_env.TEST_TARGET_OS then
+ title("OS CHECK")
+
+ if dir_sep == "\\" then
+ test_env.TEST_TARGET_OS = "windows"
+ if test_env.APPVEYOR then
+ test_env.OPENSSL_INCDIR = "C:\\OpenSSL-v111-Win32\\include"
+ test_env.OPENSSL_LIBDIR = "C:\\OpenSSL-v111-Win32\\lib"
+ if test_env.MINGW then
+ test_env.OPENSSL_LIBDIR = "C:\\OpenSSL-v111-Win32\\bin"
+ end
+ end
+ else
+ local system = execute_output("uname -s")
+ if system == "Linux" then
+ test_env.TEST_TARGET_OS = "linux"
+ if test_env.CI then
+ test_env.OPENSSL_INCDIR = "/usr/include"
+ test_env.OPENSSL_LIBDIR = "/usr/lib/x86_64-linux-gnu"
+ end
+ elseif system == "Darwin" then
+ test_env.TEST_TARGET_OS = "osx"
+ if test_env.CI then
+ if exists("/opt/homebrew/opt/openssl@3/include") then
+ test_env.OPENSSL_INCDIR = "/opt/homebrew/opt/openssl@3/include"
+ test_env.OPENSSL_LIBDIR = "/opt/homebrew/opt/openssl@3/lib"
+ elseif exists("/opt/homebrew/opt/openssl@1.1/include") then
+ test_env.OPENSSL_INCDIR = "/opt/homebrew/opt/openssl@1.1/include"
+ test_env.OPENSSL_LIBDIR = "/opt/homebrew/opt/openssl@1.1/lib"
+ elseif exists("/opt/homebrew/opt/openssl/include") then
+ test_env.OPENSSL_INCDIR = "/opt/homebrew/opt/openssl/include"
+ test_env.OPENSSL_LIBDIR = "/opt/homebrew/opt/openssl/lib"
+ else
+ test_env.OPENSSL_INCDIR = "/usr/local/opt/openssl/include"
+ test_env.OPENSSL_LIBDIR = "/usr/local/opt/openssl/lib"
+ end
+ end
+ end
+ end
+ print(test_env.TEST_TARGET_OS)
+ end
+
+ if test_env.TEST_TARGET_OS == "windows" then
+ test_env.lib_extension = "dll"
+ else
+ test_env.lib_extension = "so"
+ end
+
+ test_env.openssl_dirs = ""
+ if test_env.OPENSSL_INCDIR then
+ test_env.openssl_dirs = C("OPENSSL_INCDIR=" .. test_env.OPENSSL_INCDIR,
+ "OPENSSL_LIBDIR=" .. test_env.OPENSSL_LIBDIR)
+ end
+
+ return true
+end
+
+function test_env.copy_dir(source_path, target_path)
+ source_path = V(source_path)
+ target_path = V(target_path)
+
+ local flag = test_env.TEST_TARGET_OS == "windows" and "-R" or "-a"
+ os.execute(C(tool("cp"), flag, dir_path(source_path, "."), target_path))
+end
+
+--- Remove directory recursively
+-- @param path string: directory path to delete
+function test_env.remove_dir(path)
+ path = V(path)
+
+ if exists(path) then
+ for file in lfs.dir(path) do
+ if file ~= "." and file ~= ".." then
+ local full_path = dir_path(path, file)
+
+ if lfs.attributes(full_path, "mode") == "directory" then
+ test_env.remove_dir(full_path)
+ else
+ os.remove(full_path)
+ end
+ end
+ end
+ end
+ lfs.rmdir(path)
+end
+
+--- Remove subdirectories of a directory that match a pattern
+-- @param path string: path to directory
+-- @param pattern string: pattern matching basenames of subdirectories to be removed
+function test_env.remove_subdirs(path, pattern)
+ path = V(path)
+
+ if exists(path) then
+ for file in lfs.dir(path) do
+ if file ~= "." and file ~= ".." then
+ local full_path = dir_path(path, file)
+
+ if lfs.attributes(full_path, "mode") == "directory" and file:find(pattern) then
+ test_env.remove_dir(full_path)
+ end
+ end
+ end
+ end
+end
+
+--- Remove files matching a pattern
+-- @param path string: directory where to delete files
+-- @param pattern string: pattern matching basenames of files to be deleted
+-- @return result_check boolean: true if one or more files deleted
+function test_env.remove_files(path, pattern)
+ path = V(path)
+
+ local result_check = false
+ if exists(path) then
+ for file in lfs.dir(path) do
+ if file ~= "." and file ~= ".." then
+ if file:find(pattern) then
+ if os.remove(dir_path(path, file)) then
+ result_check = true
+ end
+ end
+ end
+ end
+ end
+ return result_check
+end
+
+
+--- Function for downloading rocks and rockspecs
+-- @param urls table: array of full names of rocks/rockspecs to download
+-- @param save_path string: path to directory, where to download rocks/rockspecs
+-- @return make_manifest boolean: true if new rocks downloaded
+local function download_rocks(urls, save_path)
+ local luarocks_repo = "https://luarocks.org/"
+
+ local to_download = {}
+ local fixtures = {}
+ for _, url in ipairs(urls) do
+ url = V(url)
+
+ if url:match("^spec/fixtures") then
+ table.insert(fixtures, P(url:gsub("^spec/fixtures", test_env.testing_paths.fixtures_dir)))
+ else
+ -- check if already downloaded
+ if not exists(dir_path(save_path, url)) then
+ table.insert(to_download, ((luarocks_repo .. url):gsub("org//", "org/")))
+ end
+ end
+ end
+
+ if #fixtures > 0 then
+ os.execute(C(tool("cp"), table.concat(fixtures, " "), save_path))
+ end
+
+ if #to_download > 0 then
+ local ok = execute_bool(C(tool("wget"), "--no-check-certificate -cP", save_path, table.concat(to_download, " ")))
+ if not ok then
+ os.exit(1)
+ end
+ end
+
+ return (#fixtures > 0) or (#to_download > 0)
+end
+
+--- Create a file containing a string.
+-- @param pathname string: path to file.
+-- @param str string: content of the file.
+function test_env.write_file(pathname, str, finally)
+ pathname = V(pathname)
+
+ local file = assert(io.open(pathname, "wb"))
+ file:write(str)
+ file:close()
+ if finally then
+ finally(function()
+ os.remove(pathname)
+ end)
+ end
+end
+
+--- Create environment variables needed for tests
+-- @param testing_paths table: table with paths to testing directory
+-- @return env_variables table: table with created environment variables
+local function create_env(testing_paths)
+ local lua_v = _VERSION:gsub("Lua ", "")
+ local testrun_dir = test_env.testing_paths.testrun_dir
+ local lrprefix = testing_paths.testing_lrprefix
+ local tree = testing_paths.testing_tree
+ local sys_tree = testing_paths.testing_sys_tree
+ local deps_tree = testing_paths.testing_deps_tree
+
+ if test_env.LUAJIT_V then
+ lua_v="5.1"
+ end
+
+ local env_variables = {}
+ env_variables.GNUPGHOME = testing_paths.gpg_dir
+ env_variables.LUA_VERSION = lua_v
+ env_variables.LUAROCKS_CONFIG = dir_path(testrun_dir, "testing_config.lua")
+
+ local lua_path = {}
+ if test_env.TEST_TARGET_OS == "windows" then
+ table.insert(lua_path, dir_path(lrprefix, "lua", "?.lua"))
+ else
+ table.insert(lua_path, dir_path(lrprefix, "share", "lua", lua_v, "?.lua"))
+ end
+ table.insert(lua_path, dir_path(tree, "share", "lua", lua_v, "?.lua"))
+ table.insert(lua_path, dir_path(tree, "share", "lua", lua_v, "?", "init.lua"))
+ table.insert(lua_path, dir_path(sys_tree, "share", "lua", lua_v, "?.lua"))
+ table.insert(lua_path, dir_path(sys_tree, "share", "lua", lua_v, "?", "init.lua"))
+ table.insert(lua_path, dir_path(deps_tree, "share", "lua", lua_v, "?.lua"))
+ table.insert(lua_path, dir_path(deps_tree, "share", "lua", lua_v, "?", "init.lua"))
+ table.insert(lua_path, dir_path(testing_paths.src_dir, "?.lua"))
+ env_variables.LUA_PATH = table.concat(lua_path, ";") .. ";"
+
+ local lua_cpath = {}
+ local lib_pattern = "?." .. test_env.lib_extension
+ table.insert(lua_cpath, dir_path(tree, "lib", "lua", lua_v, lib_pattern))
+ table.insert(lua_cpath, dir_path(sys_tree, "lib", "lua", lua_v, lib_pattern))
+ table.insert(lua_cpath, dir_path(deps_tree, "lib", "lua", lua_v, lib_pattern))
+ env_variables.LUA_CPATH = table.concat(lua_cpath, ";") .. ";"
+
+ local path = { os.getenv("PATH") }
+ table.insert(path, dir_path(tree, "bin"))
+ table.insert(path, dir_path(sys_tree, "bin"))
+ table.insert(path, dir_path(deps_tree, "bin"))
+ env_variables.PATH = table.concat(path, test_env.TARGET_OS == "windows" and ";" or ":")
+
+ return env_variables
+end
+
+local function make_run_function(cmd_name, exec_function, with_coverage, do_print)
+ local cmd_prefix = Q(test_env.testing_paths.lua)
+ local testrun_dir = test_env.testing_paths.testrun_dir
+
+ if with_coverage then
+ cmd_prefix = C(cmd_prefix, "-e", "\"require('luacov.runner')([[" .. testrun_dir .. "/luacov.config]])\"")
+ end
+
+ if cmd_name then
+ cmd_prefix = C(cmd_prefix, dir_path(test_env.testing_paths.src_dir, "bin", cmd_name))
+ end
+
+ cmd_prefix = P(cmd_prefix)
+
+ return function(cmd, new_vars)
+ cmd = V(cmd)
+ local temp_vars = {}
+ for k, v in pairs(test_env.env_variables) do
+ temp_vars[k] = v
+ end
+ if new_vars then
+ for k, v in pairs(new_vars) do
+ temp_vars[k] = v
+ end
+ end
+ return exec_function(C(cmd_prefix, cmd), do_print, temp_vars)
+ end
+end
+
+local function make_run_functions()
+ local fns = {}
+
+ local cmds = {
+ ["lua"] = nil,
+ ["luarocks"] = "luarocks",
+ ["luarocks_admin"] = "luarocks-admin",
+ }
+
+ for _, name in ipairs({"lua", "luarocks", "luarocks_admin"}) do
+ fns[name] = make_run_function(cmds[name], execute_output, true, true)
+ fns[name .. "_bool"] = make_run_function(cmds[name], execute_bool, true, true)
+ fns[name .. "_nocov"] = make_run_function(cmds[name], execute_bool, false, true)
+ fns[name .. "_noprint_nocov"] = make_run_function(cmds[name], execute_bool, false, false)
+ end
+
+ return fns
+end
+
+local function move_file(src, dst)
+ local ok = execute_bool(C(tool("mv"), P(src), P(dst)))
+ if not ok then
+ print(debug.traceback())
+ os.exit(1)
+ end
+end
+
+--- Rebuild environment.
+-- Remove old installed rocks and install new ones,
+-- updating manifests and tree copies.
+local function build_environment(rocks, env_variables)
+ title("BUILDING ENVIRONMENT")
+ local testing_paths = test_env.testing_paths
+ test_env.remove_dir(testing_paths.testing_tree)
+ test_env.remove_dir(testing_paths.testing_sys_tree)
+
+ lfs.mkdir(testing_paths.testing_tree)
+ lfs.mkdir(testing_paths.testing_sys_tree)
+ lfs.mkdir(testing_paths.testing_deps_tree)
+
+ test_env.run.luarocks_admin_nocov(C("make_manifest", Q(testing_paths.testing_server)))
+ test_env.run.luarocks_admin_nocov(C("make_manifest", Q(testing_paths.testing_cache)))
+
+ for _, rock in ipairs(rocks) do
+ local only_server = "--only-server=" .. testing_paths.testing_cache
+ local tree = "--tree=" .. testing_paths.testing_deps_tree
+ if not test_env.run.luarocks_nocov(test_env.quiet(C("install", only_server, tree, Q(rock)), env_variables)) then
+ assert(test_env.run.luarocks_nocov(C("build", tree, Q(rock)), env_variables))
+ assert(test_env.run.luarocks_nocov(C("pack", tree, Q(rock)), env_variables))
+ move_file(rock .. "-*.rock", testing_paths.testing_cache)
+ end
+ end
+end
+
+local function find_lua()
+ -- (1) LUA is a full path
+ if test_env.LUA and test_env.LUA:match("[/\\]") then
+
+ local lua_bindir = test_env.LUA:match("^(.-)[/\\][^/\\]*$")
+ local luadir = test_env.LUA_DIR or lua_bindir:gsub("[/\\]bin$")
+ local lua = test_env.LUA
+
+ return lua_bindir, luadir, lua
+ end
+
+ -- (2) LUA is just the interpreter name
+ local lua_exe = test_env.LUA
+ or ((test_env.TEST_TARGET_OS == "windows") and "lua.exe")
+ or "lua"
+
+ -- (2.1) LUA_DIR was given
+ if test_env.LUA_DIR then
+
+ local luadir = test_env.LUA_DIR
+ local lua_bindir = exists(dir_path(luadir, "bin"))
+ and dir_path(luadir, "bin")
+ or luadir
+ local lua = dir_path(lua_bindir, lua_exe)
+
+ return lua_bindir, luadir, lua
+ end
+
+ -- (2.2) LUA_DIR was not given, try some default paths
+ local try_dirs = (test_env.TEST_TARGET_OS == "windows")
+ and { os.getenv("ProgramFiles(x86)").."\\LuaRocks" }
+ or { "/usr/local", "/usr" }
+
+ for _, luadir in ipairs(try_dirs) do
+ for _, lua_bindir in ipairs({ luadir, dir_path(luadir, "bin") }) do
+ local lua = dir_path(lua_bindir, lua_exe)
+ if exists(lua) then
+ return lua_bindir, luadir, lua
+ end
+ end
+ end
+end
+
+local function create_testing_paths(suffix)
+ local paths = {}
+
+ paths.lua_bindir, paths.luadir, paths.lua = find_lua()
+ if (not paths.lua) or (not exists(paths.lua)) then
+ error("Lua interpreter not found! Run `busted -Xhelper help` for options")
+ end
+
+ local base_dir = lfs.currentdir()
+ paths.src_dir = dir_path(base_dir, "src")
+ paths.spec_dir = dir_path(base_dir, "spec")
+ paths.util_dir = dir_path(base_dir, "spec", "util")
+ paths.fixtures_dir = dir_path(base_dir, "spec", "fixtures")
+ paths.fixtures_repo_dir = dir_path(base_dir, "spec", "fixtures", "a_repo")
+ paths.gpg_dir = dir_path(base_dir, "spec", "fixtures", "gpg")
+
+ local testrun_dir = dir_path(base_dir, "testrun")
+ paths.testrun_dir = testrun_dir
+ paths.testing_lrprefix = dir_path(testrun_dir, "testing_lrprefix-" .. suffix)
+ paths.testing_tree = dir_path(testrun_dir, "testing-" .. suffix)
+ paths.testing_sys_tree = dir_path(testrun_dir, "testing_sys-" .. suffix)
+ paths.testing_deps_tree = dir_path(testrun_dir, "testing_deps-" .. suffix)
+ paths.testing_cache = dir_path(testrun_dir, "testing_cache-" .. suffix)
+ paths.testing_server = dir_path(testrun_dir, "testing_server-" .. suffix)
+
+ local rocks_v = "rocks-" .. test_env.lua_version
+ paths.testing_rocks = dir_path(paths.testing_tree, "lib", "luarocks", rocks_v)
+ paths.testing_sys_rocks = dir_path(paths.testing_sys_tree, "lib", "luarocks", rocks_v)
+ paths.testing_deps_rocks = dir_path(paths.testing_deps_tree, "lib", "luarocks", rocks_v)
+
+ if test_env.TEST_TARGET_OS == "windows" then
+ paths.luarocks_tmp = os.getenv("TEMP")
+ else
+ paths.luarocks_tmp = "/tmp/luarocks_testing"
+ end
+
+ if test_env.TEST_TARGET_OS == "windows" then
+ paths.win_tools = dir_path(base_dir, "win32", "tools")
+ end
+
+ return paths
+end
+
+--- Helper function to unload luarocks modules from global table package.loaded
+-- Needed to load our local (testing) version of LuaRocks
+function test_env.unload_luarocks()
+ for modname, _ in pairs(package.loaded) do
+ if modname:match("^luarocks%.") then
+ package.loaded[modname] = nil
+ end
+ end
+ local src_pattern = dir_path(test_env.testing_paths.src_dir, "?.lua")
+ if not package.path:find(src_pattern, 1, true) then
+ package.path = src_pattern .. ";" .. package.path
+ end
+end
+
+local function get_luarocks_platform(variables)
+ local print_arch_script = "\"" ..
+ "cfg = require('luarocks.core.cfg');" ..
+ "cfg.init();" ..
+ "print(cfg.arch)" ..
+ "\""
+ local cmd = C(test_env.testing_paths.lua, "-e", print_arch_script)
+ return execute_output(cmd, false, variables)
+end
+
+--- Test if required rock is installed and if not, install it.
+-- Return `true` if the rock is already installed or has been installed successfully,
+-- `false` if installation failed.
+function test_env.need_rock(rock)
+ rock = V(rock)
+
+ print("Check if " .. rock .. " is installed")
+ if test_env.run.luarocks_noprint_nocov(test_env.quiet("show " .. rock)) then
+ return true
+ else
+ local ok = test_env.run.luarocks_noprint_nocov(test_env.quiet("install " .. rock))
+ if not ok then
+ print("WARNING: failed installing " .. rock)
+ end
+ return ok
+ end
+end
+
+--- For each key-value pair in replacements table
+-- replace %{key} in given string with value.
+local function substitute(str, replacements)
+ return (str:gsub("%%%b{}", function(marker)
+ local r = replacements[marker:sub(3, -2)]
+ if r then
+ r = r:gsub("\\", "\\\\")
+ end
+ return r
+ end))
+end
+
+
+--- Create configs for luacov and several versions of Luarocks
+-- configs needed for some tests.
+local function create_configs()
+ local testrun_dir = test_env.testing_paths.testrun_dir
+
+ -- testing_config.lua
+ -- testing_config_show_downloads.lua
+ -- testing_config_no_downloader.lua
+ local config_content = substitute([[
+ rocks_trees = {
+ { name = "user", root = "%{testing_tree}" },
+ { name = "deps", root = "%{testing_deps_tree}" },
+ { name = "system", root = "%{testing_sys_tree}" },
+ }
+ rocks_servers = {
+ "%{testing_server}"
+ }
+ local_cache = "%{testing_cache}"
+ upload_server = "testing"
+ upload_user = "%{user}"
+ upload_servers = {
+ testing = {
+ rsync = "localhost/tmp/luarocks_testing",
+ },
+ }
+ ]], {
+ user = "testuser",
+ testing_sys_tree = test_env.testing_paths.testing_sys_tree,
+ testing_deps_tree = test_env.testing_paths.testing_deps_tree,
+ testing_tree = test_env.testing_paths.testing_tree,
+ testing_server = test_env.testing_paths.testing_server,
+ testing_cache = test_env.testing_paths.testing_cache
+ })
+
+ test_env.write_file(dir_path(testrun_dir, "testing_config.lua"), config_content .. " \nweb_browser = \"true\"")
+ test_env.write_file(dir_path(testrun_dir, "testing_config_show_downloads.lua"), config_content
+ .. "show_downloads = true \n rocks_servers={\"http://luarocks.org/repositories/rocks\"}")
+ test_env.write_file(dir_path(testrun_dir, "testing_config_no_downloader.lua"), config_content
+ .. "variables = { WGET = 'invalid', CURL = 'invalid' }")
+
+ -- testing_config_sftp.lua
+ config_content = substitute([[
+ rocks_trees = {
+ "%{testing_tree}",
+ "%{testing_deps_tree}",
+ "%{testing_sys_tree}",
+ }
+ local_cache = "%{testing_cache}"
+ upload_server = "testing"
+ upload_user = "%{user}"
+ upload_servers = {
+ testing = {
+ sftp = "localhost/tmp/luarocks_testing",
+ },
+ }
+ ]], {
+ user = "testuser",
+ testing_sys_tree = test_env.testing_paths.testing_sys_tree,
+ testing_deps_tree = test_env.testing_paths.testing_deps_tree,
+ testing_tree = test_env.testing_paths.testing_tree,
+ testing_cache = test_env.testing_paths.testing_cache
+ })
+
+ test_env.write_file(dir_path(testrun_dir, "testing_config_sftp.lua"), config_content)
+
+ -- luacov.config
+ config_content = substitute([[
+ return {
+ statsfile = "%{statsfile}",
+ reportfile = "%{reportfile}",
+ exclude = {
+ "src%/luarocks%/vendor.+$",
+ },
+ modules = {
+ ["luarocks"] = "%{luarocks_path}",
+ ["luarocks-admin"] = "%{luarocks_admin_path}",
+ ["luarocks.*"] = "src",
+ ["luarocks.*.*"] = "src",
+ ["luarocks.*.*.*"] = "src"
+ }
+ }
+ ]], {
+ statsfile = dir_path(testrun_dir, "luacov.stats.out"),
+ reportfile = dir_path(testrun_dir, "luacov.report.out"),
+ luarocks_path = dir_path("src", "bin", "luarocks"),
+ luarocks_admin_path = dir_path("src", "bin", "luarocks-admin"),
+ })
+
+ test_env.write_file(dir_path(testrun_dir, "luacov.config"), config_content)
+
+ config_content = [[
+ -- Config file of mock LuaRocks.org site for tests
+ upload = {
+ server = "http://localhost:8080",
+ tool_version = "1.0.0",
+ api_version = "1",
+ }
+ ]]
+ test_env.write_file(dir_path(testrun_dir, "luarocks_site.lua"), config_content)
+end
+
+--- Remove testing directories.
+local function clean()
+ local testrun_dir = test_env.testing_paths.testrun_dir
+
+ print("Cleaning testing directory...")
+ test_env.remove_dir(test_env.testing_paths.luarocks_tmp)
+ test_env.remove_subdirs(testrun_dir, "testing[_%-]")
+ test_env.remove_files(testrun_dir, "testing_")
+ test_env.remove_files(testrun_dir, "luacov")
+ test_env.remove_files(testrun_dir, "upload_config")
+ test_env.remove_files(testrun_dir, "luarocks_site")
+ print("Cleaning done!")
+end
+
+--- Setup current checkout of luarocks to work with testing prefix.
+local function setup_luarocks()
+ local testing_paths = test_env.testing_paths
+ title("Setting up LuaRocks")
+
+ local lines = {
+ "return {",
+ ("SYSCONFDIR = %q,"):format(dir_path(testing_paths.testing_lrprefix, "etc/luarocks")),
+ ("LUA_DIR = %q,"):format(testing_paths.luadir),
+ ("LUA_BINDIR = %q,"):format(testing_paths.lua_bindir),
+ ("LUA = %q,"):format(testing_paths.lua),
+ }
+
+ if test_env.TEST_TARGET_OS == "windows" then
+ if test_env.MINGW then
+ table.insert(lines, [[SYSTEM = "mingw",]])
+ else
+ table.insert(lines, [[SYSTEM = "windows",]])
+ end
+ table.insert(lines, ("WIN_TOOLS = %q,"):format(testing_paths.win_tools))
+ end
+
+ table.insert(lines, "}")
+
+ test_env.write_file("src/luarocks/core/hardcoded.lua", table.concat(lines, "\n") .. "\n")
+
+ print("LuaRocks set up correctly!")
+end
+
+local function mock_api_call(path)
+ return test_env.execute(C(tool("wget"), "--timeout=0.1 --quiet --tries=10 http://localhost:8080" .. path))
+end
+
+function test_env.mock_server_init()
+ if not test_env.mock_prepared then
+ error("need to setup_specs with with_mock set to true")
+ end
+
+ local testing_paths = test_env.testing_paths
+ assert(test_env.need_rock("restserver-xavante"))
+
+ local lua = Q(testing_paths.lua)
+ local mock_server = Q(dir_path(testing_paths.util_dir, "mock-server.lua"))
+ local fixtures_dir = Q(testing_paths.fixtures_dir)
+
+ local cmd = C(lua, mock_server, fixtures_dir)
+
+ local bg_cmd = test_env.TEST_TARGET_OS == "windows"
+ and C("start", "/b", "\"\"", cmd)
+ or C(cmd, "&")
+
+ os.execute(test_env.execute_helper(bg_cmd, true, test_env.env_variables))
+
+ for _ = 1, 100 do
+ if mock_api_call("/api/tool_version") then
+ break
+ end
+ os.execute(test_env.TEST_TARGET_OS == "windows"
+ and "ping 192.0.2.0 -n 1 -w 250 > NUL"
+ or "sleep 0.1")
+ end
+
+end
+
+function test_env.mock_server_done()
+ mock_api_call("/shutdown")
+end
+
+local function find_binary_rock(src_rock, dirname)
+ local patt = src_rock:gsub("([.-])", "%%%1"):gsub("src", ".*[^s][^r][^c]")
+ for name in lfs.dir(dirname) do
+ if name:match(patt) then
+ return true
+ end
+ end
+ return false
+end
+
+local function prepare_mock_server_binary_rocks()
+ if test_env.mock_prepared then
+ return
+ end
+
+ local testing_paths = test_env.testing_paths
+
+ local rocks = {
+ -- rocks needed for mock-server
+ "luasocket-${LUASOCKET}.src.rock",
+ "coxpcall-1.16.0-1.src.rock",
+ "binaryheap-${BINARYHEAP}.src.rock",
+ "timerwheel-${TIMERWHEEL}.src.rock",
+ "copas-${COPAS}.src.rock",
+ "luafilesystem-${LUAFILESYSTEM}.src.rock",
+ "xavante-2.4.0-1.src.rock",
+ "wsapi-1.6.1-1.src.rock",
+ "rings-1.3.0-1.src.rock",
+ "wsapi-xavante-1.6.1-1.src.rock",
+ "dkjson-${DKJSON}.src.rock",
+ "restserver-0.1-1.src.rock",
+ "restserver-xavante-0.2-1.src.rock",
+ }
+ local make_manifest = download_rocks(rocks, testing_paths.testing_server)
+ for _, rock in ipairs(rocks) do
+ rock = V(rock)
+ local rockname = rock:gsub("%-[^-]+%-%d+%.[%a.]+$", "")
+ if not find_binary_rock(rock, testing_paths.testing_server) then
+ local rockpath = dir_path(testing_paths.testing_server, rock)
+ local tree = "--tree=" .. testing_paths.testing_cache
+
+ test_env.run.luarocks_nocov(C("build", Q(rockpath), tree))
+ test_env.run.luarocks_nocov(C("pack", rockname, tree))
+
+ move_file(rockname .. "-*.rock", testing_paths.testing_server)
+ make_manifest = true
+ end
+ end
+ if make_manifest then
+ test_env.run.luarocks_admin_nocov(C("make_manifest", Q(testing_paths.testing_server)))
+ end
+
+ test_env.mock_prepared = true
+end
+
+---
+-- Main function to create config files and testing environment
+function test_env.main()
+ local testing_paths = test_env.testing_paths
+ local testrun_dir = test_env.testing_paths.testrun_dir
+
+ if test_env.TEST_ENV_CLEAN then
+ clean()
+ end
+
+ lfs.mkdir(testrun_dir)
+ test_env.write_file(dir_path(testrun_dir, ".luarocks-no-project"), "")
+ lfs.mkdir(testing_paths.testing_cache)
+ lfs.mkdir(testing_paths.luarocks_tmp)
+
+ create_configs()
+
+ setup_luarocks()
+
+ -- Preparation of rocks for building environment
+ local rocks = {} -- names of rocks, required for building environment
+ local urls = {} -- names of rock and rockspec files to be downloaded
+
+ local env_vars = {
+ LUAROCKS_CONFIG = dir_path(testrun_dir, "testing_config.lua")
+ }
+
+ if test_env.TYPE_TEST_ENV == "full" then
+ table.insert(urls, "/luafilesystem-${LUAFILESYSTEM}.src.rock")
+ table.insert(urls, "/luasocket-${LUASOCKET}.src.rock")
+ table.insert(urls, "/luasec-${LUASEC}.src.rock")
+ table.insert(urls, "/md5-1.2-1.src.rock")
+ table.insert(urls, "/manifests/hisham/lua-zlib-1.2-0.src.rock")
+ table.insert(urls, "/manifests/hisham/lua-bz2-0.2.1.1-1.src.rock")
+ rocks = {"luafilesystem", "luasocket", "luasec", "md5", "lua-zlib", "lua-bz2"}
+ if test_env.TEST_TARGET_OS ~= "windows" then
+ if test_env.lua_version == "5.1" then
+ table.insert(urls, "/bit32-${BIT32}.src.rock")
+ table.insert(rocks, "bit32")
+ end
+ table.insert(urls, "/luaposix-${LUAPOSIX}.src.rock")
+ table.insert(rocks, "luaposix")
+ end
+ assert(test_env.run.luarocks_nocov(C("config", "variables.OPENSSL_INCDIR", Q(test_env.OPENSSL_INCDIR)), env_vars))
+ assert(test_env.run.luarocks_nocov(C("config", "variables.OPENSSL_LIBDIR", Q(test_env.OPENSSL_LIBDIR)), env_vars))
+ end
+
+ -- luacov is needed for both minimal or full environment
+ table.insert(urls, "/luacov-${LUACOV}.src.rock")
+ table.insert(urls, "/cluacov-${CLUACOV}.src.rock")
+ table.insert(rocks, "luacov")
+ table.insert(rocks, "cluacov")
+
+ -- Download rocks needed for LuaRocks testing environment
+ lfs.mkdir(testing_paths.testing_server)
+ download_rocks(urls, testing_paths.testing_server)
+
+ build_environment(rocks, env_vars)
+end
+
+--- Function for initial setup of environment and variables
+function test_env.setup_specs(extra_rocks, use_mock)
+ test_env.unload_luarocks()
+
+ local testrun_dir = test_env.testing_paths.testrun_dir
+ local variables = test_env.env_variables
+
+ -- if global variable about successful creation of testing environment doesn't exist, build environment
+ if not test_env.setup_done then
+ if test_env.CI then
+ if not exists(os.getenv("HOME"), ".ssh/id_rsa.pub") then
+ execute_bool("ssh-keygen -t rsa -P \"\" -f ~/.ssh/id_rsa")
+ execute_bool("cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys")
+ execute_bool("chmod og-wx ~/.ssh/authorized_keys")
+ execute_bool("ssh-keyscan localhost >> ~/.ssh/known_hosts")
+ end
+ end
+
+ test_env.main()
+
+ -- preload before meddling with package.path
+ require("spec.util.git_repo")
+ require("spec.util.quick")
+
+ package.path = variables.LUA_PATH
+ package.cpath = variables.LUA_CPATH
+
+ test_env.platform = get_luarocks_platform(test_env.env_variables)
+ test_env.wrapper_extension = test_env.TEST_TARGET_OS == "windows" and ".bat" or ""
+ test_env.setup_done = true
+ title("RUNNING TESTS")
+ end
+
+ if use_mock == "mock" then
+ prepare_mock_server_binary_rocks()
+ end
+
+ if extra_rocks then
+ local make_manifest = download_rocks(extra_rocks, test_env.testing_paths.testing_server)
+ if make_manifest then
+ test_env.run.luarocks_admin_nocov("make_manifest " .. test_env.testing_paths.testing_server)
+ end
+ end
+
+ if test_env.RESET_ENV then
+ test_env.remove_dir(test_env.testing_paths.testing_tree)
+ test_env.remove_dir(test_env.testing_paths.testing_sys_tree)
+ end
+
+ lfs.chdir(testrun_dir)
+end
+
+test_env.set_lua_version()
+test_env.set_args()
+test_env.testing_paths = create_testing_paths(test_env.LUA_V or test_env.LUAJIT_V)
+test_env.env_variables = create_env(test_env.testing_paths)
+test_env.run = make_run_functions()
+test_env.exists = exists
+test_env.V = V
+test_env.Q = Q
+test_env.P = P
+test_env.platform = get_luarocks_platform(test_env.env_variables)
+
+return test_env
diff --git a/spec/util/versions.lua b/spec/util/versions.lua
new file mode 100644
index 0000000..77c1129
--- /dev/null
+++ b/spec/util/versions.lua
@@ -0,0 +1,17 @@
+return {
+ binaryheap = "0.4-1", -- dependency for copas
+ bit32 = "5.3.5.1-1", -- dependency for luaposix on Lua 5.1
+ cluacov = "0.1.3-1",
+ copas = "3.0.0-2",
+ cprint = "0.2-1",
+ dkjson = "2.6-1",
+ lpeg = "1.0.0-1",
+ luacov = "0.15.0-1",
+ luafilesystem = "1.8.0-1",
+ luafilesystem_old = "1.6.3-2",
+ luaposix = "35.1-1",
+ luasocket = "3.0.0-1",
+ luasec = "1.3.2-1",
+ lxsh = "0.8.6-2",
+ timerwheel = "0.2.0-2", -- dependency for copas
+}
diff --git a/spec/util_spec.lua b/spec/util_spec.lua
new file mode 100644
index 0000000..0f199c9
--- /dev/null
+++ b/spec/util_spec.lua
@@ -0,0 +1,55 @@
+local test_env = require("spec.util.test_env")
+local lfs = require("lfs")
+local run = test_env.run
+
+describe("Basic tests #integration", function()
+
+ before_each(function()
+ test_env.setup_specs()
+ end)
+
+ it("--version", function()
+ assert.is_true(run.luarocks_bool("--version"))
+ end)
+
+ it("unknown command", function()
+ assert.is_false(run.luarocks_bool("unknown_command"))
+ end)
+
+ it("arguments fail", function()
+ assert.is_false(run.luarocks_bool("--porcelain=invalid"))
+ assert.is_false(run.luarocks_bool("--invalid-flag"))
+ assert.is_false(run.luarocks_bool("--server"))
+ assert.is_false(run.luarocks_bool("--server --porcelain"))
+ assert.is_false(run.luarocks_bool("--invalid-flag=abc"))
+ assert.is_false(run.luarocks_bool("invalid=5"))
+ end)
+
+ it("executing from not existing directory #unix", function()
+ local main_path = lfs.currentdir()
+ assert.is_true(lfs.mkdir("idontexist"))
+ assert.is_true(lfs.chdir("idontexist"))
+ local delete_path = lfs.currentdir()
+ assert.is_true(os.remove(delete_path))
+
+ local output = run.luarocks("")
+ assert.is.falsy(output:find("the Lua package manager"))
+ assert.is_true(lfs.chdir(main_path))
+
+ output = run.luarocks("")
+ assert.is.truthy(output:find("the Lua package manager"))
+ end)
+
+ it("--timeout", function()
+ assert.is.truthy(run.luarocks("--timeout=10"))
+ end)
+
+ it("--timeout invalid", function()
+ assert.is_false(run.luarocks_bool("--timeout=abc"))
+ end)
+
+ it("--only-server", function()
+ assert.is.truthy(run.luarocks("--only-server=testing"))
+ end)
+
+end)
diff --git a/spec/which_spec.lua b/spec/which_spec.lua
new file mode 100644
index 0000000..5712511
--- /dev/null
+++ b/spec/which_spec.lua
@@ -0,0 +1,39 @@
+local test_env = require("spec.util.test_env")
+local run = test_env.run
+local P = test_env.P
+
+local extra_rocks = {
+ "/say-1.2-1.src.rock",
+}
+
+describe("luarocks which #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs(extra_rocks)
+ end)
+
+ it("fails on missing arguments", function()
+ local output = run.luarocks("which")
+ assert.match("missing argument 'modname'", output, 1, true)
+ end)
+
+ it("finds modules found in package.path", function()
+ assert.is_true(run.luarocks_bool("install say 1.2"))
+ local output = run.luarocks("which say")
+ assert.match(P"say/init.lua", output, 1, true)
+ assert.match("provided by say 1.2-1", output, 1, true)
+ end)
+
+ it("finds modules found in package.path", function()
+ run.luarocks("install ")
+ local output = run.luarocks("which luarocks.loader")
+ assert.match("luarocks/loader.lua", output, 1, true)
+ assert.match("not installed as a rock", output, 1, true)
+ end)
+
+ it("report modules not found", function()
+ local output = run.luarocks("which asdfgaoeui")
+ assert.match("Module 'asdfgaoeui' not found", output, 1, true)
+ end)
+
+end)
diff --git a/spec/write_rockspec_spec.lua b/spec/write_rockspec_spec.lua
new file mode 100644
index 0000000..abd5c80
--- /dev/null
+++ b/spec/write_rockspec_spec.lua
@@ -0,0 +1,104 @@
+local test_env = require("spec.util.test_env")
+local git_repo = require("spec.util.git_repo")
+local lfs = require("lfs")
+local run = test_env.run
+
+describe("luarocks write_rockspec tests #integration", function()
+
+ lazy_setup(function()
+ test_env.setup_specs()
+ end)
+
+ it("fails with invalid argument", function()
+ assert.is_false(run.luarocks_bool("write_rockspec invalid"))
+ end)
+
+ it("fails with invalid zip", function()
+ assert.is_false(run.luarocks_bool("write_rockspec http://example.com/invalid.zip"))
+ end)
+
+ describe("from #git #unix", function()
+ local git
+
+ lazy_setup(function()
+ git = git_repo.start()
+ end)
+
+ teardown(function()
+ git:stop()
+ end)
+
+ it("runs with no flags/arguments", function()
+ local d = lfs.currentdir()
+ finally(function()
+ os.remove("testrock-dev-1.rockspec")
+ lfs.chdir(d)
+ test_env.remove_dir("testrock")
+ end)
+ os.execute("git clone git://localhost/testrock")
+ lfs.chdir("testrock")
+ assert.is_true(run.luarocks_bool("write_rockspec"))
+ assert.is.truthy(lfs.attributes("testrock-dev-1.rockspec"))
+ end)
+
+ it("runs", function()
+ finally(function() os.remove("testrock-dev-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec git://localhost/testrock"))
+ assert.is.truthy(lfs.attributes("testrock-dev-1.rockspec"))
+ end)
+
+ it("runs with --tag", function()
+ finally(function() os.remove("testrock-2.3.0-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec git://localhost/testrock --tag=v2.3.0"))
+ assert.is.truthy(lfs.attributes("testrock-2.3.0-1.rockspec"))
+ -- TODO check contents
+ end)
+
+ it("runs with format flag", function()
+ finally(function() os.remove("testrock-dev-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec git://localhost/testrock --rockspec-format=1.1 --lua-versions=5.1,5.2"))
+ assert.is.truthy(lfs.attributes("testrock-dev-1.rockspec"))
+ -- TODO check contents
+ end)
+
+ it("runs with full flags", function()
+ finally(function() os.remove("testrock-dev-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec git://localhost/testrock --lua-versions=5.1,5.2 --license=\"MIT/X11\" "
+ .. " --homepage=\"http://www.luarocks.org\" --summary=\"A package manager for Lua modules\" "))
+ assert.is.truthy(lfs.attributes("testrock-dev-1.rockspec"))
+ -- TODO check contents
+ end)
+
+ it("with various flags", function()
+ finally(function() os.remove("testrock-dev-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec git://localhost/testrock --lib=fcgi --license=\"3-clause BSD\" " .. "--lua-versions=5.1,5.2"))
+ assert.is.truthy(lfs.attributes("testrock-dev-1.rockspec"))
+ -- TODO check contents
+ end)
+ end)
+
+ describe("from tarball #mock", function()
+
+ lazy_setup(function()
+ test_env.setup_specs(nil, "mock")
+ test_env.mock_server_init()
+ end)
+ lazy_teardown(function()
+ test_env.mock_server_done()
+ end)
+
+ it("via http", function()
+ finally(function() os.remove("an_upstream_tarball-0.1-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec http://localhost:8080/file/an_upstream_tarball-0.1.tar.gz --lua-versions=5.1"))
+ assert.is.truthy(lfs.attributes("an_upstream_tarball-0.1-1.rockspec"))
+ -- TODO check contents
+ end)
+
+ it("with a different basedir", function()
+ finally(function() os.remove("renamed_upstream_tarball-0.1-1.rockspec") end)
+ assert.is_true(run.luarocks_bool("write_rockspec http://localhost:8080/file/renamed_upstream_tarball-0.1.tar.gz --lua-versions=5.1"))
+ assert.is.truthy(lfs.attributes("renamed_upstream_tarball-0.1-1.rockspec"))
+ -- TODO check contents
+ end)
+ end)
+end)