CLI refact (#391)

* some refact of gotest

* issue #376 add handlers to async formatting

* issue #343 title length

* add parallel flag

* disable trace log

* Error lines output in github action

* Go mod update in fixtures
pull/395/head
rayx 6 months ago committed by GitHub
parent 8732792d9c
commit c4819d1625
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -292,7 +292,8 @@ first run of `GoFmt` may fail. Recommended to run `GoInstallBinaries` to install
| GoTest -n | test nearest, see GoTestFunc |
| GoTest -f | test current file, see GoTestFile |
| GoTest -n 1 | -count=1 flag |
| GoTest -p | test current package, see GoTestPkg |
| GoTest -p {pkgname} | test package, see GoTestPkg, test current package if {pkgname} not specified |
| GoTest -parallel {number} | test current package with parallel number |
| GoTest -b {build_flags} | run `go test` with build flags e.g. `-gcflags=.` |
| GoTest -t yourtags | go test ./... -tags=yourtags, see notes |
| GoTest -a your_args | go test ./... -args=yourargs, see notes |
@ -843,6 +844,9 @@ require('go').setup({
posititon = 'auto', -- one of {`top`, `bottom`, `left`, `right`, `center`, `auto`}
width = 0.45, -- width of float window if not auto
height = 0.98, -- height of float window if not auto
title_colors = 'nord', -- default to nord, one of {'nord', 'tokyo', 'dracula', 'rainbow', 'solarized ', 'monokai'}
-- can also set to a list of colors to define colors to choose from
-- e.g {'#D8DEE9', '#5E81AC', '#88C0D0', '#EBCB8B', '#A3BE8C', '#B48EAD'}
},
trouble = false, -- true: use trouble to open quickfix
test_efm = false, -- errorfomat for quickfix, default mix mode, set to true will be efm only

@ -125,6 +125,7 @@ _GO_NVIM_CFG = {
posititon = 'auto', -- one of {`top`, `bottom`, `left`, `right`, `center`, `auto`}
width = 0.45, -- width of float window if not auto
height = 0.98, -- height of float window if not auto
title_colors = 'nord', -- table of colors for title, 'rainbow' for system default of rainbow colors
},
trouble = false, -- true: use trouble to open quickfix
test_efm = false, -- errorfomat for quickfix, default mix mode, set to true will be efm only

@ -37,13 +37,11 @@ local long_opts = {
fuzz = 'f',
}
local short_opts = 'a:vcC:f:t:b:n:Fr:g'
local short_opts = 'a:ct:b:Fg'
local bench_opts = { '-benchmem', '-cpuprofile', 'profile.out' }
function M.make(...)
local args = { ... }
local lines = {}
local errorlines = {}
local winnr = vim.fn.win_getid()
local bufnr = vim.api.nvim_win_get_buf(winnr)
local makeprg = vim.api.nvim_buf_get_option(bufnr, 'makeprg')
@ -151,46 +149,46 @@ function M.make(...)
local bench = false
if makeprg:find('go test') then
log('go test')
runner = 'go test'
efm = compile_efm()
if optarg['c'] then
log('compile test')
compile_test = true
end
for _, arg in ipairs(args) do
--check if it is bench test
if arg:find('-bench') then
bench = true
end
end
if optarg['v'] then
table.insert(cmd, '-v')
end
if optarg['C'] then
table.insert(cmd, '-coverprofile=' .. optarg['C'])
end
if optarg['f'] then
log('fuzz test')
table.insert(cmd, '-fuzz')
end
if optarg['n'] then
table.insert(cmd, '-count=' .. optarg['n'])
end
if not bench and compile_test then
table.insert(cmd, '-c')
end
if optarg['r'] then
log('run test', optarg['r'])
table.insert(cmd, '-run')
table.insert(cmd, optarg['r'])
end
if optarg['b'] then
log('build test flags', optarg['b'])
table.insert(cmd, optarg['b'])
end
-- log('go test')
-- runner = 'go test'
-- efm = compile_efm()
-- if optarg['c'] then
-- log('compile test')
-- compile_test = true
-- end
-- for _, arg in ipairs(args) do
-- --check if it is bench test
-- if arg:find('-bench') then
-- bench = true
-- end
-- end
-- if optarg['v'] then
-- table.insert(cmd, '-v')
-- end
-- if optarg['C'] then
-- table.insert(cmd, '-coverprofile=' .. optarg['C'])
-- end
-- if optarg['f'] then
-- log('fuzz test')
-- table.insert(cmd, '-fuzz')
-- end
-- if optarg['n'] then
-- table.insert(cmd, '-count=' .. optarg['n'])
-- end
-- if not bench and compile_test then
-- table.insert(cmd, '-c')
-- end
-- if optarg['r'] then
-- log('run test', optarg['r'])
-- table.insert(cmd, '-run')
-- table.insert(cmd, optarg['r'])
-- end
-- if optarg['b'] then
-- log('build test flags', optarg['b'])
-- table.insert(cmd, optarg['b'])
-- end
end
if bench then
@ -208,29 +206,36 @@ function M.make(...)
end
end
local function handle_color(line)
if _GO_NVIM_CFG.run_in_floaterm or optarg['F'] then
return line
end
if tonumber(vim.fn.match(line, '\\%x1b\\[[0-9;]\\+')) < 0 then
return line
end
if type(line) ~= 'string' then
return line
end
line = vim.fn.substitute(line, '\\%x1b\\[[0-9;]\\+[mK]', '', 'g')
log(line)
return line
end
if _GO_NVIM_CFG.run_in_floaterm or optarg['F'] then
local term = require('go.term').run
cmd = table.concat(cmd, ' ')
term({ cmd = cmd, autoclose = false })
return
local cmdstr = table.concat(cmd, ' ')
term({ cmd = cmdstr, autoclose = false })
return cmd
end
return M.runjob(cmd, runner, efm, args)
end
local function handle_color(line)
if tonumber(vim.fn.match(line, '\\%x1b\\[[0-9;]\\+')) < 0 then
return line
end
if type(line) ~= 'string' then
return line
end
line = vim.fn.substitute(line, '\\%x1b\\[[0-9;]\\+[mK]', '', 'g')
log(line)
return line
end
M.runjob = function(cmd, runner, args, efm)
vim.validate({ cmd = { cmd, 't' }, runner = { runner, 's' } })
efm = efm or compile_efm()
local failed = false
local itemn = 1
local lines = {}
local errorlines = {}
local cmdstr = vim.fn.join(cmd, ' ') -- cmd list run without shell, cmd string run with shell
local package_path = (cmd[#cmd] or '')
if package_path ~= nil then
@ -243,8 +248,6 @@ function M.make(...)
else
package_path = ''
end
local cmdstr = vim.fn.join(cmd, ' ') -- cmd list run without shell, cmd string run with shell
local Sprite = util.load_plugin('guihua.lua', 'guihua.sprite')
local sprite
if Sprite then
@ -281,7 +284,7 @@ function M.make(...)
if vim.fn.empty(vim.fn.glob(args[#args])) == 0 then -- pkg name in args
changed = true
if value:find('FAIL') == nil then
local p, fn, ln = extract_filepath(value, package_path)
local p, _, _ = extract_filepath(value, package_path)
if p == true then -- path existed, but need to attach the pkg name
-- log(fn, ln, package_path, package_path:gsub('%.%.%.', ''))
-- remove ... in package path
@ -299,8 +302,8 @@ function M.make(...)
log(value)
end
end
log(value, #lines)
table.insert(lines, value)
log(value, #lines)
if itemn == 1 and failed and changed then
itemn = #lines
end
@ -330,11 +333,9 @@ function M.make(...)
end
if event == 'exit' then
log('exit')
sprite.on_close()
if type(cmd) == 'table' then
cmd = table.concat(cmd, ' ')
end
local info = cmd
local info = cmdstr
local level = vim.log.levels.INFO
if #errorlines > 0 then
if #lines > 0 then
@ -342,26 +343,28 @@ function M.make(...)
end
trace(errorlines)
vim.fn.setqflist({}, ' ', {
title = cmd,
title = info,
lines = errorlines,
efm = efm,
})
failed = true
log(errorlines[1], job_id)
vim.cmd([[echo v:shell_error]])
vim.schedule(function()
vim.cmd([[echo v:shell_error]])
end)
elseif #lines > 0 then
trace(lines)
local opts = {}
if _GO_NVIM_CFG.test_efm == true then
efm = require('go.gotest').efm()
opts = {
title = cmd,
title = info,
lines = lines,
efm = efm,
}
else
opts = {
title = cmd,
title = info,
lines = lines,
}
end
@ -370,12 +373,12 @@ function M.make(...)
if tonumber(data) ~= 0 then
failed = true
info = info .. ' exited with code: ' .. tostring(data)
info = info .. ' exited with code: ' .. tostring(data) .. vim.inspect(errorlines)
level = vim.log.levels.ERROR
end
_GO_NVIM_CFG.job_id = nil
if failed then
cmd = cmd .. ' go test failed'
info = info .. ' go test failed'
level = vim.log.levels.WARN
util.quickfix('botright copen')
end
@ -385,6 +388,7 @@ function M.make(...)
vim.notify(info .. ' failed', level)
else
vim.notify(info .. ' succeed', level)
vim.notify(table.concat(lines, '\n\r'), level)
end
failed = false
_GO_NVIM_CFG.on_exit(event, data)
@ -393,17 +397,18 @@ function M.make(...)
-- releative dir does not work without shell
log('cmd ', cmdstr)
if is_windows then -- gitshell is more like cmd.exe
cmdstr = cmd
local runcmd = cmdstr
if is_windows then -- gitshell & cmd.exe prefer list
runcmd = cmd
end
_GO_NVIM_CFG.job_id = vim.fn.jobstart(cmdstr, {
_GO_NVIM_CFG.job_id = vim.fn.jobstart(runcmd, {
on_stderr = on_event,
on_stdout = on_event,
on_exit = on_event,
stdout_buffered = true,
stderr_buffered = true,
})
_GO_NVIM_CFG.on_jobstart(cmdstr)
_GO_NVIM_CFG.on_jobstart(runcmd)
return cmd
end
@ -419,5 +424,5 @@ M.stopjob = function(id)
util.warn('failed to stop job ' .. tostring(id))
end
end
M.compile_efm = compile_efm
return M

@ -6,6 +6,11 @@ local log = utils.log
local max_len = _GO_NVIM_CFG.max_line_len or 120
local gofmt = _GO_NVIM_CFG.gofmt or 'gofumpt'
local vfn = vim.fn
local write_delay = 10
if _GO_NVIM_CFG.lsp_fmt_async then
write_delay = 200
end
local install = require('go.install').install
local gofmt_args = _GO_NVIM_CFG.gofmt_args
or {
@ -41,18 +46,19 @@ local run = function(fmtargs, bufnr, cmd)
bufnr = bufnr,
name = 'gopls',
})
vim.defer_fn(function()
if vfn.getbufinfo('%')[1].changed == 1 then
vim.cmd('noautocmd write')
end
end, 200)
if not _GO_NVIM_CFG.lsp_fmt_async then
vim.defer_fn(function()
if vfn.getbufinfo('%')[1].changed == 1 then
vim.cmd('noautocmd write')
end
end, write_delay)
end
end
local args = vim.deepcopy(fmtargs)
table.insert(args, api.nvim_buf_get_name(bufnr))
log('formatting buffer... ' .. vim.inspect(args), vim.log.levels.DEBUG)
local old_lines = api.nvim_buf_get_lines(0, 0, -1, true)
if cmd then
table.insert(args, 1, cmd)
@ -93,7 +99,7 @@ local run = function(fmtargs, bufnr, cmd)
if vfn.getbufinfo('%')[1].changed == 1 then
vim.cmd('noautocmd write')
end
end, 300)
end, 200)
end,
stdout_buffered = true,
stderr_buffered = true,
@ -155,9 +161,13 @@ M.org_imports = function()
bufnr = vim.api.nvim_get_current_buf(),
name = 'gopls',
})
vim.defer_fn(function()
vim.cmd('noautocmd write')
end, 200)
if not _GO_NVIM_CFG.lsp_fmt_async then
vim.defer_fn(function()
if vfn.getbufinfo('%')[1].changed == 1 then
vim.cmd('noautocmd write')
end
end, write_delay)
end
end)
end

@ -201,7 +201,8 @@ local function get_build_flags()
return nil
end
end
local range_format = 'textDocument/rangeFormatting'
local formatting = 'textDocument/formatting'
M.setups = function()
local setups = {
capabilities = {
@ -279,6 +280,23 @@ M.setups = function()
buildFlags = { '-tags', 'integration' },
},
},
-- NOTE: it is important to add handler to formatting handlers
-- the async formatter will call these handlers when gopls responed
-- without these handlers, the file will not be saved
handlers = {
[range_format] = function(...)
vim.lsp.handlers[range_format](...)
if vfn.getbufinfo('%')[1].changed == 1 then
vim.cmd('noautocmd write')
end
end,
[formatting] = function(...)
vim.lsp.handlers[formatting](...)
if vfn.getbufinfo('%')[1].changed == 1 then
vim.cmd('noautocmd write')
end
end,
},
}
setups.settings.gopls.semanticTokens = true
local v = M.version()
@ -298,7 +316,7 @@ M.setups = function()
setups.settings.gopls.buildFlags = { tags }
end
if ver > 90 and _GO_NVIM_CFG.lsp_inlay_hints.enable then
if ver > 90 and _GO_NVIM_CFG.lsp_inlay_hints.enable and vim.fn.has('nvim-0.10') then
setups.settings.gopls = vim.tbl_deep_extend('force', setups.settings.gopls, {
hints = {
assignVariableTypes = true,

@ -26,12 +26,13 @@ local long_opts = {
}
local sep = require('go.utils').sep()
local short_opts = 'a:cC:t:bsFmpn:v'
local short_opts = 'a:cC:b:fFmn:pst:rv'
local bench_opts = { '-benchmem', '-cpuprofile', 'profile.out' }
local os_name = vim.loop.os_uname().sysname
local is_windows = os_name == 'Windows' or os_name == 'Windows_NT'
local is_git_shell = is_windows and (vim.fn.exists('$SHELL') and vim.fn.expand('$SHELL'):find('bash.exe') ~= nil)
local is_git_shell = is_windows
and (vim.fn.exists('$SHELL') and vim.fn.expand('$SHELL'):find('bash.exe') ~= nil)
M.efm = function()
local indent = [[%\\%( %\\)]]
local efm = [[%-G=== RUN %.%#]]
@ -72,11 +73,10 @@ end
-- return "-tags=tag1,tag2"
M.get_build_tags = function(args, tbl)
-- local tags = "-tags"
args = args or {}
local tags = {}
if _GO_NVIM_CFG.build_tags ~= '' then
tags = { _GO_NVIM_CFG.build_tags }
table.insert(tags, _GO_NVIM_CFG.build_tags)
end
local optarg, _, reminder = getopt.get_opts(args, short_opts, long_opts)
@ -90,13 +90,16 @@ M.get_build_tags = function(args, tbl)
vim.list_extend(tags, rt)
end
local t = '-tags'
if _GO_NVIM_CFG.test_runner == 'dlv' then
t = '--build-flags'
end
if #tags > 0 then
if tbl then
return { '-tags', table.concat(tags, ',') }, reminder, optarg
return { t, table.concat(tags, ',') }, reminder, optarg
end
return '-tags=' .. table.concat(tags, ','), reminder, optarg
return t .. '=' .. table.concat(tags, ','), reminder, optarg
end
return
end
function M.get_test_path()
@ -137,21 +140,25 @@ local function get_test_filebufnr()
return bufnr
end
-- {-c: compile, -v: verbose, -t: tags, -b: bench, -s: select}
local function run_test(path, args)
local function cmd_builder(path, args)
log(args)
local compile = false
local bench = false
local extra_args = ''
for i, arg in ipairs(args) do
--check if it is bench test
if arg:find('-bench') then
bench = true
table.remove(args, i)
break
end
end
local optarg, oid, reminder = getopt.get_opts(args, short_opts, long_opts)
trace(optarg, oid, reminder)
if optarg['c'] then
path = utils.rel_path(true) -- vfn.expand("%:p:h") can not resolve releative path
compile = true
end
if optarg['b'] then
bench = true
end
if reminder and #reminder > 0 then
--if % in args expand to current file
@ -162,10 +169,6 @@ local function run_test(path, args)
end
end
if optarg['a'] then
extra_args = optarg['a']
end
if next(reminder) then
path = reminder[1]
table.remove(reminder, 1)
@ -174,49 +177,56 @@ local function run_test(path, args)
if _GO_NVIM_CFG.test_runner ~= test_runner then
test_runner = _GO_NVIM_CFG.test_runner
if not install(test_runner) then
vim.notify('test runner not found', vim.log.levels.INFO)
test_runner = 'go'
end
end
local tags = M.get_build_tags(args)
log(tags)
local cmd = {}
log('tags', tags)
local cmd = { 'go', 'test' }
local run_in_floaterm = optarg['F'] or _GO_NVIM_CFG.run_in_floaterm
if run_in_floaterm then
table.insert(cmd, test_runner or 'go')
table.insert(cmd, 'test')
cmd[1] = test_runner or 'go'
end
if not empty(tags) then
cmd = vim.list_extend(cmd, { tags })
end
if optarg['C'] then
if run_in_floaterm then
table.insert(cmd, '-coverprofile=' .. optarg['C'])
else
table.insert(cmd, '-C')
table.insert(cmd, optarg['C'])
end
if optarg['c'] then
compile = true
end
if optarg['n'] then
if run_in_floaterm then
table.insert(cmd, '-count=' .. optarg['n'])
else
table.insert(cmd, '-n')
table.insert(cmd, optarg['n'])
end
table.insert(cmd, '-count=' .. optarg['n'])
end
if (optarg['v'] or _GO_NVIM_CFG.verbose_tests) and _GO_NVIM_CFG.test_runner == 'go' then
table.insert(cmd, '-v')
end
if not empty(reminder) then
cmd = vim.list_extend(cmd, reminder)
log('****', reminder, cmd)
if optarg['f'] then
log('fuzz test')
table.insert(cmd, '-fuzz')
end
if optarg['P'] then
table.insert(cmd, '-parallel')
table.insert(cmd, optarg['P'])
end
if optarg['r'] then
log('run test', optarg['r'])
table.insert(cmd, '-run')
table.insert(cmd, optarg['r'])
end
if optarg['b'] and optarg['b'] ~= '' then
log('build test flags', optarg['b'])
assert(type(optarg['b']) == 'string', 'build flags must be string')
table.insert(cmd, optarg['b'])
end
if compile == true then
@ -240,11 +250,27 @@ local function run_test(path, args)
end
end
if #extra_args > 0 then
table.insert(cmd, '-a')
table.insert(cmd, extra_args)
if optarg['C'] then
table.insert(cmd, '-coverprofile=' .. optarg['C'])
end
if not empty(reminder) then
cmd = vim.list_extend(cmd, reminder)
log('****', reminder, cmd)
end
utils.log(cmd, args)
if optarg['a'] then
table.insert(cmd, '-args')
table.insert(cmd, optarg['a'])
end
return cmd, optarg, tags
end
-- {-c: compile, -v: verbose, -t: tags, -b: bench, -s: select}
local function run_test(path, args)
log(args)
local cmd, optarg = cmd_builder(path, args)
log(cmd, args)
local run_in_floaterm = _GO_NVIM_CFG.run_in_floaterm or optarg['F']
if run_in_floaterm then
install('richgo')
local term = require('go.term').run
@ -257,7 +283,8 @@ local function run_test(path, args)
vim.cmd([[setl makeprg=]] .. _GO_NVIM_CFG.go .. [[\ test]])
utils.log('test cmd', cmd)
return require('go.asyncmake').make(unpack(cmd))
local asyncmake = require('go.asyncmake')
return asyncmake.runjob(cmd, 'go test', args)
end
M.test = function(...)
@ -278,8 +305,23 @@ M.test = function(...)
package = 'p',
}
local parallel = 0
for i, arg in ipairs(args) do
--check if it is bench test
if arg:find('-parallel') then
parallel = args[i + 1]:match('%d+')
table.remove(args, i)
table.remove(args, i)
break
end
end
local test_short_opts = 'a:vcC:t:bsfmnpF'
local optarg, _, reminder = getopt.get_opts(args, test_short_opts, test_opts)
if parallel ~= 0 then
optarg['P'] = parallel
table.insert(args, '-P')
table.insert(args, parallel)
end
-- if % in reminder expand to current file
for i, v in ipairs(reminder) do
@ -383,11 +425,8 @@ M.get_testcase_name = function()
end
local function run_tests_with_ts_node(args, func_node, tblcase_ns)
local optarg, _, reminder = getopt.get_opts(args, short_opts, long_opts)
local tags = M.get_build_tags(args)
utils.log('args: ', args)
utils.log('tags: ', tags)
utils.log('parnode' .. vim.inspect(func_node))
local fpath = M.get_test_path()
local cmd, optarg, tags = cmd_builder(fpath, args)
local test_runner = _GO_NVIM_CFG.test_runner or 'go'
@ -395,54 +434,19 @@ local function run_tests_with_ts_node(args, func_node, tblcase_ns)
if not install(test_runner) then
test_runner = 'go'
end
if test_runner == 'ginkgo' then
ginkgo.test_func(args)
end
end
local run_flags = '-r'
local cmd = {}
local run_in_floaterm = optarg['F'] or _GO_NVIM_CFG.run_in_floaterm
if run_in_floaterm then
table.insert(cmd, test_runner)
table.insert(cmd, 'test')
run_flags = '-run'
if test_runner == 'ginkgo' then
return ginkgo.test_func(args)
end
if optarg['s'] then
return M.select_tests()
end
if (optarg['v'] or _GO_NVIM_CFG.verbose_tests) and _GO_NVIM_CFG.test_runner == 'go' then
table.insert(cmd, '-v')
end
if tags and tags ~= '' then
table.insert(cmd, tags)
end
if func_node == nil or func_node.name == nil then
return
end
if optarg['n'] then
if run_in_floaterm then
table.insert(cmd, '-count')
table.insert(cmd, (optarg['n'] or '1'))
else
table.insert(cmd, '-n')
table.insert(cmd, (optarg['n'] or '1'))
end
end
if optarg['C'] then
if run_in_floaterm then
table.insert(cmd, '-count')
table.insert(cmd, optarg['C'])
else
table.insert(cmd, '-C')
table.insert(cmd, optarg['C'])
end
end
local tbl_name = ''
if tblcase_ns then
tbl_name = tblcase_ns:gsub('/', '//')
@ -452,50 +456,39 @@ local function run_tests_with_ts_node(args, func_node, tblcase_ns)
end
if func_node.name:find('Bench') then
if run_in_floaterm then
local bench = '-bench=' .. func_node.name .. tbl_name
table.insert(cmd, bench)
else
table.insert(cmd, '-b')
table.insert(cmd, func_node.name)
local bench = '-bench=' .. func_node.name .. tbl_name
for i, v in ipairs(cmd) do
if v:find('-bench') then
cmd[i] = bench
break
end
if i == #cmd then
table.insert(cmd, bench)
end
end
vim.list_extend(cmd, bench_opts)
elseif func_node.name:find('Fuzz') then
if run_in_floaterm then
table.insert(cmd, '-fuzz=func_node.name')
else
table.insert(cmd, '-f')
table.insert(cmd, func_node.name)
end
table.insert(cmd, '-fuzz=' .. func_node.name)
else
table.insert(cmd, run_flags)
table.insert(cmd, '-run')
if is_windows then
table.insert(cmd, [[^]] .. func_node.name .. [[$]] .. tbl_name)
table.insert(cmd, [["^]] .. func_node.name .. [[$"]] .. tbl_name)
else
table.insert(cmd, [['^]] .. func_node.name .. [[$']] .. tbl_name)
end
end
local fpath = M.get_test_path()
table.insert(cmd, fpath)
if optarg['a'] then
table.insert(cmd, '-a')
table.insert(cmd, optarg['a'])
end
if test_runner == 'dlv' then
local runflag = string.format("-test.run='^%s$'%s", func_node.name, tbl_name)
if tags and #tags > 0 then
cmd = { 'dlv', 'test', fpath, '--build-flags', tags, '--', runflag }
else
cmd = { 'dlv', 'test', fpath, '--', runflag }
end
table.insert(cmd, 3, fpath)
table.insert(cmd, '--')
table.insert(cmd, runflag)
log(cmd)
local term = require('go.term').run
term({ cmd = cmd, autoclose = false })
return
end
local run_in_floaterm = optarg['F'] or _GO_NVIM_CFG.run_in_floaterm
if run_in_floaterm then
utils.log(cmd)
@ -505,13 +498,12 @@ local function run_tests_with_ts_node(args, func_node, tblcase_ns)
term({ cmd = cmd, autoclose = false })
return
end
vim.list_extend(cmd, reminder)
vim.cmd([[setl makeprg=]] .. test_runner .. [[\ test]])
-- set_efm()
utils.log('test cmd', cmd)
return require('go.asyncmake').make(unpack(cmd))
return require('go.asyncmake').runjob(cmd, 'go test', args)
end
--options {s:select, F: floaterm}
@ -524,8 +516,7 @@ M.test_func = function(...)
return M.select_tests()
end
local parser_path = vim.api.nvim_get_runtime_file('parser' .. sep .. 'go.so', false)[1]
if not parser_path then
if not vim.api.nvim_get_runtime_file('parser' .. sep .. 'go.so', false)[1] then
-- require('nvim-treesitter.install').commands.TSInstallSync['run!']('go')
vim.notify(
'go treesitter parser not found, please Run `:TSInstallSync go`',
@ -566,18 +557,18 @@ M.get_test_cases = function()
.. [[| sed -n 's/func\s\+\(Test.*\)(.*/\1/p' | xargs | sed 's/ /\\|/g']]
-- TODO maybe with treesitter or lsp list all functions in current file and regex with Test
if vfn.executable('sed') == 0 then
vim.notify('sed not found', vim.log.levels.WARN)
return
end
local tests = vfn.systemlist(cmd)
local tests_results = vfn.systemlist(cmd)
if vim.v.shell_error ~= 0 then
utils.warn('go test failed' .. vim.inspect(tests))
utils.warn('go test failed' .. vim.inspect(tests_results))
return
end
return tests[1]
return tests_results[1]
end
local sep = '|'
local testsstr = vim.fn.join(tests, sep)
local testsstr = vim.fn.join(tests, '|')
utils.log(tests, testsstr)
return testsstr, tests
end
@ -593,18 +584,12 @@ M.test_file = function(...)
return M.test_package(...)
end
local optarg, _, reminder = getopt.get_opts(args, short_opts, long_opts)
local run_in_floaterm = optarg['F'] or _GO_NVIM_CFG.run_in_floaterm
if vfn.empty(tests) == 1 then
vim.notify('no test found fallback to package test', vim.log.levels.DEBUG)
M.test_package(...)
return
end
local tags = M.get_build_tags(args)
local test_runner = _GO_NVIM_CFG.go
if _GO_NVIM_CFG.test_runner ~= 'go' then
test_runner = _GO_NVIM_CFG.test_runner
@ -618,79 +603,70 @@ M.test_file = function(...)
local relpath = utils.rel_path(true)
log(relpath)
--
-- local optarg, _, reminder = getopt.get_opts(args, short_opts, long_opts)
--
-- local run_in_floaterm = optarg['F'] or _GO_NVIM_CFG.run_in_floaterm
-- local tags = M.get_build_tags(args)
--
-- local cmd_args = { 'go', 'test' }
-- if run_in_floaterm then
-- cmd_args[1] = test_runner or 'go'
-- end
--
-- if (optarg['v'] or _GO_NVIM_CFG.verbose_tests) and _GO_NVIM_CFG.test_runner == 'go' then
-- table.insert(cmd_args, '-v')
-- end
--
-- if tags ~= nil then
-- table.insert(cmd_args, tags)
-- end
--
-- if next(reminder) then
-- vim.list_extend(cmd_args, reminder)
-- end
-- if optarg['n'] then
-- table.insert(cmd_args, '-count=' .. (optarg['n'] or '1'))
-- table.insert(cmd_args, optarg['n'] or '1')
-- end
--
-- if optarg['C'] then
-- table.insert(cmd_args, '-coverprofile=' .. optarg['C'])
-- end
--
local cmd_args, optarg = cmd_builder(relpath, args)
local cmd_args = {}
if run_in_floaterm then
table.insert(cmd_args, test_runner)
table.insert(cmd_args, 'test')
end
if (optarg['v'] or _GO_NVIM_CFG.verbose_tests) and _GO_NVIM_CFG.test_runner == 'go' then
table.insert(cmd_args, '-v')
end
if tags ~= nil then
table.insert(cmd_args, tags)
end
if next(reminder) then
vim.list_extend(cmd_args, reminder)
end
if optarg['n'] then
if run_in_floaterm then
table.insert(cmd_args, '-count=' .. (optarg['n'] or '1'))
table.insert(cmd_args, optarg['n'] or '1')
else
table.insert(cmd_args, '-n')
table.insert(cmd_args, optarg['n'] or '1')
end
end
if optarg['C'] then
if run_in_floaterm then
table.insert(cmd_args, '-coverprofile=' .. optarg['C'])
else
table.insert(cmd_args, '-C')
table.insert(cmd_args, optarg['C'])
end
end
if run_in_floaterm then
table.insert(cmd_args, '-run')
else
table.insert(cmd_args, '-r')
end
table.insert(cmd_args, '-run')
if is_windows then
tests = tests
tests = '"' .. tests .. '"'
else
tests = "'" .. tests .. "'"
end
table.insert(cmd_args, tests) -- shell script | is a pipe
table.insert(cmd_args, relpath)
if run_in_floaterm then
if optarg['F'] or _GO_NVIM_CFG.run_in_floaterm then
install('richgo')
local term = require('go.term').run
cmd_args = richgo(cmd_args)
cmd_args = table.concat(cmd_args, ' ')
local cmd_args_str = table.concat(cmd_args, ' ')
log(cmd_args)
term({ cmd = cmd_args, autoclose = false })
term({ cmd = cmd_args_str, autoclose = false })
return cmd_args
end
if _GO_NVIM_CFG.test_runner == 'dlv' then
cmd_args = { 'dlv', 'test', relpath, '--', '-test.run', tests }
cmd_args = table.concat(cmd_args, ' ')
local term = require('go.term').run
term({ cmd = cmd_args, autoclose = false })
term({ cmd = table.concat(cmd_args, ' '), autoclose = false })
log(cmd_args)
return cmd_args
end
vim.cmd([[setl makeprg=]] .. _GO_NVIM_CFG.go .. [[\ test]])
log(cmd_args)
local cmdret = require('go.asyncmake').make(unpack(cmd_args))
local cmdret = require('go.asyncmake').runjob(cmd_args, 'go test', args)
utils.log('test cmd: ', cmdret, ' finished')
return cmdret

@ -7,17 +7,6 @@ local diagnostic_map = function(bufnr)
api.nvim_buf_set_keymap(bufnr, 'n', ']O', ':lua vim.diagnostic.setloclist()<CR>', opts)
end
if vim.lsp.buf.format == nil then
-- neovim < 0.8 only
vim.lsp.buf.format = function(options)
if options.async then
vim.lsp.buf.formatting()
else
vim.lsp.buf.formatting_sync()
end
end
end
if vim.fn.has('nvim-0.8.3') ~= 1 then
return vim.notify(
'Please upgrade to neovim 0.8.3 or above',

@ -88,6 +88,7 @@ local term = function(opts)
opts.win_height = opts.win_height or win_height
opts.win_width = opts.win_width or win_width
opts.border = opts.border or 'single'
opts.title_colors = _GO_NVIM_CFG.floaterm.title_colors
if opts.autoclose == nil then
opts.autoclose = true
end
@ -95,7 +96,7 @@ local term = function(opts)
if type(opts.cmd) == 'table' then
opts.cmd = table.concat(opts.cmd, ' ')
end
opts.title = opts.title or opts.cmd:sub(1, 40)
opts.title = opts.title or opts.cmd:sub(1, win_width - 4)
utils.log(opts)
local buf, win, closer = guihua_term.floating_term(opts)

@ -1,3 +1,3 @@
module github.com/go.nvim
module github.com/ray-x/go.nvim/lua/tests/fixtures/coverage
go 1.17
go 1.21.1

@ -1,3 +1,3 @@
module fill
module github.com/ray-x/go.nvim/lua/tests/fixtures/fill
go 1.17
go 1.21.1

@ -1,3 +1,3 @@
module github.com/go.nvim
module github.com/ray-x/go.nvim/lua/tests/fixtures/fixplurals
go 1.18
go 1.21.1

@ -1,3 +1,3 @@
module github.com/go.nvim
module github.com/ray-x/go.nvim/lua/tests/fixtures/fmt
go 1.17
go 1.21.1

@ -1,3 +1,3 @@
module main
module github.com/ray-x/go.nvim/lua/tests/fixtures/ts
go 1.18
go 1.21.1

@ -22,7 +22,7 @@ describe('should run func test', function()
vim.fn.setpos('.', { 0, 5, 11, 0 })
local cmd = require('go.gotest').test_func()
eq({ 'go', 'test', '-run', [['^Test_branch$']], './lua/tests/fixtures/coverage' }, cmd)
eq({ 'go', 'test', './lua/tests/fixtures/coverage', '-run', [['^Test_branch$']] }, cmd)
end)
it('should test function inside a source code', function()
--
@ -40,7 +40,7 @@ describe('should run func test', function()
vim.fn.setpos('.', { 0, 6, 11, 0 })
local cmd = require('go.gotest').test_func()
eq({ 'go', 'test', '-run', [['^Test_branch$']], './lua/tests/fixtures/coverage' }, cmd)
eq({ 'go', 'test', './lua/tests/fixtures/coverage', '-run', [['^Test_branch$']] }, cmd)
end)
it('should test function with additional args to test binary', function()
--
@ -58,18 +58,15 @@ describe('should run func test', function()
vim.fn.setpos('.', { 0, 5, 11, 0 })
local cmd = require('go.gotest').test_func('-a', 'mock=true')
eq(
{
'go',
'test',
'-run',
[['^Test_branch$']],
'./lua/tests/fixtures/coverage',
'-args',
'mock=true',
},
cmd
)
eq({
'go',
'test',
'./lua/tests/fixtures/coverage',
'-args',
'mock=true',
'-run',
[['^Test_branch$']],
}, cmd)
end)
end)
@ -93,7 +90,13 @@ describe('should run test file', function()
vim.fn.setpos('.', { 0, 5, 11, 0 })
local cmd = require('go.gotest').test_file()
eq({ 'go', 'test', '-run', [['Test_branch|TestBranch|TestBranchSubTest']], 'lua/tests/fixtures/coverage' }, cmd)
eq({
'go',
'test',
'lua/tests/fixtures/coverage',
'-run',
[['Test_branch|TestBranch|TestBranchSubTest']],
}, cmd)
end)
end)
@ -116,17 +119,14 @@ describe('should run test file with flags', function()
vim.fn.setpos('.', { 0, 5, 11, 0 })
local cmd = require('go.gotest').test_file('-t', 'tag1')
eq(
{
'go',
'test',
'-tags=tag1',
'-run',
[['Test_branch|TestBranch|TestBranchSubTest']],
'lua/tests/fixtures/coverage',
},
cmd
)
eq({
'go',
'test',
'-tags=tag1',
'lua/tests/fixtures/coverage',
'-run',
[['Test_branch|TestBranch|TestBranchSubTest']],
}, cmd)
end)
end)
@ -172,7 +172,7 @@ describe('should run test ', function()
local cmd = require('go.gotest').test('-n', '-t', 'tags1')
eq(
{ 'go', 'test', '-tags=tags1', '-run', [['^Test_branch$']], './lua/tests/fixtures/coverage' },
{ 'go', 'test', '-tags=tags1', './lua/tests/fixtures/coverage', '-run', [['^Test_branch$']] },
cmd
)
end)
@ -225,9 +225,9 @@ describe('should run test file with flags inside file', function()
'go',
'test',
'-tags=tag1,integration,unit',
'lua/tests/fixtures/coverage',
'-run',
[['TestTag']],
'lua/tests/fixtures/coverage',
}, cmd)
end)
end)
@ -248,7 +248,7 @@ describe('should run subcase test', function()
vim.cmd("silent exe 'e " .. path .. "'")
vim.fn.setpos('.', { 1, 18, 11, 0 })
local cmd = require('go.gotest').test_tblcase()
eq({ 'go', 'test', '-run', [['^Test_branch$'/"a10"]], './lua/tests/fixtures/coverage' }, cmd)
eq({ 'go', 'test', './lua/tests/fixtures/coverage', '-run', [['^Test_branch$'/"a10"]] }, cmd)
end)
it('should test subcase in table test style when cursor inside test block', function()
@ -264,7 +264,7 @@ describe('should run subcase test', function()
vim.cmd("silent exe 'e " .. path .. "'")
vim.fn.setpos('.', { 1, 29, 12, 0 })
local cmd = require('go.gotest').test_tblcase()
eq({ 'go', 'test', '-run', [['^Test_branch$'/"b10"]], './lua/tests/fixtures/coverage' }, cmd)
eq({ 'go', 'test', './lua/tests/fixtures/coverage', '-run', [['^Test_branch$'/"b10"]] }, cmd)
end)
it('should test subcase in subtest style', function()
@ -280,7 +280,10 @@ describe('should run subcase test', function()
vim.cmd("silent exe 'e " .. path .. "'")
vim.fn.setpos('.', { 1, 75, 11, 0 })
local cmd = require('go.gotest').test_tblcase()
eq({ 'go', 'test', '-run', [['^TestBranchSubTest$'/"a11"]], './lua/tests/fixtures/coverage' }, cmd)
eq(
{ 'go', 'test', './lua/tests/fixtures/coverage', '-run', [['^TestBranchSubTest$'/"a11"]] },
cmd
)
end)
it('should test subcase in subtest style when cursor insde test block', function()
@ -296,6 +299,9 @@ describe('should run subcase test', function()
vim.cmd("silent exe 'e " .. path .. "'")
vim.fn.setpos('.', { 1, 82, 7, 0 })
local cmd = require('go.gotest').test_tblcase()
eq({ 'go', 'test', '-run', [['^TestBranchSubTest$'/"b11"]], './lua/tests/fixtures/coverage' }, cmd)
eq(
{ 'go', 'test', './lua/tests/fixtures/coverage', '-run', [['^TestBranchSubTest$'/"b11"]] },
cmd
)
end)
end)

@ -0,0 +1,24 @@
package pkg
import (
"strconv"
"testing"
)
func Fib(n string) string {
nn, _ := strconv.Atoi(n)
if nn < 2 {
r := strconv.Itoa(nn)
return r
}
n1, _ := strconv.Atoi(Fib(strconv.Itoa(nn - 1)))
n2, _ := strconv.Atoi(Fib(strconv.Itoa(nn - 2)))
return strconv.Itoa(n1 + n2)
}
func BenchmarkFib10(b *testing.B) {
// run the Fib function b.N times
for n := 0; n < b.N; n++ {
Fib("10")
}
}

@ -2,6 +2,7 @@ package pkg
import (
"strings"
"sync"
)
func FindAllSubStr(stack, niddle string) (result []int) {
@ -19,10 +20,13 @@ func FindAllSubStr(stack, niddle string) (result []int) {
func FindSubStr(stack, niddle string) (result int) {
stack = strings.ToLower(stack)
niddle = strings.ToLower(niddle)
mu := sync.Mutex{}
for idx := 1; idx >= 0; {
mu.Lock()
if idx = strings.Index(stack, niddle); idx != -1 {
return idx
}
mu.Unlock()
}
return -1
}

@ -64,3 +64,9 @@ func TestFindSubStr(t *testing.T) {
})
}
}
func BenchmarkPrimeNumbers(b *testing.B) {
for i := 0; i < b.N; i++ {
FindSubStr("Foobarfobafoooo", "foo")
}
}

Loading…
Cancel
Save