Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,33 @@ jobs:
# neovim: true
# version: nightly

# 2. Checkout Neovim source into a subdirectory
# 2. Checkout Neovim source into a subdirectory.
- name: Checkout Neovim
uses: actions/checkout@v4
with:
repository: neovim/neovim
path: neovim
fetch-depth: 1

# 3. Install test dependencies (Neovim's framework needs them)
# 3. Install Neovim's test dependencies.
- name: Install deps
run: |
# sudo apt-get update
sudo apt-get install -y ninja-build gettext cmake curl build-essential git

# 4. Build Neovim’s test environment (no need to build the binary)
# 4. Build Neovim. Run a dummy test. This avoids build noise in the logs for the next step.
- name: Setup Neovim test environment
run: make -C neovim deps
env:
GH_TOKEN: ${{ github.token }}
NEOVIM_PATH: ${{ github.workspace }}/neovim
run: |
make patch-runner
cd neovim
TEST_FILE=test/functional/example_spec.lua make functionaltest

# 5. Run your plugin tests using Neovim’s framework
# 5. Run the plugin tests using Neovim’s framework.
- name: Run plugin tests
run: make test
env:
GH_TOKEN: ${{ github.token }}
NEOVIM_PATH: ${{ github.workspace }}/neovim
run: make test
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@
# Run tests with "nvim -l" instead of "-ll", so tests can use the full "vim."
# API from the Nvim test harness process itself.
patch-runner:
sed -i.bak 's/-ll /-l /' $(NEOVIM_PATH)/cmake/RunTests.cmake && rm $(NEOVIM_PATH)/cmake/RunTests.cmake.bak
@if grep -q -- "-ll " "$(NEOVIM_PATH)/cmake/RunTests.cmake"; then \
echo "Patching RunTests.cmake (-ll → -l)..."; \
sed -i.bak 's/-ll /-l /' "$(NEOVIM_PATH)/cmake/RunTests.cmake" && rm -f "$(NEOVIM_PATH)/cmake/RunTests.cmake.bak"; \
else \
echo "RunTests.cmake already patched; skipping."; \
fi


test: patch-runner
ifeq ($(NEOVIM_PATH),)
$(error NEOVIM_PATH is not set)
endif
ln -sf $(shell pwd) $(NEOVIM_PATH)/test/functional/guh.nvim
cd $(NEOVIM_PATH) && TEST_FILE=test/functional/guh.nvim/test/gh_spec.lua make functionaltest
@cd $(NEOVIM_PATH) && env GH_TOKEN=$${GH_TOKEN:-$(shell gh auth token 2>/dev/null)} \
TEST_FILE=test/functional/guh.nvim/test/gh_spec.lua make functionaltest
1 change: 1 addition & 0 deletions lua/guh/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function M.system_str(cmd, cb)
if result.code ~= 0 and #result.stderr > 0 then
config.log('system_str error', result.stderr)
M.notify(result.stderr, vim.log.levels.ERROR)
error(result.stderr)
end

cb(result.stdout, result.stderr)
Expand Down
139 changes: 69 additions & 70 deletions test/gh_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ vim.opt.runtimepath:append{

local t = require('test.testutil')
local n = require('test.functional.testnvim')()
local Screen = require('test.functional.ui.screen')
local clear, eq, eval, command, feed, insert, wait = n.clear, t.eq, n.eval, n.command, n.feed, n.insert, n.wait

local async = require('async')
Expand All @@ -20,11 +21,10 @@ local get_issue_async = async.wrap(2, gh.get_issue)

local tests = {}

function tests.test_get_pr_info(ctx)
function tests.test_get_pr_info()
return async.run(function()
local result = system_str_async('gh pr list --json number')
local pr_num = assert(vim.json.decode(assert(result))[1].number, 'failed to get a repo issue')
ctx.desc = ('(pr=%s)'):format(pr_num)
local result = assert(system_str_async('gh pr list --json number'))
local pr_num = assert(vim.json.decode(result)[1].number, 'failed to get a repo issue')

local pr = get_pr_info_async(pr_num)
assert(pr, 'pr is nil')
Expand All @@ -34,11 +34,10 @@ function tests.test_get_pr_info(ctx)
end)
end

function tests.test_get_issue(ctx)
function tests.test_get_issue()
return async.run(function()
local result = system_str_async('gh issue list --json number')
local issue_num = assert(vim.json.decode(assert(result))[1].number, 'failed to get a repo issue')
ctx.desc = ('(issue=%s)'):format(issue_num)

local issue = get_issue_async(issue_num)
assert(issue, 'issue is nil')
Expand All @@ -49,7 +48,7 @@ function tests.test_get_issue(ctx)
end

-- Tests hardcoded diff.
function tests.test_get_prepare_comment(ctx)
function tests.test_get_prepare_comment()
local pr_id = 42
local buf = state.get_buf('diff', pr_id)
state.show_buf(buf)
Expand Down Expand Up @@ -81,68 +80,14 @@ function tests.test_get_prepare_comment(ctx)
assert(buf == info.buf, info.buf)
end

-- Tests real response from "gh pr diff".
function tests.test_get_prepare_comment2(ctx)
return async.run(function()
local pr_id = 1
ctx.desc = ('(pr=%s)'):format(pr_id)

return async.await(function(callback)
vim.schedule(function()
vim.cmd(('GuhDiff %d'):format(pr_id))

-- Wait for the buffer to be created and have content
local ok, buf = vim.wait(5000, function()
local b = vim.fn.bufnr(('guh://diff/%d'):format(pr_id))
if b <= 0 then return false end
local lines = vim.api.nvim_buf_get_lines(b, 0, -1, false)
return #lines > 0, b
end)
assert(ok)

-- Set the current buffer
vim.api.nvim_set_current_buf(buf)

-- Find a line with a '+' (added line or +++ header)
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local target_line
for i, line in ipairs(lines) do
if line:match('^%+') and not line:match('^%+%+%+') then
target_line = i
break
end
end
assert(target_line, 'No added line (+) found in diff')

-- Move cursor to the found line
vim.api.nvim_win_set_cursor(0, {target_line, 0})

-- Call prepare_to_comment
local info = pr_commands.prepare_to_comment(target_line, target_line)

-- Assert the returned info
assert(info, 'prepare_to_comment returned nil')
assert(type(info.file) == 'string', 'file is not a string')
assert(16 == info.start_line)
assert(type(info.start_line) == 'number', 'start_line is not a number')
assert(type(info.end_line) == 'number', 'end_line is not a number')
assert(info.pr_id == pr_id, ('pr_id is not %s'):format(pr_id))

callback()
end)
end)
end)
end

-- Tests real comments response Github.
-- Calls load_comments() and asserts that some comments were loaded into quickfix.
function tests.test_get_comments(ctx)
function tests.test_get_comments()
return async.run(function()
local result = system_str_async('gh pr list --json number')
local prs = assert(vim.json.decode(assert(result)), 'failed to get PRs')
assert(#prs > 0, 'no PRs found')
local pr_num = prs[1].number
ctx.desc = ('(pr=%s)'):format(pr_num)

return async.await(function(callback)
vim.schedule(function()
Expand Down Expand Up @@ -175,11 +120,10 @@ function tests.test_get_comments(ctx)
end

-- Tests that ":Guh 1" shows the issue in a buffer.
function tests.test_Guh(ctx)
function tests.test_Guh()
return async.run(function()
local result = system_str_async('gh issue list --json number')
local issue_num = assert(vim.json.decode(assert(result))[1].number, 'failed to get a repo issue')
ctx.desc = ('(issue=%s)'):format(issue_num)
local result = assert(system_str_async('gh issue list --json number'))
local issue_num = assert(vim.json.decode(result)[1].number, 'failed to get a repo issue')

return async.await(function(callback)
vim.schedule(function()
Expand All @@ -205,11 +149,66 @@ function tests.test_Guh(ctx)
end

describe('guh.gh', function()
-- THIS IS AN EXAMPLE. DO NOT TOUCH. USE IT TO CREATE OTHER it() CASES.
it('get_pr_info', function()
local screen
before_each(function()
clear()
screen = Screen.new(80, 10)
n.exec_lua[[
-- TODO: do this in global test setup
vim.opt.runtimepath:append{
vim.fn.getcwd() .. '/test/functional/guh.nvim/',
}
require('guh').setup({})
]]
end)

it(':GuhDiff', function()
n.command('GuhDiff 1')
-- screen:snapshot_util()

screen:expect{
attr_ids = {}, -- Don't care about colors.
grid = [[
^diff --git {MATCH:a/.* b/.* +}|
new file mode {MATCH:%d+ +}|
index {MATCH:.*}|
--- {MATCH:.*}|
+++ {MATCH:.*}|
@@ {MATCH:.*} @@ {MATCH: +}|
{MATCH:.*}|
{MATCH:.*}|
{MATCH:.*}|
{MATCH:.*}|
]]
}
end)

pending('get_pr_info', function()
local task = tests.test_get_pr_info()
local ok, rv = task:pwait()
assert(ok)
local ok, err = task:wait(5000)
assert(ok, err or 'get_pr_info failed')
end)

pending('get_issue', function()
local task = tests.test_get_issue()
local ok, err = task:wait(5000)
assert(ok, err or 'get_issue failed')
end)

it('prepare_to_comment (static diff)', function()
tests.test_get_prepare_comment({})
end)

pending('get_comments', function()
local task = tests.test_get_comments()
local ok, err = task:wait(5000)
assert(ok, err or 'get_comments failed')
end)

pending('Guh command shows issue buffer', function()
local task = tests.test_Guh()
local ok, err = task:wait(5000)
assert(ok, err or 'Guh command failed')
end)
end)

Expand Down