summaryrefslogtreecommitdiff
path: root/tests/plugins/repository/test.lua
blob: c4c6c4c2040feb3783722bb71ceb046194df5bad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
local global = import("core.base.global")

function _write_plugin(dir, name, text)
    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))
end

function main(t)
    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 cachefile = path.join(global.cachedir(), "repository")

    -- 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))
        end
        local cache = os.isfile(cachefile) and io.load(cachefile) or {}
        cache.repositories = cache.repositories or {}
        cache.repositories[reponame] = nil
        io.save(cachefile, cache)
        os.tryrm(repodir)
        os.tryrm(path.directory(localdir))
    end
    cleanup()

    -- mock repository with installed and available plugins
    _write_plugin(path.join(repodir, "plugins", hello_name), hello_name, "repo-ok")
    _write_plugin(path.join(repodir, "plugins", formatter_name), formatter_name, "format-ok")
    _write_plugin(path.join(repodir, "plugins", 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)

    -- Feature: install by plain name from repository
    os.runv("xmake", {"plugin", "--install", hello_name})
    os.runv("xmake", {hello_name})

    -- Feature: install by repo@name format
    os.runv("xmake", {"plugin", "--install", reponame .. "@" .. formatter_name})
    os.runv("xmake", {formatter_name})

    -- Feature: --list shows installed and available repository plugins
    local out = os.iorun("xmake plugin --list")
    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))

    -- Feature: install from local directory
    _write_plugin(localdir, local_name, "local-ok")
    os.runv("xmake", {"plugin", "--install", localdir})
    os.runv("xmake", {local_name})

    out = os.iorun("xmake plugin --list")
    t:require(out:find(local_name, 1, true))

    -- 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))

    -- 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)

    -- Feature: reject plugin name traversal
    ok = try { function () os.runv("xmake", {"plugin", "--install", reponame .. "@.."}) return true end }
    t:require_not(ok)

    cleanup()
end