diff options
| author | ruki <[email protected]> | 2026-08-01 08:53:30 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-08-01 08:53:30 +0800 |
| commit | 8d7a74306556a4c292c0345f1a9aa833116ebcec (patch) | |
| tree | 49b0b3ae14157a3f24193623d6adb69e282675e9 /tests/plugins | |
| parent | f91724eb1d7f80e81772ad6f20b03b2a0cff8125 (diff) | |
improve tests
Diffstat (limited to 'tests/plugins')
| -rw-r--r-- | tests/plugins/repository/test.lua | 135 |
1 files changed, 76 insertions, 59 deletions
diff --git a/tests/plugins/repository/test.lua b/tests/plugins/repository/test.lua index 4f1347317..f1cfba8c7 100644 --- a/tests/plugins/repository/test.lua +++ b/tests/plugins/repository/test.lua @@ -1,88 +1,105 @@ import("core.base.global") -function _write_plugin(dir, name, text) +-- write a minimal plugin that prints its name when run +function _write_plugin(dir, name) io.writefile(path.join(dir, "xmake.lua"), string.format([[ task("%s") set_category("plugin") on_run("main") - set_menu {usage = "xmake %s"} -]], name, name)) - io.writefile(path.join(dir, "main.lua"), string.format([[function main() print("%s") end]], text)) + set_menu {usage = "xmake %s", description = "say hello from %s"} +]], name, name, name)) + io.writefile(path.join(dir, "main.lua"), string.format([[function main() print("%s") end]], name)) end -function main(t) +-- create a temporary plugin repository (packages layout: plugins/<first-letter>/<name>) and register it +-- +-- @return reponame, names, cleanup +function _mock_repo(basenames) local suffix = path.filename(os.tmpfile()):gsub("[^%w]", "") - local reponame = "plugin-test-repository-" .. suffix - local hello_name = "plugin-test-hello-" .. suffix - local formatter_name = "plugin-test-formatter-" .. suffix - local available_name = "plugin-test-available-" .. suffix - local local_name = "plugin-test-local-" .. suffix - local repodir = os.tmpfile() .. ".plugins-repository" - local localdir = path.join(os.tmpfile() .. ".local-plugin", local_name) - local plugindir = path.join(global.directory(), "plugins") + local reponame = "plugin-test-repo-" .. suffix + local repodir = os.tmpfile() .. ".plugin-repo" + local names = {} + for _, base in ipairs(basenames) do + local name = base .. "-" .. suffix + _write_plugin(path.join(repodir, "plugins", name:sub(1, 1), name), name) + table.insert(names, name) + end + + -- register the repository into the cache local cachefile = path.join(global.cachedir(), "repository") + local cache = os.isfile(cachefile) and io.load(cachefile) or {} + cache.repositories = cache.repositories or {} + cache.repositories[reponame] = {repodir} + io.save(cachefile, cache) - -- reset test state local function cleanup() - for _, name in ipairs({hello_name, formatter_name, available_name, local_name}) do - os.tryrm(path.join(plugindir, name)) + for _, name in ipairs(names) do + os.tryrm(path.join(global.directory(), "plugins", name)) end local cache = os.isfile(cachefile) and io.load(cachefile) or {} - cache.repositories = cache.repositories or {} - cache.repositories[reponame] = nil + if cache.repositories then + cache.repositories[reponame] = nil + end io.save(cachefile, cache) os.tryrm(repodir) - os.tryrm(path.directory(localdir)) end - cleanup() + return reponame, names, cleanup +end - -- mock repository with installed and available plugins (packages-like layout: plugins/<first-letter>/<name>) - _write_plugin(path.join(repodir, "plugins", hello_name:sub(1, 1), hello_name), hello_name, "repo-ok") - _write_plugin(path.join(repodir, "plugins", formatter_name:sub(1, 1), formatter_name), formatter_name, "format-ok") - _write_plugin(path.join(repodir, "plugins", available_name:sub(1, 1), available_name), available_name, "available-ok") - os.mkdir(path.directory(cachefile)) - local cache = os.isfile(cachefile) and io.load(cachefile) or {} - cache.repositories = cache.repositories or {} - cache.repositories[reponame] = {repodir} - io.save(cachefile, cache) +-- install a plugin from a repository, by plain name and by repo@name +function test_install_from_repo(t) + local reponame, names, cleanup = _mock_repo({"hello"}) + local name = names[1] - -- Feature: install by plain name from repository - os.runv("xmake", {"plugin", "--install", hello_name}) - os.runv("xmake", {hello_name}) + -- install by plain name (searched across all repositories) + os.runv("xmake", {"plugin", "--install", name}) + t:require(os.iorunv("xmake", {name}):find(name, 1, true)) - -- Feature: install by repo@name format - os.runv("xmake", {"plugin", "--install", reponame .. "@" .. formatter_name}) - os.runv("xmake", {formatter_name}) + -- reinstall by repo@name + os.runv("xmake", {"plugin", "--remove", name}) + os.runv("xmake", {"plugin", "--install", reponame .. "@" .. name}) + t:require(os.iorunv("xmake", {name}):find(name, 1, true)) - -- Feature: --list shows installed and available repository plugins - local out = os.iorun("xmake plugin --list") - t:require(out:find("the built-in plugins:", 1, true)) - t:require(out:find("project", 1, true)) - t:require(out:find(hello_name, 1, true)) - t:require(out:find(formatter_name, 1, true)) - t:require(out:find(available_name, 1, true)) - t:require(out:find("xmake plugin --install " .. available_name, 1, true)) + os.runv("xmake", {"plugin", "--remove", name}) + cleanup() +end + +-- install a plugin from a local directory, then remove it +function test_install_from_local(t) + local suffix = path.filename(os.tmpfile()):gsub("[^%w]", "") + local name = "hello-local-" .. suffix + local dir = path.join(os.tmpfile() .. ".plugin-local", name) + _write_plugin(dir, name) - -- Feature: install from local directory - _write_plugin(localdir, local_name, "local-ok") - os.runv("xmake", {"plugin", "--install", localdir}) - os.runv("xmake", {local_name}) + os.runv("xmake", {"plugin", "--install", dir}) + t:require(os.iorunv("xmake", {name}):find(name, 1, true)) - out = os.iorun("xmake plugin --list") - t:require(out:find(local_name, 1, true)) + -- the removed plugin should no longer be runnable + os.runv("xmake", {"plugin", "--remove", name}) + t:require_not(try { function () os.runv("xmake", {name}); return true end }) - -- Feature: remove plugin - os.runv("xmake", {"plugin", "--remove", local_name}) - out = os.iorun("xmake plugin --list") - t:require_not(out:find(local_name, 1, true)) + os.tryrm(path.directory(dir)) +end - -- Feature: install non-existent plugin fails gracefully - local ok = try { function () os.runv("xmake", {"plugin", "--install", "plugin-test-missing-" .. suffix}) return true end } - t:require_not(ok) +-- --list shows the built-in, installed and available plugins +function test_list(t) + local reponame, names, cleanup = _mock_repo({"hello", "world"}) - -- Feature: reject plugin name traversal - ok = try { function () os.runv("xmake", {"plugin", "--install", reponame .. "@.."}) return true end } - t:require_not(ok) + -- install the first plugin, leave the second only available + os.runv("xmake", {"plugin", "--install", names[1]}) + local out = os.iorunv("xmake", {"plugin", "--list"}) + t:require(out:find("the built-in plugins:", 1, true)) + t:require(out:find("project", 1, true)) + t:require(out:find(names[1], 1, true)) + t:require(out:find(names[2], 1, true)) + t:require(out:find("xmake plugin --install " .. names[2], 1, true)) + os.runv("xmake", {"plugin", "--remove", names[1]}) cleanup() end + +-- invalid installs should fail +function test_install_invalid(t) + t:require_not(try { function () os.runv("xmake", {"plugin", "--install", "plugin-test-missing"}); return true end }) + t:require_not(try { function () os.runv("xmake", {"plugin", "--install", "somerepo@.."}); return true end }) +end |
