summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--tests/profile.lua132
2 files changed, 136 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index e10905a..1551f25 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
NVIM ?= nvim
-.PHONY: test
+.PHONY: test profile
test:
NVIM_LOG_FILE=/dev/null $(NVIM) --headless -u NONE -i NONE -l tests/run.lua
@@ -8,3 +8,6 @@ test:
NVIM_LOG_FILE=/dev/null $(NVIM) --headless -u NONE -i NONE -l tests/phase16.lua
NVIM_LOG_FILE=/dev/null $(NVIM) --headless -u NONE -i NONE -l tests/host_adapter_contract.lua
NVIM_LOG_FILE=/dev/null $(NVIM) --headless -u NONE -i NONE -l tests/plugin_smoke.lua
+
+profile:
+ NVIM_LOG_FILE=/dev/null $(NVIM) --headless -u NONE -i NONE -l tests/profile.lua
diff --git a/tests/profile.lua b/tests/profile.lua
new file mode 100644
index 0000000..5546d88
--- /dev/null
+++ b/tests/profile.lua
@@ -0,0 +1,132 @@
+local script = debug.getinfo(1, "S").source:sub(2)
+local root = script:match("^(.*)/tests/profile%.lua$") or "."
+package.path = table.concat({
+ root .. "/lua/?.lua",
+ root .. "/lua/?/init.lua",
+ package.path,
+}, ";")
+
+local destination_engine = require("clever_f.destination_engine")
+local direct_preview_planner = require("clever_f.direct_preview_planner")
+local domain = require("clever_f.domain")
+local migemo_catalog = require("clever_f.migemo_catalog")
+local motion_plan = require("clever_f.motion_plan")
+local sequence_state = require("clever_f.sequence_state")
+local state_transitions = require("clever_f.state_transitions")
+local target_plan = require("clever_f.target_plan")
+local text_topology = require("clever_f.text_topology")
+
+local assertions = dofile(root .. "/tests/assertions.lua")
+local same = assertions.same
+local truthy = assertions.truthy
+
+local clock = vim.uv or vim.loop
+
+local function measure(body)
+ collectgarbage("collect")
+ local started = clock.hrtime()
+ local result = body()
+ return (clock.hrtime() - started) / 1000000, result
+end
+
+local transitions = state_transitions.new()
+transitions:ClearTemporaryOverlays()
+transitions:DiagnosticFullReset()
+
+local candidate_count = 10000
+local candidate_view = text_topology.new({ string.rep("a", candidate_count) }, "utf-8")
+local candidate_evaluations = 0
+local missing_target = domain.TargetPlan.new({
+ target = domain.TargetValue.character("z", string.byte("z")),
+ kind = domain.TargetPlanKind.LITERAL,
+ case_mode = domain.CaseMode.SENSITIVE,
+ matcher = function()
+ candidate_evaluations = candidate_evaluations + 1
+ return false
+ end,
+})
+local candidate_ms, candidate_outcome = measure(function()
+ return destination_engine.calculate(
+ candidate_view,
+ domain.Position.new(1, 1),
+ motion_plan.build(missing_target, "f"),
+ 1,
+ true
+ )
+end)
+same(domain.SearchStatus.BOUNDARY_BEFORE_ANY, candidate_outcome.status)
+same(candidate_count - 1, candidate_evaluations)
+
+local preview_view = text_topology.new({ string.rep("ab", 5000) }, "utf-8")
+local preview_ms, preview_positions = measure(function()
+ return direct_preview_planner.plan(
+ preview_view,
+ domain.Position.new(1, 1),
+ "f",
+ 2,
+ { ignore_case = false, smart_case = false }
+ )
+end)
+same(2, #preview_positions)
+same(domain.Position.new(1, 4), preview_positions[1])
+same(domain.Position.new(1, 5), preview_positions[2])
+
+local catalog = migemo_catalog.new()
+same(0, catalog:load_count("utf-8"))
+local factory = target_plan.new({ migemo_catalog = catalog })
+factory:build(
+ domain.TargetValue.character("a", string.byte("a")),
+ {
+ ignore_case = false,
+ smart_case = false,
+ use_migemo = false,
+ chars_match_any_signs = "",
+ }
+)
+same(0, catalog:load_count("utf-8"))
+
+local load_ms, dictionary = measure(function()
+ return catalog:get("utf-8")
+end)
+same(1, catalog:load_count("utf-8"))
+same(dictionary, catalog:get("utf8"))
+same(1, catalog:load_count("utf-8"))
+
+local assertion = dictionary:predicate("a", domain.CaseMode.SENSITIVE)
+local assertion_count = 500
+local assertion_ms, accepted = measure(function()
+ local count = 0
+ for _ = 1, assertion_count do
+ if assertion("a") then
+ count = count + 1
+ end
+ end
+ return count
+end)
+same(assertion_count, accepted)
+
+for _, encoding in ipairs({ "cp932", "euc-jp" }) do
+ local first = catalog:get(encoding)
+ same(first, catalog:get(encoding))
+ same(1, catalog:load_count(encoding))
+end
+same(3, #sequence_state.get():to_table().migemo_cache)
+
+local cleanup = transitions:PublicReset("window-1")
+same(nil, cleanup.highlight_timer)
+same(0, #sequence_state.get():to_table().migemo_cache)
+local reloaded = catalog:get("utf-8")
+truthy(reloaded ~= dictionary)
+same(2, catalog:load_count("utf-8"))
+
+io.stdout:write(string.format(
+ "Phase 16 profile: candidates=%d %.3fms, direct=%d %.3fms, "
+ .. "migemo-load=%.3fms, migemo-assertions=%d %.3fms\n",
+ candidate_evaluations,
+ candidate_ms,
+ #preview_positions,
+ preview_ms,
+ load_ms,
+ assertion_count,
+ assertion_ms
+))