aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/metadata-diff.yml2
-rw-r--r--.github/workflows/tests.yml19
-rw-r--r--.gitignore2
-rw-r--r--Makefile22
-rw-r--r--lua/nvim-lsp-installer/dispatcher.lua8
-rw-r--r--lua/nvim-lsp-installer/path.lua2
-rw-r--r--lua/nvim-lsp-installer/ui/display.lua19
-rw-r--r--lua/nvim-lsp-installer/ui/status-win/init.lua1
-rw-r--r--tests/README.md1
-rw-r--r--tests/data_spec.lua135
-rw-r--r--tests/dispatcher_spec.lua24
-rw-r--r--tests/fs_spec.lua18
-rw-r--r--tests/luassertx/lua/luassertx.lua27
-rw-r--r--tests/minimal_init.vim30
-rw-r--r--tests/path_spec.lua23
-rw-r--r--tests/server_spec.lua56
-rw-r--r--tests/ui_spec.lua249
17 files changed, 624 insertions, 14 deletions
diff --git a/.github/workflows/metadata-diff.yml b/.github/workflows/metadata-diff.yml
index b2b1679a..f98b6c15 100644
--- a/.github/workflows/metadata-diff.yml
+++ b/.github/workflows/metadata-diff.yml
@@ -16,7 +16,7 @@ jobs:
- uses: rhysd/action-setup-vim@v1
with:
neovim: true
- version: v0.5.1
+ version: v0.6.0
- name: Clone latest lspconfig
run: |
mkdir -p ~/.local/share/nvim/site/pack/packer/start
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 00000000..4e6640fd
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,19 @@
+name: Tests
+
+on:
+ push:
+ branches:
+ - "main"
+ pull_request:
+
+jobs:
+ tests:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: rhysd/action-setup-vim@v1
+ with:
+ neovim: true
+ version: v0.6.0
+ - name: Run tests
+ run: make test
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..978d3570
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/dependencies
+/tests/fixtures/lsp_servers
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..48a28d7a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+INSTALL_ROOT_DIR:=$(shell pwd)/tests/fixtures/lsp_servers
+NVIM_HEADLESS:=nvim --headless --noplugin -u tests/minimal_init.vim
+
+dependencies:
+ git clone --depth 1 https://github.com/nvim-lua/plenary.nvim dependencies/pack/vendor/start/plenary.nvim
+
+.PHONY: clean_dependencies
+clean_dependencies:
+ rm -rf dependencies
+
+.PHONY: clean_servers
+clean_servers:
+ rm -rf "${INSTALL_ROOT_DIR}"
+
+.PHONY: clean
+clean: clean_servers clean_dependencies
+
+.PHONY: test
+test: clean_servers dependencies
+ INSTALL_ROOT_DIR=${INSTALL_ROOT_DIR} $(NVIM_HEADLESS) -c "call RunTests()"
+
+# vim:noexpandtab
diff --git a/lua/nvim-lsp-installer/dispatcher.lua b/lua/nvim-lsp-installer/dispatcher.lua
index 0ad41897..762da3e3 100644
--- a/lua/nvim-lsp-installer/dispatcher.lua
+++ b/lua/nvim-lsp-installer/dispatcher.lua
@@ -4,6 +4,7 @@ local M = {}
local registered_callbacks = {}
+---@param server Server
M.dispatch_server_ready = function(server)
for _, callback in pairs(registered_callbacks) do
local ok, err = pcall(callback, server)
@@ -13,12 +14,11 @@ M.dispatch_server_ready = function(server)
end
end
-local idx = 0
+---@param callback fun(server: Server)
function M.register_server_ready_callback(callback)
- local key = idx + 1
- registered_callbacks[("%d"):format(key)] = callback
+ registered_callbacks[callback] = callback
return function()
- table.remove(registered_callbacks, key)
+ registered_callbacks[callback] = nil
end
end
diff --git a/lua/nvim-lsp-installer/path.lua b/lua/nvim-lsp-installer/path.lua
index ed906954..533be48d 100644
--- a/lua/nvim-lsp-installer/path.lua
+++ b/lua/nvim-lsp-installer/path.lua
@@ -39,7 +39,7 @@ function M.realpath(relpath, depth)
end
function M.is_subdirectory(root_path, path)
- return path:sub(1, #root_path) == root_path
+ return root_path == path or path:sub(1, #root_path + 1) == root_path .. sep
end
return M
diff --git a/lua/nvim-lsp-installer/ui/display.lua b/lua/nvim-lsp-installer/ui/display.lua
index 43550222..889c3ac3 100644
--- a/lua/nvim-lsp-installer/ui/display.lua
+++ b/lua/nvim-lsp-installer/ui/display.lua
@@ -92,12 +92,14 @@ local function render_node(viewport_context, node, _render_context, _output)
local content, hl_group = span[1], span[2]
local col_start = #full_line
full_line = full_line .. content
- line_highlights[#line_highlights + 1] = {
- hl_group = hl_group,
- line = #output.lines,
- col_start = col_start,
- col_end = col_start + #content,
- }
+ if hl_group ~= "" then
+ line_highlights[#line_highlights + 1] = {
+ hl_group = hl_group,
+ line = #output.lines,
+ col_start = col_start,
+ col_end = col_start + #content,
+ }
+ end
end
local active_styles = get_styles(full_line, render_context)
@@ -135,6 +137,9 @@ local function render_node(viewport_context, node, _render_context, _output)
return output
end
+-- exported for tests
+M._render_node = render_node
+
local function create_popup_window_opts()
local win_height = vim.o.lines - vim.o.cmdheight - 2 -- Add margin for status and buffer line
local win_width = vim.o.columns
@@ -314,7 +319,7 @@ function M.new_view_only_win(name)
output.lines, output.virt_texts, output.highlights, output.keybinds
-- set line contents
- vim.api.nvim_buf_clear_namespace(0, namespace, 0, -1)
+ vim.api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1)
vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
diff --git a/lua/nvim-lsp-installer/ui/status-win/init.lua b/lua/nvim-lsp-installer/ui/status-win/init.lua
index 6adcf2ae..3191c6ae 100644
--- a/lua/nvim-lsp-installer/ui/status-win/init.lua
+++ b/lua/nvim-lsp-installer/ui/status-win/init.lua
@@ -769,7 +769,6 @@ local function init(all_servers)
end)
window.open {
- win_width = 95,
highlight_groups = {
"hi def LspInstallerHeader gui=bold guifg=#ebcb8b",
"hi def LspInstallerServerExpanded gui=italic",
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 00000000..bd9259d4
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1 @@
+Refer to https://github.com/williamboman/nvim-lspconfig-test for system tests.
diff --git a/tests/data_spec.lua b/tests/data_spec.lua
new file mode 100644
index 00000000..0e13d44c
--- /dev/null
+++ b/tests/data_spec.lua
@@ -0,0 +1,135 @@
+local Data = require "nvim-lsp-installer.data"
+local spy = require "luassert.spy"
+
+describe("data", function()
+ it("creates enums", function()
+ local colors = Data.enum {
+ "BLUE",
+ "YELLOW",
+ }
+ assert.equal(
+ vim.inspect {
+ ["BLUE"] = "BLUE",
+ ["YELLOW"] = "YELLOW",
+ },
+ vim.inspect(colors)
+ )
+ end)
+
+ it("creates sets", function()
+ local colors = Data.set_of {
+ "BLUE",
+ "YELLOW",
+ "BLUE",
+ "RED",
+ }
+ assert.equal(
+ vim.inspect {
+ ["BLUE"] = true,
+ ["YELLOW"] = true,
+ ["RED"] = true,
+ },
+ vim.inspect(colors)
+ )
+ end)
+
+ it("reverses lists", function()
+ local colors = { "BLUE", "YELLOW", "RED" }
+ assert.equal(
+ vim.inspect {
+ "RED",
+ "YELLOW",
+ "BLUE",
+ },
+ vim.inspect(Data.list_reverse(colors))
+ )
+ -- should not modify in-place
+ assert.equal(vim.inspect { "BLUE", "YELLOW", "RED" }, vim.inspect(colors))
+ end)
+
+ it("maps over list", function()
+ local colors = { "BLUE", "YELLOW", "RED" }
+ assert.equal(
+ vim.inspect {
+ "LIGHT_BLUE1",
+ "LIGHT_YELLOW2",
+ "LIGHT_RED3",
+ },
+ vim.inspect(Data.list_map(function(color, i)
+ return "LIGHT_" .. color .. i
+ end, colors))
+ )
+ -- should not modify in-place
+ assert.equal(vim.inspect { "BLUE", "YELLOW", "RED" }, vim.inspect(colors))
+ end)
+
+ it("coalesces first non-nil value", function()
+ assert.equal("Hello World!", Data.coalesce(nil, nil, "Hello World!", ""))
+ end)
+
+ it("makes a shallow copy of a list", function()
+ local list = { "BLUE", { nested = "TABLE" }, "RED" }
+ local list_copy = Data.list_copy(list)
+ assert.equal(vim.inspect { "BLUE", { nested = "TABLE" }, "RED" }, vim.inspect(list_copy))
+ assert.is_not.is_true(list == list_copy)
+ assert.is_true(list[2] == list_copy[2])
+ end)
+
+ it("finds first item that fulfills predicate", function()
+ local predicate = spy.new(function(item)
+ return item == "Waldo"
+ end)
+
+ assert.equal(
+ "Waldo",
+ Data.list_find_first({
+ "Where",
+ "On Earth",
+ "Is",
+ "Waldo",
+ "?",
+ }, predicate)
+ )
+ assert.spy(predicate).was.called(4)
+ end)
+
+ it("determines whether any item in the list fulfills predicate", function()
+ local predicate = spy.new(function(item)
+ return item == "On Earth"
+ end)
+
+ assert.is_true(Data.list_any({
+ "Where",
+ "On Earth",
+ "Is",
+ "Waldo",
+ "?",
+ }, predicate))
+
+ assert.spy(predicate).was.called(2)
+ end)
+
+ it("memoizes functions with default cache mechanism", function()
+ local expensive_function = spy.new(function(s)
+ return s
+ end)
+ local memoized_fn = Data.memoize(expensive_function)
+ assert.equal("key", memoized_fn "key")
+ assert.equal("key", memoized_fn "key")
+ assert.equal("new_key", memoized_fn "new_key")
+ assert.spy(expensive_function).was_called(2)
+ end)
+
+ it("memoizes function with custom cache mechanism", function()
+ local expensive_function = spy.new(function(arg1, arg2)
+ return arg1 .. arg2
+ end)
+ local memoized_fn = Data.memoize(expensive_function, function(arg1, arg2)
+ return arg1 .. arg2
+ end)
+ assert.equal("key1key2", memoized_fn("key1", "key2"))
+ assert.equal("key1key2", memoized_fn("key1", "key2"))
+ assert.equal("key1key3", memoized_fn("key1", "key3"))
+ assert.spy(expensive_function).was_called(2)
+ end)
+end)
diff --git a/tests/dispatcher_spec.lua b/tests/dispatcher_spec.lua
new file mode 100644
index 00000000..da2148bc
--- /dev/null
+++ b/tests/dispatcher_spec.lua
@@ -0,0 +1,24 @@
+local dispatcher = require "nvim-lsp-installer.dispatcher"
+local spy = require "luassert.spy"
+
+describe("dispatcher", function()
+ it("calls registered callbacks", function()
+ local server = {}
+ local callback = spy.new()
+ dispatcher.register_server_ready_callback(callback)
+ dispatcher.dispatch_server_ready(server)
+
+ assert.spy(callback).was_called(1)
+ assert.spy(callback).was_called_with(server)
+ end)
+
+ it("deregisters callbacks", function()
+ local server = {}
+ local callback = spy.new()
+ local deregister = dispatcher.register_server_ready_callback(callback)
+ deregister()
+ dispatcher.dispatch_server_ready(server)
+
+ assert.spy(callback).was_not_called()
+ end)
+end)
diff --git a/tests/fs_spec.lua b/tests/fs_spec.lua
new file mode 100644
index 00000000..e227b9da
--- /dev/null
+++ b/tests/fs_spec.lua
@@ -0,0 +1,18 @@
+local fs = require "nvim-lsp-installer.fs"
+local lsp_installer = require "nvim-lsp-installer"
+
+describe("fs", function()
+ before_each(function()
+ lsp_installer.settings {
+ install_root_dir = "/foo",
+ }
+ end)
+
+ it("refuses to rmrf unsafe paths", function()
+ local e = assert.has.errors(function()
+ fs.rmrf "/thisisa/path"
+ end)
+
+ assert.equal("Refusing to operate on path (/thisisa/path) outside of the servers root dir (/foo).", e)
+ end)
+end)
diff --git a/tests/luassertx/lua/luassertx.lua b/tests/luassertx/lua/luassertx.lua
new file mode 100644
index 00000000..33fa9957
--- /dev/null
+++ b/tests/luassertx/lua/luassertx.lua
@@ -0,0 +1,27 @@
+local a = require "plenary.async"
+local assert = require "luassert"
+
+local function wait_for(_, arguments)
+ ---@type fun() @Function to execute until it does not error.
+ local assertions_fn = arguments[1]
+ ---@type number @Timeout in milliseconds. Defaults to 5000.
+ local timeout = arguments[2]
+ timeout = timeout or 15000
+
+ local start = vim.loop.hrtime()
+ local is_ok, err
+ repeat
+ is_ok, err = pcall(assertions_fn)
+ if not is_ok then
+ a.util.sleep(math.min(timeout, 100))
+ end
+ until is_ok or ((vim.loop.hrtime() - start) / 1e6) > timeout
+
+ if not is_ok then
+ error(err)
+ end
+
+ return is_ok
+end
+
+assert:register("assertion", "wait_for", wait_for)
diff --git a/tests/minimal_init.vim b/tests/minimal_init.vim
new file mode 100644
index 00000000..d0fe4e41
--- /dev/null
+++ b/tests/minimal_init.vim
@@ -0,0 +1,30 @@
+" Avoid neovim/neovim#11362
+set display=lastline
+set directory=""
+set noswapfile
+
+let $lsp_installer = getcwd()
+let $luassertx_rtp = getcwd() .. "/tests/luassertx"
+let $dependencies = getcwd() .. "/dependencies"
+
+set rtp+=$lsp_installer,$luassertx_rtp
+set packpath=$dependencies
+
+packloadall
+
+" Luassert extensions
+lua require("luassertx")
+
+lua <<EOF
+require("nvim-lsp-installer").settings {
+ install_root_dir = os.getenv("INSTALL_ROOT_DIR"),
+}
+EOF
+
+function! RunTests() abort
+ lua <<EOF
+ require("plenary.test_harness").test_directory(os.getenv("FILE") or "./tests", {
+ minimal_init = vim.fn.getcwd() .. "/tests/minimal_init.vim",
+ })
+EOF
+endfunction
diff --git a/tests/path_spec.lua b/tests/path_spec.lua
new file mode 100644
index 00000000..3ccaf3ad
--- /dev/null
+++ b/tests/path_spec.lua
@@ -0,0 +1,23 @@
+local path = require "nvim-lsp-installer.path"
+
+describe("path", function()
+ it("concatenates paths", function()
+ assert.equal("foo/bar/baz/~", path.concat { "foo", "bar", "baz", "~" })
+ end)
+
+ it("concatenates paths on Windows", function()
+ local old_os = jit.os
+ jit.os = "windows"
+ package.loaded["nvim-lsp-installer.path"] = nil
+ local path = require "nvim-lsp-installer.path"
+ assert.equal([[foo\bar\baz\~]], path.concat { "foo", "bar", "baz", "~" })
+ jit.os = old_os
+ end)
+
+ it("identifies subdirectories", function()
+ assert.is_true(path.is_subdirectory("/foo/bar", "/foo/bar/baz"))
+ assert.is_true(path.is_subdirectory("/foo/bar", "/foo/bar"))
+ assert.is_false(path.is_subdirectory("/foo/bar", "/foo/bas/baz"))
+ assert.is_false(path.is_subdirectory("/foo/bar", "/foo/bars/baz"))
+ end)
+end)
diff --git a/tests/server_spec.lua b/tests/server_spec.lua
new file mode 100644
index 00000000..0695710e
--- /dev/null
+++ b/tests/server_spec.lua
@@ -0,0 +1,56 @@
+local lsp_installer = require "nvim-lsp-installer"
+local server = require "nvim-lsp-installer.server"
+local spy = require "luassert.spy"
+local a = require "plenary.async"
+
+describe("server", function()
+ a.tests.it("calls registered on_ready handlers upon successful installation", function()
+ local on_ready_handler = spy.new()
+ local generic_handler = spy.new()
+
+ lsp_installer.on_server_ready(generic_handler)
+
+ local srv = server.Server:new {
+ name = "on_ready_fixture",
+ root_dir = server.get_server_root_path "on_ready_fixture",
+ installer = function(_, callback)
+ callback(true)
+ end,
+ default_options = {
+ cmd = { "my-server" },
+ },
+ }
+ srv:on_ready(on_ready_handler)
+ srv:install()
+ assert.wait_for(function()
+ assert.spy(on_ready_handler).was_called(1)
+ assert.spy(generic_handler).was_called(1)
+ assert.spy(generic_handler).was_called_with(srv)
+ end)
+ assert.is_true(srv:is_installed())
+ end)
+
+ a.tests.it("doesn't call on_ready handler when server fails installation", function()
+ local on_ready_handler = spy.new()
+ local generic_handler = spy.new()
+
+ lsp_installer.on_server_ready(generic_handler)
+
+ local srv = server.Server:new {
+ name = "on_ready_fixture_failing",
+ root_dir = server.get_server_root_path "on_ready_fixture_failing",
+ installer = function(_, callback)
+ callback(false)
+ end,
+ default_options = {
+ cmd = { "my-server" },
+ },
+ }
+ srv:on_ready(on_ready_handler)
+ srv:install()
+ a.util.sleep(500)
+ assert.spy(on_ready_handler).was_not_called()
+ assert.spy(generic_handler).was_not_called()
+ assert.is_false(srv:is_installed())
+ end)
+end)
diff --git a/tests/ui_spec.lua b/tests/ui_spec.lua
new file mode 100644
index 00000000..df771a4d
--- /dev/null
+++ b/tests/ui_spec.lua
@@ -0,0 +1,249 @@
+local display = require "nvim-lsp-installer.ui.display"
+local match = require "luassert.match"
+local spy = require "luassert.spy"
+local Ui = require "nvim-lsp-installer.ui"
+local a = require "plenary.async"
+
+describe("ui", function()
+ it("produces a correct tree", function()
+ local function renderer(state)
+ return Ui.CascadingStyleNode({ "INDENT" }, {
+ Ui.When(not state.is_active, function()
+ return Ui.Text {
+ "I'm not active",
+ "Another line",
+ }
+ end),
+ Ui.When(state.is_active, function()
+ return Ui.Text {
+ "I'm active",
+ "Yet another line",
+ }
+ end),
+ })
+ end
+
+ assert.equal(
+ vim.inspect {
+ children = {
+ {
+ type = "HL_TEXT",
+ lines = {
+ { { "I'm not active", "" } },
+ { { "Another line", "" } },
+ },
+ },
+ {
+ type = "NODE",
+ children = {},
+ },
+ },
+ styles = { "INDENT" },
+ type = "CASCADING_STYLE",
+ },
+ vim.inspect(renderer { is_active = false })
+ )
+
+ assert.equal(
+ vim.inspect {
+ children = {
+ {
+ type = "NODE",
+ children = {},
+ },
+ {
+ type = "HL_TEXT",
+ lines = {
+ { { "I'm active", "" } },
+ { { "Yet another line", "" } },
+ },
+ },
+ },
+ styles = { "INDENT" },
+ type = "CASCADING_STYLE",
+ },
+ vim.inspect(renderer { is_active = true })
+ )
+ end)
+
+ it("renders a tree correctly", function()
+ local render_output = display._render_node(
+ {
+ win_width = 120,
+ },
+ Ui.CascadingStyleNode({ "INDENT" }, {
+ Ui.Keybind("i", "INSTALL_SERVER", { "sumneko_lua" }, true),
+ Ui.HlTextNode {
+ {
+ { "Hello World!", "MyHighlightGroup" },
+ },
+ {
+ { "Another Line", "Comment" },
+ },
+ },
+ Ui.HlTextNode {
+ {
+ { "Install something idk", "Stuff" },
+ },
+ },
+ Ui.Keybind("<CR>", "INSTALL_SERVER", { "tsserver" }, false),
+ Ui.Text { "I'm a text node" },
+ })
+ )
+
+ assert.equal(
+ vim.inspect {
+ highlights = {
+ {
+ col_start = 2,
+ col_end = 14,
+ line = 0,
+ hl_group = "MyHighlightGroup",
+ },
+ {
+ col_start = 2,
+ col_end = 14,
+ line = 1,
+ hl_group = "Comment",
+ },
+ {
+ col_start = 2,
+ col_end = 23,
+ line = 2,
+ hl_group = "Stuff",
+ },
+ },
+ lines = { " Hello World!", " Another Line", " Install something idk", " I'm a text node" },
+ virt_texts = {},
+ keybinds = {
+ {
+ effect = "INSTALL_SERVER",
+ key = "i",
+ line = -1,
+ payload = { "sumneko_lua" },
+ },
+ {
+ effect = "INSTALL_SERVER",
+ key = "<CR>",
+ line = 3,
+ payload = { "tsserver" },
+ },
+ },
+ },
+ vim.inspect(render_output)
+ )
+ end)
+end)
+
+describe("integration test", function()
+ a.tests.it("calls vim APIs as expected during rendering", function()
+ local window = display.new_view_only_win "test"
+
+ window.view(function(state)
+ return Ui.Node {
+ Ui.Keybind("U", "EFFECT", nil, true),
+ Ui.Text {
+ "Line number 1!",
+ state.text,
+ },
+ Ui.Keybind("R", "R_EFFECT", { state.text }),
+ Ui.HlTextNode {
+ {
+ { "My highlighted text", "MyHighlightGroup" },
+ },
+ },
+ }
+ end)
+
+ local mutate_state = window.init { text = "Initial state" }
+
+ window.open {
+ effects = {
+ ["EFFECT"] = function() end,
+ ["R_EFFECT"] = function() end,
+ },
+ highlight_groups = {
+ "hi def MyHighlight gui=bold",
+ },
+ }
+
+ local clear_namespace = spy.on(vim.api, "nvim_buf_clear_namespace")
+ local buf_set_option = spy.on(vim.api, "nvim_buf_set_option")
+ local win_set_option = spy.on(vim.api, "nvim_win_set_option")
+ local set_lines = spy.on(vim.api, "nvim_buf_set_lines")
+ local set_extmark = spy.on(vim.api, "nvim_buf_set_extmark")
+ local add_highlight = spy.on(vim.api, "nvim_buf_add_highlight")
+ local set_keymap = spy.on(vim.api, "nvim_buf_set_keymap")
+
+ -- Initial window and buffer creation + initial render
+ a.util.scheduler()
+
+ assert.spy(win_set_option).was_called(8)
+ assert.spy(win_set_option).was_called_with(match.is_number(), "number", false)
+ assert.spy(win_set_option).was_called_with(match.is_number(), "relativenumber", false)
+ assert.spy(win_set_option).was_called_with(match.is_number(), "wrap", false)
+ assert.spy(win_set_option).was_called_with(match.is_number(), "spell", false)
+ assert.spy(win_set_option).was_called_with(match.is_number(), "foldenable", false)
+ assert.spy(win_set_option).was_called_with(match.is_number(), "signcolumn", "no")
+ assert.spy(win_set_option).was_called_with(match.is_number(), "colorcolumn", "")
+ assert.spy(win_set_option).was_called_with(match.is_number(), "cursorline", true)
+
+ assert.spy(buf_set_option).was_called(9)
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "modifiable", false)
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "swapfile", false)
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "textwidth", 0)
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "buftype", "nofile")
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "bufhidden", "wipe")
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "buflisted", false)
+ assert.spy(buf_set_option).was_called_with(match.is_number(), "filetype", "lsp-installer")
+
+ assert.spy(set_lines).was_called(1)
+ assert.spy(set_lines).was_called_with(
+ match.is_number(),
+ 0,
+ -1,
+ false,
+ { "Line number 1!", "Initial state", "My highlighted text" }
+ )
+
+ assert.spy(set_extmark).was_called(0)
+
+ assert.spy(add_highlight).was_called(1)
+ assert.spy(add_highlight).was_called_with(match.is_number(), match.is_number(), "MyHighlightGroup", 2, 0, 19)
+
+ assert.spy(set_keymap).was_called(2)
+ assert.spy(set_keymap).was_called_with(
+ match.is_number(),
+ "n",
+ "U",
+ match.has_match [[<cmd>lua require%('nvim%-lsp%-installer%.ui%.display'%)%.dispatch_effect%(%d, "55"%)<cr>]],
+ { nowait = true, silent = true, noremap = true }
+ )
+ assert.spy(set_keymap).was_called_with(
+ match.is_number(),
+ "n",
+ "R",
+ match.has_match [[<cmd>lua require%('nvim%-lsp%-installer%.ui%.display'%)%.dispatch_effect%(%d, "52"%)<cr>]],
+ { nowait = true, silent = true, noremap = true }
+ )
+
+ assert.spy(clear_namespace).was_called(1)
+ assert.spy(clear_namespace).was_called_with(match.is_number(), match.is_number(), 0, -1)
+
+ mutate_state(function(state)
+ state.text = "New state"
+ end)
+
+ assert.spy(set_lines).was_called(1)
+ a.util.scheduler()
+ assert.spy(set_lines).was_called(2)
+
+ assert.spy(set_lines).was_called_with(
+ match.is_number(),
+ 0,
+ -1,
+ false,
+ { "Line number 1!", "New state", "My highlighted text" }
+ )
+ end)
+end)