diff options
Diffstat (limited to 'tests/host_adapter_contract.lua')
| -rw-r--r-- | tests/host_adapter_contract.lua | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/tests/host_adapter_contract.lua b/tests/host_adapter_contract.lua new file mode 100644 index 0000000..ff369d5 --- /dev/null +++ b/tests/host_adapter_contract.lua @@ -0,0 +1,179 @@ +local script = debug.getinfo(1, "S").source:sub(2) +local root = script:match("^(.*)/tests/host_adapter_contract%.lua$") or "." +package.path = table.concat({ + root .. "/lua/?.lua", + root .. "/lua/?/init.lua", + package.path, +}, ";") + +local capabilities = require("clever_f.capabilities") +local composition_root = require("clever_f.composition_root") +local domain = require("clever_f.domain") +local host_adapter = require("clever_f.host_adapter") + +local function same(expected, actual, message) + if expected ~= actual then + error((message or "values differ") + .. ": expected " .. tostring(expected) + .. ", got " .. tostring(actual), 2) + end +end + +local function truthy(value, message) + if not value then + error(message or "value must be true", 2) + end +end + +local exercised = {} +local host = host_adapter.new() +capabilities.assert_implements(host) + +local function call(name, ...) + exercised[name] = true + return host[name](host, ...) +end + +vim.api.nvim_buf_set_lines(0, 0, -1, true, { "ababa" }) +vim.api.nvim_win_set_cursor(0, { 1, 0 }) + +same("ababa", call("read_text"):line(1)) +same(vim.api.nvim_get_current_buf(), call("read_buffer")) +same(vim.api.nvim_get_current_win(), call("read_window")) +same(domain.Position.new(1, 1), call("read_cursor")) +same("n", call("read_mode")) +truthy(not call("read_selection").active) +same(1, call("read_count").value) + +local ignore_case_global = host_adapter.configuration_global("ignore_case") +vim.g[ignore_case_global] = 0 +truthy(call("configuration_present", "ignore_case")) +same(false, call("read_configuration", "ignore_case")) +call("write_configuration", "ignore_case", true) +same(true, call("read_configuration", "ignore_case")) +same("utf-8", call("read_encoding")) +same(vim.fn.tolower("AbC"), call("lowercase", "AbC")) +truthy(not call("read_macro_state").executing) +truthy(domain.FoldState.is(call("read_fold_state"))) +truthy(call("read_time_ms") > 0) + +same("", call("read_pending_operator")) +call("apply_cursor", domain.Position.new(1, 2)) +same(domain.Position.new(1, 2), call("read_cursor")) +call("apply_selection", domain.Position.new(1, 3), domain.SelectionKind.CHARACTER) +same(domain.Position.new(1, 3), call("read_cursor")) +call("set_operator_inclusive", false) + +vim.api.nvim_feedkeys("z", "n", false) +local packet = call("read_input") +same(domain.InputPacketKind.TEXT, packet.kind) +same("z", packet.text) +same(false, call("open_fold", domain.Position.new(1, 3))) +call("show_prompt", "clever-f: ") +call("redraw", "screen") +call("redraw", "full") +same(false, call("redraw", "suppressed")) + +local notifications = {} +vim.notify = function(text, level, options) + notifications[#notifications + 1] = { + text = text, + level = level, + title = options.title, + } +end +call("emit_diagnostic", "info", "adapter contract") +same("adapter contract", notifications[1].text) +same("clever-f", notifications[1].title) + +call("define_highlight_group", "CleverFContract", { + guifg = "red", + guibg = "NONE", + gui = { bold = true }, +}, { force = true }) +truthy(call("read_highlight_group", "CleverFContract") ~= nil) +local highlight = call("create_highlight", { + group = "CleverFContract", + window = call("read_window"), + positions = { domain.Position.new(1, 1), domain.Position.new(1, 3) }, + priority = "high", +}) +truthy(call("remove_highlight", highlight)) + +truthy(call("supports_timers")) +local timer = call("start_timer", 100000, function() end) +truthy(timer ~= nil) +truthy(call("stop_timer", timer)) + +local prior_guicursor = vim.o.guicursor +local prior_terminal_cursor = vim.fn.eval("&t_ve") +local presentation_supported = call("supports_cursor_presentation") +local lease = call("suppress_cursor_presentation") +if presentation_supported then + truthy(lease ~= nil) + truthy(call("restore_cursor_presentation", lease)) + same(prior_guicursor, vim.o.guicursor) + same(prior_terminal_cursor, vim.fn.eval("&t_ve")) +else + same(nil, lease) + same(false, call("restore_cursor_presentation", lease)) +end + +local delivered +local registration = call("register_events", "CursorMoved", function(name, payload) + delivered = { name = name, payload = payload } +end) +local transition = call("begin_action_transition") +call("deliver_event", "CursorMoved", { + buffer = call("read_buffer"), + window = call("read_window"), +}) +same(nil, delivered) +call("commit_action_transition", transition) +same("CursorMoved", delivered.name) +truthy(call("remove_event_registration", registration)) + +local neutral_position = call("read_cursor") +call("register_action", "ContractNeutral", function() + return domain.ActionOutcome.neutral(neutral_position) +end) +local mapping = call( + "register_mapping", + { "n" }, + "<Plug>(CleverFContract)", + "ContractNeutral", + { silent = true, remap = false, preserve_count = true } +) +truthy(mapping ~= nil) +local mapping_info = vim.fn.maparg("<Plug>(CleverFContract)", "n", false, true) +same(1, mapping_info.silent) +same(1, mapping_info.noremap) + +local target = domain.TargetValue.character("a", string.byte("a")) +local payload = domain.DotPayload.new("f", target) +same(payload, call("register_dot_repeat", payload, function() + return domain.ActionOutcome.neutral(neutral_position) +end)) + +for _, method_name in ipairs(capabilities.required_methods()) do + truthy(exercised[method_name], "adapter capability was not exercised: " .. method_name) +end + +local suppression_global = host_adapter.configuration_global( + "suppress_default_mappings" +) +same("clever_f_not_overwrites_standard_mappings", suppression_global) +for _, value in ipairs({ false, 0 }) do + vim.g[suppression_global] = value + local suppressed = composition_root.new({ + host = host_adapter.new(), + }):activate() + same(false, suppressed.setup.install_default_mappings) + same(nil, next(suppressed.mappings)) +end +vim.g[suppression_global] = nil + +io.stdout:write(string.format( + "Phase 15 adapter contract: %d capabilities passed\n", + #capabilities.required_methods() +)) |
