feat: implement public API and plugin commands
Rewrite init.lua to expose setup(), run(), stop(), and toggle() that
coordinate across config, runner, window, and indicator modules. Replace
the placeholder SayHello command in plugin/watchexec.lua with keymaps
(<Leader>wx{t,s,r}), :WatchexecRun/:WatchexecStop/:WatchexecToggle
commands, VimLeavePre cleanup, and VimResized auto-resize.
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
local watchexec = require("watchexec")
|
||||
local stub = require("luassert.stub")
|
||||
|
||||
describe("watchexec commands", function()
|
||||
local runner
|
||||
local window
|
||||
local indicator
|
||||
|
||||
before_each(function()
|
||||
runner = require("watchexec.runner")
|
||||
window = require("watchexec.window")
|
||||
indicator = require("watchexec.indicator")
|
||||
|
||||
stub(runner, "start")
|
||||
stub(runner, "stop")
|
||||
|
||||
stub(runner, "is_running", function()
|
||||
return false
|
||||
end)
|
||||
|
||||
stub(window, "open")
|
||||
stub(window, "close")
|
||||
stub(window, "toggle")
|
||||
|
||||
stub(window, "resize_float")
|
||||
stub(window, "clear")
|
||||
|
||||
stub(window, "is_visible", function()
|
||||
return false
|
||||
end)
|
||||
|
||||
stub(indicator, "refresh")
|
||||
stub(indicator, "reset")
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
runner.start:revert()
|
||||
runner.stop:revert()
|
||||
runner.is_running:revert()
|
||||
|
||||
window.open:revert()
|
||||
window.close:revert()
|
||||
window.toggle:revert()
|
||||
window.resize_float:revert()
|
||||
window.clear:revert()
|
||||
window.is_visible:revert()
|
||||
|
||||
indicator.refresh:revert()
|
||||
indicator.reset:revert()
|
||||
end)
|
||||
|
||||
describe("run()", function()
|
||||
it("opens window and starts runner", function()
|
||||
watchexec.run("echo hello")
|
||||
|
||||
assert.stub(runner.start).was_called_with("echo hello")
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(window.open).was_called(1)
|
||||
end)
|
||||
|
||||
it("does not open window if already visible", function()
|
||||
window.is_visible:revert()
|
||||
stub(window, "is_visible", function()
|
||||
return true
|
||||
end)
|
||||
|
||||
watchexec.run("echo hello")
|
||||
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(window.open).was_called(0)
|
||||
end)
|
||||
|
||||
it("stops previous run before starting new one", function()
|
||||
runner.is_running:revert()
|
||||
stub(runner, "is_running", function()
|
||||
return true
|
||||
end)
|
||||
|
||||
watchexec.run("echo hello")
|
||||
|
||||
assert.stub(runner.stop).was_called(1)
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(runner.start).was_called_with("echo hello")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("stop()", function()
|
||||
it("stops the runner", function()
|
||||
watchexec.stop()
|
||||
|
||||
assert.stub(runner.stop).was_called(1)
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(indicator.reset).was_called(1)
|
||||
assert.stub(indicator.refresh).was_called(1)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("VimLeavePre autocmd", function()
|
||||
it("stops the runner on exit", function()
|
||||
dofile("plugin/watchexec.lua")
|
||||
|
||||
vim.api.nvim_exec_autocmds("VimLeavePre", { group = "watchexec_nvim" })
|
||||
|
||||
assert.stub(runner.stop).was_called(1)
|
||||
assert.stub(window.clear).was_called(0)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("VimResized autocmd", function()
|
||||
it("calls resize_float on terminal resize", function()
|
||||
dofile("plugin/watchexec.lua")
|
||||
|
||||
vim.api.nvim_exec_autocmds("VimResized", { group = "watchexec_nvim" })
|
||||
|
||||
vim.wait(200, function()
|
||||
return pcall(function()
|
||||
assert.stub(window.resize_float).was_called(1)
|
||||
return true
|
||||
end)
|
||||
end)
|
||||
|
||||
assert.stub(window.resize_float).was_called(1)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("keymaps", function()
|
||||
before_each(function()
|
||||
vim.g.loaded_watchexec = nil
|
||||
dofile("plugin/watchexec.lua")
|
||||
end)
|
||||
|
||||
local function leader()
|
||||
return vim.g.mapleader or "\\"
|
||||
end
|
||||
|
||||
it("defines <Leader>wxt toggle keymap", function()
|
||||
local maps = vim.api.nvim_get_keymap("n")
|
||||
local found = false
|
||||
for _, m in ipairs(maps) do
|
||||
if m.lhs == leader() .. "wxt" then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(found)
|
||||
end)
|
||||
|
||||
it("defines <Leader>wxs stop keymap", function()
|
||||
local maps = vim.api.nvim_get_keymap("n")
|
||||
local found = false
|
||||
for _, m in ipairs(maps) do
|
||||
if m.lhs == leader() .. "wxs" then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(found)
|
||||
end)
|
||||
|
||||
it("defines <Leader>wxr run keymap", function()
|
||||
local maps = vim.api.nvim_get_keymap("n")
|
||||
local found = false
|
||||
for _, m in ipairs(maps) do
|
||||
if m.lhs == leader() .. "wxr" then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(found)
|
||||
end)
|
||||
|
||||
it("invokes toggle via <Leader>wxt", function()
|
||||
local ldr = leader()
|
||||
vim.cmd("normal " .. ldr .. "wxt")
|
||||
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(runner.start).was_called(0)
|
||||
assert.stub(window.open).was_called(1)
|
||||
end)
|
||||
|
||||
it("invokes stop via <Leader>wxs", function()
|
||||
local ldr = leader()
|
||||
vim.cmd("normal " .. ldr .. "wxs")
|
||||
|
||||
assert.stub(runner.stop).was_called(1)
|
||||
assert.stub(window.clear).was_called(1)
|
||||
end)
|
||||
|
||||
it("prompts and runs via <Leader>wxr", function()
|
||||
local input_stub = stub(vim.fn, "input", function()
|
||||
return "echo hello"
|
||||
end)
|
||||
|
||||
local ldr = leader()
|
||||
vim.cmd("normal " .. ldr .. "wxr")
|
||||
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(runner.start).was_called_with("echo hello")
|
||||
assert.stub(window.open).was_called(1)
|
||||
|
||||
input_stub:revert()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("toggle()", function()
|
||||
it("opens window with placeholder if nothing running", function()
|
||||
watchexec.toggle()
|
||||
|
||||
assert.stub(window.clear).was_called(1)
|
||||
assert.stub(runner.start).was_called(0)
|
||||
assert.stub(window.open).was_called(1)
|
||||
end)
|
||||
|
||||
it("hides window if runner is running and window is visible", function()
|
||||
runner.is_running:revert()
|
||||
|
||||
stub(runner, "is_running", function()
|
||||
return true
|
||||
end)
|
||||
|
||||
window.is_visible:revert()
|
||||
|
||||
stub(window, "is_visible", function()
|
||||
return true
|
||||
end)
|
||||
|
||||
watchexec.toggle()
|
||||
|
||||
assert.stub(window.clear).was_called(0)
|
||||
assert.stub(runner.start).was_called(0)
|
||||
assert.stub(window.toggle).was_called(1)
|
||||
end)
|
||||
|
||||
it("opens window if runner is running but not visible", function()
|
||||
runner.is_running:revert()
|
||||
|
||||
stub(runner, "is_running", function()
|
||||
return true
|
||||
end)
|
||||
|
||||
window.is_visible:revert()
|
||||
|
||||
stub(window, "is_visible", function()
|
||||
return false
|
||||
end)
|
||||
|
||||
watchexec.toggle()
|
||||
|
||||
assert.stub(window.clear).was_called(0)
|
||||
assert.stub(runner.start).was_called(0)
|
||||
assert.stub(window.open).was_called(1)
|
||||
end)
|
||||
|
||||
it("closes window if nothing running and window is visible", function()
|
||||
window.is_visible:revert()
|
||||
|
||||
stub(window, "is_visible", function()
|
||||
return true
|
||||
end)
|
||||
|
||||
watchexec.toggle()
|
||||
|
||||
assert.stub(window.clear).was_called(0)
|
||||
assert.stub(runner.start).was_called(0)
|
||||
assert.stub(window.close).was_called(1)
|
||||
assert.stub(window.open).was_called(0)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
@@ -2,8 +2,11 @@ local health = require("watchexec.health")
|
||||
local stub = require("luassert.stub")
|
||||
|
||||
describe("watchexec healthcheck", function()
|
||||
local start_stub, ok_stub, error_stub
|
||||
local has_stub, exec_stub
|
||||
local start_stub
|
||||
local ok_stub
|
||||
local error_stub
|
||||
local has_stub
|
||||
local exec_stub
|
||||
|
||||
before_each(function()
|
||||
start_stub = stub(vim.health, "start")
|
||||
@@ -29,6 +32,7 @@ describe("watchexec healthcheck", function()
|
||||
has_stub = stub(vim.fn, "has", function()
|
||||
return 1
|
||||
end)
|
||||
|
||||
exec_stub = stub(vim.fn, "executable", function()
|
||||
return 1
|
||||
end)
|
||||
@@ -44,6 +48,7 @@ describe("watchexec healthcheck", function()
|
||||
has_stub = stub(vim.fn, "has", function()
|
||||
return 1
|
||||
end)
|
||||
|
||||
exec_stub = stub(vim.fn, "executable", function()
|
||||
return 0
|
||||
end)
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
local plugin = require("watchexec")
|
||||
|
||||
describe("watchexec logic", function()
|
||||
before_each(function()
|
||||
plugin.setup({
|
||||
greeting = "Hello Test!",
|
||||
})
|
||||
end)
|
||||
local watchexec = require("watchexec")
|
||||
|
||||
describe("watchexec module", function()
|
||||
it("can be required without errors", function()
|
||||
assert.not_nil(plugin)
|
||||
assert.not_nil(watchexec)
|
||||
end)
|
||||
|
||||
it("correctly applies user configuration", function()
|
||||
assert.equals("Hello Test!", plugin.config.greeting)
|
||||
it("exposes setup function", function()
|
||||
assert.is_function(watchexec.setup)
|
||||
end)
|
||||
|
||||
it("exposes run function", function()
|
||||
assert.is_function(watchexec.run)
|
||||
end)
|
||||
|
||||
it("exposes stop function", function()
|
||||
assert.is_function(watchexec.stop)
|
||||
end)
|
||||
|
||||
it("exposes toggle function", function()
|
||||
assert.is_function(watchexec.toggle)
|
||||
end)
|
||||
|
||||
it("setup delegates to config", function()
|
||||
local config = require("watchexec.config")
|
||||
|
||||
watchexec.setup({ auto_scroll = false })
|
||||
|
||||
assert.equals(false, config.get().auto_scroll)
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user