summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/run.lua273
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))