diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/run.lua | 273 |
1 files changed, 272 insertions, 1 deletions
diff --git a/tests/run.lua b/tests/run.lua index 6a42d00..f984123 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -8,6 +8,7 @@ package.path = table.concat({ local domain = require("clever_f.domain") local capabilities = require("clever_f.capabilities") +local policy = require("clever_f.policy") local MemoryHost = require("clever_f.testing.memory_host") local tests = {} @@ -561,6 +562,276 @@ test("MemoryHost manages timers, events, mappings, and dot repeat", function() same(2, count.value) end) +test("Policy schema contains every default and color target", function() + local defaults = policy.defaults() + local false_settings = { + "search_current_line_only", + "ignore_case", + "smart_case", + "use_migemo", + "fix_key_direction", + "show_prompt", + "mark_direct", + } + local true_settings = { + "mark_cursor", + "hide_cursor_on_cmdline", + "mark_char", + "clean_labels_eagerly", + } + + for _, name in ipairs(false_settings) do + same(false, defaults[name], name) + end + for _, name in ipairs(true_settings) do + same(true, defaults[name], name) + end + same("", defaults.chars_match_any_signs) + same(0, defaults.repeat_timeout_ms) + same(0, defaults.highlight_timeout_ms) + list_same({ "\r" }, defaults.repeat_last_char_inputs) + same(nil, policy.default("mark_cursor_color")) + same(nil, policy.default("mark_char_color")) + same(nil, policy.default("mark_direct_color")) + + local schema = policy.schema() + same("Cursor", schema.mark_cursor_color.default_target) + same("CleverFDefaultLabel", schema.mark_char_color.default_target) + same("CleverFDefaultLabel", schema.mark_direct_color.default_target) + same(policy.ValueType.OPTIONAL_GROUP_NAME, schema.mark_cursor_color.value_type) + same(policy.ValueType.PRESENCE, + schema[policy.DEFAULT_MAP_SUPPRESSION_SENTINEL].value_type) + + defaults.repeat_last_char_inputs[1] = "changed" + schema.repeat_last_char_inputs.default[1] = "changed" + list_same({ "\r" }, policy.default("repeat_last_char_inputs")) +end) + +test("Policy typed accessors validate semantic values", function() + local host = MemoryHost.new({ + configuration = { + search_current_line_only = true, + chars_match_any_signs = ";:", + repeat_last_char_inputs = { "x", "" }, + mark_cursor_color = "IncSearch", + repeat_timeout_ms = 25, + }, + }) + local service = policy.new(host) + + truthy(service:get_boolean("search_current_line_only")) + same(";:", service:get_string("chars_match_any_signs")) + list_same({ "x", "" }, service:get_string_list("repeat_last_char_inputs")) + same("IncSearch", service:get_optional_group_name("mark_cursor_color")) + same(25, service:get_nonnegative_integer("repeat_timeout_ms")) + same(nil, service:get_optional_group_name("mark_char_color")) + + local inputs = service:get_string_list("repeat_last_char_inputs") + inputs[1] = "changed" + same("x", service:get_string_list("repeat_last_char_inputs")[1]) + + host:set_configuration("ignore_case", 1) + fails(function() + service:get_boolean("ignore_case") + end, "must be a Boolean") + host:set_configuration("chars_match_any_signs", {}) + fails(function() + service:get_string("chars_match_any_signs") + end, "must be a string") + host:set_configuration("repeat_last_char_inputs", { "x", 2 }) + fails(function() + service:get_string_list("repeat_last_char_inputs") + end, "list of strings") + host:set_configuration("mark_cursor_color", "") + fails(function() + service:get_optional_group_name("mark_cursor_color") + end, "optional group name") + host:set_configuration("repeat_timeout_ms", -1) + fails(function() + service:get_nonnegative_integer("repeat_timeout_ms") + end, "nonnegative integer") + host:set_configuration("repeat_timeout_ms", 1.5) + fails(function() + service:get_nonnegative_integer("repeat_timeout_ms") + end, "nonnegative integer") + fails(function() + service:get_string("ignore_case") + end, "does not have type string") + fails(function() + service:get("unknown") + end, "unknown policy setting") +end) + +test("Default-map suppression is presence-based and activation values are retained", function() + local absent_host = MemoryHost.new() + local absent_policy = policy.new(absent_host) + falsy(absent_policy:default_maps_suppressed()) + truthy(absent_policy:capture_activation().install_default_mappings) + + for _, sentinel_value in ipairs({ false, 0 }) do + local configuration = { + clean_labels_eagerly = false, + } + configuration[policy.DEFAULT_MAP_SUPPRESSION_SENTINEL] = sentinel_value + local host = MemoryHost.new({ configuration = configuration }) + local service = policy.new(host) + + host:clear_operations() + truthy(service:default_maps_suppressed()) + local operations = host:operations() + same(1, #operations) + same("configuration_present", operations[1].operation) + + local activation = service:capture_activation() + falsy(activation.install_default_mappings) + falsy(activation.clean_labels_eagerly) + + host:unset_configuration(policy.DEFAULT_MAP_SUPPRESSION_SENTINEL) + host:set_configuration("clean_labels_eagerly", true) + local retained = service:capture_activation() + falsy(retained.install_default_mappings) + falsy(retained.clean_labels_eagerly) + + local next_activation = policy.new(host):capture_activation() + truthy(next_activation.install_default_mappings) + truthy(next_activation.clean_labels_eagerly) + end +end) + +test("Runtime policy samples read current behavior values", function() + local host = MemoryHost.new() + local service = policy.new(host) + local target = domain.TargetValue.character("a", 97) + + same(domain.SearchScope.BUFFER, service:sample_search().search_scope) + same(domain.CaseMode.SENSITIVE, service:sample_match(target).case_mode) + falsy(service:sample_direction().fix_key_direction) + falsy(service:sample_acquisition().show_prompt) + truthy(service:sample_markers().mark_char) + same(0, service:sample_timeouts().repeat_timeout_ms) + list_same({ "\r" }, service:sample_previous_input().repeat_last_char_inputs) + + host:set_configuration("search_current_line_only", true) + host:set_configuration("ignore_case", true) + host:set_configuration("smart_case", true) + host:set_configuration("use_migemo", true) + host:set_configuration("chars_match_any_signs", ";") + host:set_configuration("fix_key_direction", true) + host:set_configuration("show_prompt", true) + host:set_configuration("mark_cursor", false) + host:set_configuration("hide_cursor_on_cmdline", false) + host:set_configuration("mark_char", false) + host:set_configuration("mark_direct", true) + host:set_configuration("repeat_timeout_ms", 75) + host:set_configuration("highlight_timeout_ms", 125) + host:set_configuration("repeat_last_char_inputs", { "x", "yz" }) + + local search = service:sample_search() + truthy(search.search_current_line_only) + same(domain.SearchScope.CURRENT_LINE, search.search_scope) + + local match = service:sample_match(target) + truthy(match.ignore_case) + truthy(match.smart_case) + truthy(match.use_migemo) + same(";", match.chars_match_any_signs) + same(domain.CaseMode.INSENSITIVE, match.case_mode) + truthy(service:sample_direction().fix_key_direction) + + local acquisition = service:sample_acquisition() + truthy(acquisition.show_prompt) + falsy(acquisition.mark_cursor) + falsy(acquisition.hide_cursor_on_cmdline) + truthy(acquisition.mark_direct) + + local markers = service:sample_markers() + falsy(markers.mark_cursor) + falsy(markers.mark_char) + truthy(markers.mark_direct) + + local timeouts = service:sample_timeouts() + same(75, timeouts.repeat_timeout_ms) + same(125, timeouts.highlight_timeout_ms) + list_same({ "x", "yz" }, service:sample_previous_input().repeat_last_char_inputs) +end) + +test("Highlight policy is reevaluated with live feature and color values", function() + local host = MemoryHost.new() + local service = policy.new(host) + service:capture_activation() + + local initial = service:evaluate_highlight_links() + truthy(initial.CleverFCursor.enabled) + same(nil, initial.CleverFCursor.configured_target) + same("Cursor", initial.CleverFCursor.target) + truthy(initial.CleverFChar.enabled) + same("CleverFDefaultLabel", initial.CleverFChar.target) + falsy(initial.CleverFDirect.enabled) + same("CleverFDefaultLabel", initial.CleverFDirect.target) + + host:set_configuration("mark_cursor", false) + host:set_configuration("mark_cursor_color", "Search") + host:set_configuration("mark_char", false) + host:set_configuration("mark_char_color", "ErrorMsg") + host:set_configuration("mark_direct", true) + host:set_configuration("mark_direct_color", "IncSearch") + + local refreshed = service:evaluate_highlight_links() + falsy(refreshed.CleverFCursor.enabled) + same("Search", refreshed.CleverFCursor.target) + falsy(refreshed.CleverFChar.enabled) + same("ErrorMsg", refreshed.CleverFChar.target) + truthy(refreshed.CleverFDirect.enabled) + same("IncSearch", refreshed.CleverFDirect.target) +end) + +test("Case policy resolves an explicit mode for each target", function() + local host = MemoryHost.new() + local service = policy.new(host) + local lower = domain.TargetValue.character("a", 97) + local upper = domain.TargetValue.character("A", 65) + local multibyte = domain.TargetValue.character("\227\129\130", 0x3042) + + same(domain.CaseMode.SENSITIVE, service:case_mode(lower)) + host:set_configuration("smart_case", true) + same(domain.CaseMode.INSENSITIVE, service:case_mode(lower)) + same(domain.CaseMode.SENSITIVE, service:case_mode(upper)) + same(domain.CaseMode.SENSITIVE, service:case_mode(multibyte)) + host:set_configuration("ignore_case", true) + same(domain.CaseMode.INSENSITIVE, service:case_mode(upper)) + + local match = service:sample_match(upper) + local plan = domain.TargetPlan.new({ + target = upper, + kind = domain.TargetPlanKind.LITERAL, + case_mode = match.case_mode, + matcher = function() + return true + end, + }) + same(domain.CaseMode.INSENSITIVE, plan.case_mode) +end) + +test("Unsupported Migemo policy mutation updates live configuration", function() + local host = MemoryHost.new({ + configuration = { use_migemo = true }, + }) + local service = policy.new(host) + truthy(service:get_boolean("use_migemo")) + + host:clear_operations() + service:disable_migemo_for_unsupported_encoding() + local operations = host:operations() + same(1, #operations) + same("write_configuration", operations[1].operation) + same("use_migemo", operations[1].name) + same(false, operations[1].value) + falsy(service:get_boolean("use_migemo")) + + host:set_configuration("use_migemo", true) + truthy(service:get_boolean("use_migemo")) +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then @@ -570,4 +841,4 @@ for _, item in ipairs(tests) do passed = passed + 1 end -io.stdout:write(string.format("Phase 2: %d tests passed\n", passed)) +io.stdout:write(string.format("Phase 3: %d tests passed\n", passed)) |
