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 assertions = dofile(root .. "/tests/assertions.lua") local same = assertions.same local truthy = assertions.truthy 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" }, "(CleverFContract)", "ContractNeutral", { silent = true, remap = false, preserve_count = true } ) truthy(mapping ~= nil) local mapping_info = vim.fn.maparg("(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() ))