diff --git a/lua/octo/gh/init.lua b/lua/octo/gh/init.lua index 75b37f16..72b3148e 100644 --- a/lua/octo/gh/init.lua +++ b/lua/octo/gh/init.lua @@ -323,16 +323,50 @@ function M.api.graphql(opts) } end -local rest = function(method, opts) - local run_opts = opts.opts or {} +---Format the endpoint with the format table +---@param endpoint string the endpoint to format +---@param format table the format table +local format_endpoint = function(endpoint, format) + for key, value in pairs(format) do + endpoint = endpoint:gsub("{" .. key .. "}", value) + end + return endpoint +end + +---@param method string the rest method +---@param opts table the options for the rest command +---@return table|nil +M.create_rest_args = function(method, opts) + local format = opts.format or {} + + local endpoint = opts[1] + if not endpoint then + return + end + endpoint = format_endpoint(endpoint, format) + opts[1] = endpoint + local args = { "api" } if method ~= nil then table.insert(args, "--method") table.insert(args, method) end + opts.format = nil opts.opts = nil - args = M.insert_args(args, opts) + return M.insert_args(args, opts) +end + +---Run a rest command +local rest = function(method, opts) + local run_opts = opts.opts or {} + + local args = M.create_rest_args(method, opts) + if not args then + local utils = require "octo.utils" + utils.error "Endpoint is required" + return + end run { args = args, diff --git a/lua/tests/plenary/gh_spec.lua b/lua/tests/plenary/gh_spec.lua index e81f909d..92dd11b0 100644 --- a/lua/tests/plenary/gh_spec.lua +++ b/lua/tests/plenary/gh_spec.lua @@ -109,6 +109,74 @@ describe("insert_args:", function() end) end) +local tables_have_same_elements = function(t1, t2) + if #t1 ~= #t2 then + return false + end + for _, v in ipairs(t1) do + if not vim.tbl_contains(t2, v) then + return false + end + end + for _, v in ipairs(t2) do + if not vim.tbl_contains(t1, v) then + return false + end + end + return true +end + +local assert_tables_have_same_elements = function(t1, t2) + assert( + tables_have_same_elements(t1, t2), + string.format("Expected tables to have the same elements:\n%s\n%s", vim.inspect(t1), vim.inspect(t2)) + ) +end + +describe("REST API args", function() + it("no args", function() + local actual = gh.create_rest_args(nil, {}) + eq(actual, nil) + end) + it("Endpoint is required", function() + local actual = gh.create_rest_args(nil, { format = { owner = "pwntester" }, json = "id", jq = ".id" }) + eq(actual, nil) + end) + it("Returns table with untouched endpoint", function() + local actual = gh.create_rest_args("GET", { + "repos/pwntester/octo.nvim/pulls", + jq = ".[].number", + paginate = true, + }) + assert_tables_have_same_elements(actual, { + "api", + "--method", + "GET", + "repos/pwntester/octo.nvim/pulls", + "--jq", + ".[].number", + "--paginate", + }) + end) + it("Returns table with formated endpoint", function() + local actual = gh.create_rest_args("GET", { + "repos/{owner}/{name}/pulls", + format = { owner = "pwntester", name = "octo.nvim" }, + jq = ".[].number", + paginate = true, + }) + assert_tables_have_same_elements(actual, { + "api", + "--method", + "GET", + "repos/pwntester/octo.nvim/pulls", + "--jq", + ".[].number", + "--paginate", + }) + end) +end) + describe("create_graphql_opts:", function() local query = "example query" local login = "pwntester"