summaryrefslogtreecommitdiff
path: root/lua/99/test
diff options
context:
space:
mode:
authorThePrimeAgain <theprimeagain@theprimeagain.com>2026-01-14 18:32:30 -0700
committerThePrimeAgain <theprimeagain@theprimeagain.com>2026-01-14 18:32:30 -0700
commit6c88a9537ae829cd8a4b92312e115c311e6beb42 (patch)
treed2b1796d453cbbd7374ed740fa50a1be411362b1 /lua/99/test
parent701b4c34a1e3de34327d21cc6f51c79b49d26b51 (diff)
downloada4-6c88a9537ae829cd8a4b92312e115c311e6beb42.tar.xz
a4-6c88a9537ae829cd8a4b92312e115c311e6beb42.zip
fuzzy_find: for agents stuff
Diffstat (limited to 'lua/99/test')
-rw-r--r--lua/99/test/agent.helpers_spec.lua52
-rw-r--r--lua/99/test/fill_in_function.cpp_spec.lua186
-rw-r--r--lua/99/test/fill_in_function_spec.lua148
-rw-r--r--lua/99/test/geo_spec.lua174
-rw-r--r--lua/99/test/implement-fn_spec-DO-NOT-USE-YET.lua62
-rw-r--r--lua/99/test/logger_spec.lua128
-rw-r--r--lua/99/test/marks_spec.lua228
-rw-r--r--lua/99/test/request_status_spec.lua18
-rw-r--r--lua/99/test/test_utils.lua98
-rw-r--r--lua/99/test/visual_spec.lua225
10 files changed, 682 insertions, 637 deletions
diff --git a/lua/99/test/agent.helpers_spec.lua b/lua/99/test/agent.helpers_spec.lua
new file mode 100644
index 0000000..f59870a
--- /dev/null
+++ b/lua/99/test/agent.helpers_spec.lua
@@ -0,0 +1,52 @@
+-- luacheck: globals describe it assert
+local helpers = require("99.agents.helpers")
+local eq = assert.are.same
+
+--- @param selected _99.Agents.FuzzyState.Selected[]
+--- @return string[]
+local function n(selected)
+ return vim.tbl_map(function(item) return item.name end, selected)
+end
+
+local possible = {
+ "react-hooks",
+ "react-state",
+ "redux",
+ "recoil",
+ "rust-analyzer",
+}
+
+describe("99.agents.helpers", function()
+ it("fuzzy matching", function()
+ local state = helpers.create_state(possible, false)
+ eq(5, #state.selected)
+
+ state = helpers.fuzzy_match("rea", state)
+ eq({ "react-hooks", "react-state", }, n(state.selected))
+
+ state = helpers.fuzzy_match("rh", state)
+ eq({ "react-hooks" }, n(state.selected))
+
+ state = helpers.fuzzy_match("rst", state)
+ eq({ "react-state", "rust-analyzer" }, n(state.selected))
+
+ state = helpers.fuzzy_match("xyz", state)
+ eq({}, state.selected)
+ end)
+
+ it("fuzzy matching iterative", function()
+ local state = helpers.create_state(possible, false)
+
+ state = helpers.fuzzy_match("r", state)
+ eq(possible, n(state.selected))
+
+ state = helpers.fuzzy_match("re", state)
+ eq(possible, n(state.selected))
+
+ state = helpers.fuzzy_match("rea", state)
+ eq({ "react-hooks", "react-state", }, n(state.selected))
+
+ state = helpers.fuzzy_match("re", state)
+ eq(possible, n(state.selected))
+ end)
+end)
diff --git a/lua/99/test/fill_in_function.cpp_spec.lua b/lua/99/test/fill_in_function.cpp_spec.lua
index 9edf550..3cb67b5 100644
--- a/lua/99/test/fill_in_function.cpp_spec.lua
+++ b/lua/99/test/fill_in_function.cpp_spec.lua
@@ -12,122 +12,122 @@ local eq = assert.are.same
--- @param lang string?
--- @return _99.test.Provider, number
local function setup(content, row, col, lang)
- assert(lang, "lang must be provided")
- local provider = test_utils.TestProvider.new()
- _99.setup({
- provider = provider,
- logger = {
- error_cache_level = Levels.ERROR,
- type = "print",
- },
- })
+ assert(lang, "lang must be provided")
+ local provider = test_utils.TestProvider.new()
+ _99.setup({
+ provider = provider,
+ logger = {
+ error_cache_level = Levels.ERROR,
+ type = "print",
+ },
+ })
- local buffer = test_utils.create_file(content, lang, row, col)
- return provider, buffer
+ local buffer = test_utils.create_file(content, lang, row, col)
+ return provider, buffer
end
--- @param buffer number
--- @return string[]
local function read(buffer)
- return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
+ return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
end
describe("fill_in_function", function()
- it("fill in cpp function", function()
- local cpp_content = {
- "",
- "uint32_t test() { }",
- }
- local provider, buffer = setup(cpp_content, 2, 5, "cpp")
- local state = _99.__get_state()
+ it("fill in cpp function", function()
+ local cpp_content = {
+ "",
+ "uint32_t test() { }",
+ }
+ local provider, buffer = setup(cpp_content, 2, 5, "cpp")
+ local state = _99.__get_state()
- _99.fill_in_function()
+ _99.fill_in_function()
- eq(1, state:active_request_count())
- eq(cpp_content, read(buffer))
+ eq(1, state:active_request_count())
+ eq(cpp_content, read(buffer))
- provider:resolve("success", "uint32_t test() {\n return 42;\n}")
- test_utils.next_frame()
+ provider:resolve("success", "uint32_t test() {\n return 42;\n}")
+ test_utils.next_frame()
- local expected_state = {
- "",
- "uint32_t test() {",
- " return 42;",
- "}",
- }
- eq(expected_state, read(buffer))
- eq(0, state:active_request_count())
- end)
+ local expected_state = {
+ "",
+ "uint32_t test() {",
+ " return 42;",
+ "}",
+ }
+ eq(expected_state, read(buffer))
+ eq(0, state:active_request_count())
+ end)
- it("fill in cpp concept with requires clause", function()
- local cpp_content = {
- "",
- "template <typename T>",
- "concept Callback = requires(T cb) {",
- " // Invocation must return an int",
- "};",
- }
+ it("fill in cpp concept with requires clause", function()
+ local cpp_content = {
+ "",
+ "template <typename T>",
+ "concept Callback = requires(T cb) {",
+ " // Invocation must return an int",
+ "};",
+ }
- local provider, buffer = setup(cpp_content, 3, 10, "cpp")
- local state = _99.__get_state()
+ local provider, buffer = setup(cpp_content, 3, 10, "cpp")
+ local state = _99.__get_state()
- _99.fill_in_function()
+ _99.fill_in_function()
- eq(1, state:active_request_count())
- eq(cpp_content, read(buffer))
+ eq(1, state:active_request_count())
+ eq(cpp_content, read(buffer))
- provider:resolve(
- "success",
- "concept Callback = requires(T cb) {\n { cb() } -> std::same_as<int>;\n};"
- )
- test_utils.next_frame()
+ provider:resolve(
+ "success",
+ "concept Callback = requires(T cb) {\n { cb() } -> std::same_as<int>;\n};"
+ )
+ test_utils.next_frame()
- local expected_state = {
- "",
- "template <typename T>",
- "concept Callback = requires(T cb) {",
- " { cb() } -> std::same_as<int>;",
- "};",
- }
- eq(expected_state, read(buffer))
- eq(0, state:active_request_count())
- end)
+ local expected_state = {
+ "",
+ "template <typename T>",
+ "concept Callback = requires(T cb) {",
+ " { cb() } -> std::same_as<int>;",
+ "};",
+ }
+ eq(expected_state, read(buffer))
+ eq(0, state:active_request_count())
+ end)
- it("fill in nested lambda inside a function", function()
- local cpp_content = {
- "",
- "auto test() -> void",
- "{",
- " const auto say_42 = []() -> int {",
- " // TODO: return 42",
- " };",
- "}",
- }
+ it("fill in nested lambda inside a function", function()
+ local cpp_content = {
+ "",
+ "auto test() -> void",
+ "{",
+ " const auto say_42 = []() -> int {",
+ " // TODO: return 42",
+ " };",
+ "}",
+ }
- local provider, buffer = setup(cpp_content, 4, 20, "cpp")
- local state = _99.__get_state()
+ local provider, buffer = setup(cpp_content, 4, 20, "cpp")
+ local state = _99.__get_state()
- _99.fill_in_function()
+ _99.fill_in_function()
- eq(1, state:active_request_count())
- eq(cpp_content, read(buffer))
+ eq(1, state:active_request_count())
+ eq(cpp_content, read(buffer))
- provider:resolve(
- "success",
- "const auto say_42 = []() -> int {\n return 42;\n };"
- )
- test_utils.next_frame()
+ provider:resolve(
+ "success",
+ "const auto say_42 = []() -> int {\n return 42;\n };"
+ )
+ test_utils.next_frame()
- local expected_state = {
- "",
- "auto test() -> void",
- "{",
- " const auto say_42 = []() -> int {",
- " return 42;",
- " };",
- "}",
- }
- eq(expected_state, read(buffer))
- eq(0, state:active_request_count())
- end)
+ local expected_state = {
+ "",
+ "auto test() -> void",
+ "{",
+ " const auto say_42 = []() -> int {",
+ " return 42;",
+ " };",
+ "}",
+ }
+ eq(expected_state, read(buffer))
+ eq(0, state:active_request_count())
+ end)
end)
diff --git a/lua/99/test/fill_in_function_spec.lua b/lua/99/test/fill_in_function_spec.lua
index 24cdcfe..cc356f1 100644
--- a/lua/99/test/fill_in_function_spec.lua
+++ b/lua/99/test/fill_in_function_spec.lua
@@ -10,109 +10,109 @@ local Levels = require("99.logger.level")
--- @param lang string?
--- @return _99.test.Provider, number
local function setup(content, row, col, lang)
- lang = lang or "lua"
- local p = test_utils.TestProvider.new()
- _99.setup({
- provider = p,
- logger = {
- error_cache_level = Levels.ERROR,
- type = "print",
- },
- })
+ lang = lang or "lua"
+ local p = test_utils.TestProvider.new()
+ _99.setup({
+ provider = p,
+ logger = {
+ error_cache_level = Levels.ERROR,
+ type = "print",
+ },
+ })
- local buffer = test_utils.create_file(content, lang, row, col)
- return p, buffer
+ local buffer = test_utils.create_file(content, lang, row, col)
+ return p, buffer
end
--- @param buffer number
--- @return string[]
local function r(buffer)
- return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
+ return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
end
local content = {
- "",
- "local foo = function() end",
+ "",
+ "local foo = function() end",
}
describe("fill_in_function", function()
- it("replace function contents", function()
- local p, buffer = setup(content, 2, 12)
- local state = _99.__get_state()
+ it("replace function contents", function()
+ local p, buffer = setup(content, 2, 12)
+ local state = _99.__get_state()
- _99.fill_in_function()
+ _99.fill_in_function()
- eq(1, state:active_request_count())
- eq(content, r(buffer))
+ eq(1, state:active_request_count())
+ eq(content, r(buffer))
- p:resolve("success", "function()\n return 42\nend")
- test_utils.next_frame()
+ p:resolve("success", "function()\n return 42\nend")
+ test_utils.next_frame()
- local expected_state = {
- "",
- "local foo = function()",
- " return 42",
- "end",
- }
- eq(expected_state, r(buffer))
- eq(0, state:active_request_count())
- end)
+ local expected_state = {
+ "",
+ "local foo = function()",
+ " return 42",
+ "end",
+ }
+ eq(expected_state, r(buffer))
+ eq(0, state:active_request_count())
+ end)
- it("should test a typescript file", function()
- local ts_content = {
- "",
- "const foo = function() {}",
- }
- local p, buffer = setup(ts_content, 2, 12, "typescript")
- local state = _99.__get_state()
+ it("should test a typescript file", function()
+ local ts_content = {
+ "",
+ "const foo = function() {}",
+ }
+ local p, buffer = setup(ts_content, 2, 12, "typescript")
+ local state = _99.__get_state()
- _99.fill_in_function()
+ _99.fill_in_function()
- eq(1, state:active_request_count())
- eq(ts_content, r(buffer))
+ eq(1, state:active_request_count())
+ eq(ts_content, r(buffer))
- p:resolve("success", "function() {\n return 42;\n}")
- test_utils.next_frame()
+ p:resolve("success", "function() {\n return 42;\n}")
+ test_utils.next_frame()
- local expected_state = {
- "",
- "const foo = function() {",
- " return 42;",
- "}",
- }
- eq(expected_state, r(buffer))
- eq(0, state:active_request_count())
- end)
+ local expected_state = {
+ "",
+ "const foo = function() {",
+ " return 42;",
+ "}",
+ }
+ eq(expected_state, r(buffer))
+ eq(0, state:active_request_count())
+ end)
- it("should cancel request when stop_all_requests is called", function()
- local p, buffer = setup(content, 2, 12)
- _99.fill_in_function()
+ it("should cancel request when stop_all_requests is called", function()
+ local p, buffer = setup(content, 2, 12)
+ _99.fill_in_function()
- eq(content, r(buffer))
+ eq(content, r(buffer))
- assert.is_false(p.request.request:is_cancelled())
- assert.is_not_nil(p.request)
- assert.is_not_nil(p.request.request)
+ assert.is_false(p.request.request:is_cancelled())
+ assert.is_not_nil(p.request)
+ assert.is_not_nil(p.request.request)
- _99.stop_all_requests()
- test_utils.next_frame()
+ _99.stop_all_requests()
+ test_utils.next_frame()
- assert.is_true(p.request.request:is_cancelled())
+ assert.is_true(p.request.request:is_cancelled())
- p:resolve("success", "function foo()\n return 42\nend")
- test_utils.next_frame()
+ p:resolve("success", "function foo()\n return 42\nend")
+ test_utils.next_frame()
- eq(content, r(buffer))
- end)
+ eq(content, r(buffer))
+ end)
- it("should handle error cases with graceful failures", function()
- local p, buffer = setup(content, 2, 12)
- _99.fill_in_function()
+ it("should handle error cases with graceful failures", function()
+ local p, buffer = setup(content, 2, 12)
+ _99.fill_in_function()
- eq(content, r(buffer))
+ eq(content, r(buffer))
- p:resolve("failed", "Something went wrong")
- test_utils.next_frame()
+ p:resolve("failed", "Something went wrong")
+ test_utils.next_frame()
- eq(content, r(buffer))
- end)
+ eq(content, r(buffer))
+ end)
end)
diff --git a/lua/99/test/geo_spec.lua b/lua/99/test/geo_spec.lua
index c8213a7..9dc107b 100644
--- a/lua/99/test/geo_spec.lua
+++ b/lua/99/test/geo_spec.lua
@@ -6,103 +6,103 @@ local test_utils = require("99.test.test_utils")
local eq = assert.are.same
describe("Range", function()
- local buffer
+ local buffer
- before_each(function()
- buffer = test_utils.create_file({
- "function foo()",
- " local x = 1",
- " return x",
- "end",
- "",
- "function bar()",
- " return 42",
- "end",
- }, "lua", 1, 0)
- end)
+ before_each(function()
+ buffer = test_utils.create_file({
+ "function foo()",
+ " local x = 1",
+ " return x",
+ "end",
+ "",
+ "function bar()",
+ " return 42",
+ "end",
+ }, "lua", 1, 0)
+ end)
- after_each(function()
- test_utils.clean_files()
- end)
+ after_each(function()
+ test_utils.clean_files()
+ end)
- it("replace text", function()
- local start_point = Point:new(2, 3)
- local end_point = Point:new(3, 11)
- local range = Range:new(buffer, start_point, end_point)
- local original_text = range:to_text()
- eq("local x = 1\n return x", original_text)
+ it("replace text", function()
+ local start_point = Point:new(2, 3)
+ local end_point = Point:new(3, 11)
+ local range = Range:new(buffer, start_point, end_point)
+ local original_text = range:to_text()
+ eq("local x = 1\n return x", original_text)
- local replace_text = { "local y = 2" }
- range:replace_text(replace_text)
- local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
- eq({
- "function foo()",
- " local y = 2",
- "end",
- "",
- "function bar()",
- " return 42",
- "end",
- }, lines)
- end)
+ local replace_text = { "local y = 2" }
+ range:replace_text(replace_text)
+ local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
+ eq({
+ "function foo()",
+ " local y = 2",
+ "end",
+ "",
+ "function bar()",
+ " return 42",
+ "end",
+ }, lines)
+ end)
- it("replace text single line into multi-line", function()
- local start_point = Point:new(2, 3)
- local end_point = Point:new(3, 11)
- local range = Range:new(buffer, start_point, end_point)
- local original_text = range:to_text()
- eq("local x = 1\n return x", original_text)
+ it("replace text single line into multi-line", function()
+ local start_point = Point:new(2, 3)
+ local end_point = Point:new(3, 11)
+ local range = Range:new(buffer, start_point, end_point)
+ local original_text = range:to_text()
+ eq("local x = 1\n return x", original_text)
- local replace_text = {
- "local y = 2",
- " local z = 3",
- }
- range:replace_text(replace_text)
- local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
- eq({
- "function foo()",
- " local y = 2",
- " local z = 3",
- "end",
- "",
- "function bar()",
- " return 42",
- "end",
- }, lines)
- end)
+ local replace_text = {
+ "local y = 2",
+ " local z = 3",
+ }
+ range:replace_text(replace_text)
+ local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
+ eq({
+ "function foo()",
+ " local y = 2",
+ " local z = 3",
+ "end",
+ "",
+ "function bar()",
+ " return 42",
+ "end",
+ }, lines)
+ end)
- it(
- "should be able to visual line select an empty line and return out an empty line of text",
- function()
- vim.api.nvim_win_set_cursor(0, { 5, 0 })
- vim.api.nvim_feedkeys("V", "x", false)
+ it(
+ "should be able to visual line select an empty line and return out an empty line of text",
+ function()
+ vim.api.nvim_win_set_cursor(0, { 5, 0 })
+ vim.api.nvim_feedkeys("V", "x", false)
- test_utils.next_frame()
- vim.api.nvim_feedkeys(
- vim.api.nvim_replace_termcodes("<Esc>", true, false, true),
- "x",
- false
- )
+ test_utils.next_frame()
+ vim.api.nvim_feedkeys(
+ vim.api.nvim_replace_termcodes("<Esc>", true, false, true),
+ "x",
+ false
+ )
- local range = Range.from_visual_selection()
- local text = range:to_text()
- eq("", text)
- end
- )
+ local range = Range.from_visual_selection()
+ local text = range:to_text()
+ eq("", text)
+ end
+ )
- it("should create range from simple visual line selection", function()
- vim.api.nvim_win_set_cursor(0, { 2, 0 })
- vim.api.nvim_feedkeys("V", "x", false)
+ it("should create range from simple visual line selection", function()
+ vim.api.nvim_win_set_cursor(0, { 2, 0 })
+ vim.api.nvim_feedkeys("V", "x", false)
- test_utils.next_frame()
- vim.api.nvim_feedkeys(
- vim.api.nvim_replace_termcodes("<Esc>", true, false, true),
- "x",
- false
- )
+ test_utils.next_frame()
+ vim.api.nvim_feedkeys(
+ vim.api.nvim_replace_termcodes("<Esc>", true, false, true),
+ "x",
+ false
+ )
- local range = Range.from_visual_selection()
- local text = range:to_text()
- eq(" local x = 1", text)
- end)
+ local range = Range.from_visual_selection()
+ local text = range:to_text()
+ eq(" local x = 1", text)
+ end)
end)
diff --git a/lua/99/test/implement-fn_spec-DO-NOT-USE-YET.lua b/lua/99/test/implement-fn_spec-DO-NOT-USE-YET.lua
index 317d270..66ee174 100644
--- a/lua/99/test/implement-fn_spec-DO-NOT-USE-YET.lua
+++ b/lua/99/test/implement-fn_spec-DO-NOT-USE-YET.lua
@@ -7,49 +7,49 @@ local test_content = require("99.test.test_content")
--- @param content string[]
--- @return _99.test.Provider, number
local function setup(content)
- local p = test_utils.TestProvider.new()
- _99.setup({
- provider = p,
- })
+ local p = test_utils.TestProvider.new()
+ _99.setup({
+ provider = p,
+ })
- local buffer = test_utils.create_file(content, "lua", 3, 3)
- return p, buffer
+ local buffer = test_utils.create_file(content, "lua", 3, 3)
+ return p, buffer
end
--- @param buffer number
--- @return string[]
local function r(buffer)
- return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
+ return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
end
local content = {
- "function some_other_function() end",
- "function foo()",
- " bar()",
- "end",
- "",
+ "function some_other_function() end",
+ "function foo()",
+ " bar()",
+ "end",
+ "",
}
describe("implement_function", function()
- it("basic call", function()
- local p, buffer = setup(content)
- _99.implement_fn()
- eq(content, r(buffer))
+ it("basic call", function()
+ local p, buffer = setup(content)
+ _99.implement_fn()
+ eq(content, r(buffer))
- p:resolve("success", "function bar()\n return 42\nend")
- test_utils.next_frame()
+ p:resolve("success", "function bar()\n return 42\nend")
+ test_utils.next_frame()
- local expected_state = {
- "function some_other_function() end",
- "function bar()",
- " return 42",
- "end",
- "function foo()",
- " bar()",
- "end",
- "",
- }
- eq(expected_state, r(buffer))
- end)
+ local expected_state = {
+ "function some_other_function() end",
+ "function bar()",
+ " return 42",
+ "end",
+ "function foo()",
+ " bar()",
+ "end",
+ "",
+ }
+ eq(expected_state, r(buffer))
+ end)
- it("should cancel request when stop_all_requests is called", function() end)
+ it("should cancel request when stop_all_requests is called", function() end)
end)
diff --git a/lua/99/test/logger_spec.lua b/lua/99/test/logger_spec.lua
index a602dd5..c7bda84 100644
--- a/lua/99/test/logger_spec.lua
+++ b/lua/99/test/logger_spec.lua
@@ -5,7 +5,7 @@ local eq = assert.are.same
local now = 0
time.now = function()
- return now
+ return now
end
--- @class _99.Test.Logger.RequestLogs
@@ -15,82 +15,82 @@ end
--- @param all_logs string[][]
--- @return _99.Test.Logger.RequestLogs
local function l(all_logs)
- local out = {}
- for _, logs in ipairs(all_logs) do
- local lines = {}
- table.insert(out, lines)
- for _, log_line in ipairs(logs) do
- table.insert(lines, vim.json.decode(log_line))
- end
+ local out = {}
+ for _, logs in ipairs(all_logs) do
+ local lines = {}
+ table.insert(out, lines)
+ for _, log_line in ipairs(logs) do
+ table.insert(lines, vim.json.decode(log_line))
end
- return out
+ end
+ return out
end
describe("Logger", function()
- after_each(function()
- Logger.reset()
- now = 0
- Logger.set_max_cached_requests(2)
- end)
+ after_each(function()
+ Logger.reset()
+ now = 0
+ Logger.set_max_cached_requests(2)
+ end)
- it("no caching of non ID'd logs. Global logs", function()
- eq({}, Logger.logs())
+ it("no caching of non ID'd logs. Global logs", function()
+ eq({}, Logger.logs())
- local ok = pcall(Logger.debug, Logger, "test log")
- eq({}, Logger.logs())
- eq(ok, false)
- end)
+ local ok = pcall(Logger.debug, Logger, "test log")
+ eq({}, Logger.logs())
+ eq(ok, false)
+ end)
- it("cache logs, keep max count", function()
- eq({}, Logger.logs())
- local logger = Logger:set_id(69)
+ it("cache logs, keep max count", function()
+ eq({}, Logger.logs())
+ local logger = Logger:set_id(69)
- logger:debug("test log")
+ logger:debug("test log")
- eq({
- {
- { level = "DEBUG", id = 69, msg = "test log" },
- },
- }, l(Logger.logs()))
+ eq({
+ {
+ { level = "DEBUG", id = 69, msg = "test log" },
+ },
+ }, l(Logger.logs()))
- local logger2 = logger:set_id(420)
- now = 1000
- logger2:error("error log")
+ local logger2 = logger:set_id(420)
+ now = 1000
+ logger2:error("error log")
- eq({
- {
- { level = "ERROR", id = 420, msg = "error log" },
- },
- {
- { level = "DEBUG", id = 69, msg = "test log" },
- },
- }, l(Logger.logs()))
+ eq({
+ {
+ { level = "ERROR", id = 420, msg = "error log" },
+ },
+ {
+ { level = "DEBUG", id = 69, msg = "test log" },
+ },
+ }, l(Logger.logs()))
- now = 1001
- logger:warn("warn log")
+ now = 1001
+ logger:warn("warn log")
- eq({
- {
- { level = "DEBUG", id = 69, msg = "test log" },
- { level = "WARN", id = 69, msg = "warn log" },
- },
- {
- { level = "ERROR", id = 420, msg = "error log" },
- },
- }, l(Logger.logs()))
+ eq({
+ {
+ { level = "DEBUG", id = 69, msg = "test log" },
+ { level = "WARN", id = 69, msg = "warn log" },
+ },
+ {
+ { level = "ERROR", id = 420, msg = "error log" },
+ },
+ }, l(Logger.logs()))
- local logger3 = logger:set_id(1337)
- now = 1002
- logger3:info("info log")
+ local logger3 = logger:set_id(1337)
+ now = 1002
+ logger3:info("info log")
- eq({
- {
- { level = "INFO", id = 1337, msg = "info log" },
- },
- {
- { level = "DEBUG", id = 69, msg = "test log" },
- { level = "WARN", id = 69, msg = "warn log" },
- },
- }, l(Logger.logs()))
- end)
+ eq({
+ {
+ { level = "INFO", id = 1337, msg = "info log" },
+ },
+ {
+ { level = "DEBUG", id = 69, msg = "test log" },
+ { level = "WARN", id = 69, msg = "warn log" },
+ },
+ }, l(Logger.logs()))
+ end)
end)
diff --git a/lua/99/test/marks_spec.lua b/lua/99/test/marks_spec.lua
index 3c28248..0b810f0 100644
--- a/lua/99/test/marks_spec.lua
+++ b/lua/99/test/marks_spec.lua
@@ -7,147 +7,143 @@ local test_utils = require("99.test.test_utils")
local eq = assert.are.same
describe("Mark", function()
- local buffer
+ local buffer
- before_each(function()
- buffer = test_utils.create_file({
- "function foo()",
- " local x = 1",
- " return x",
- "end",
- "",
- "function bar()",
- " return 42",
- "end",
- }, "lua", 1, 0)
- end)
+ before_each(function()
+ buffer = test_utils.create_file({
+ "function foo()",
+ " local x = 1",
+ " return x",
+ "end",
+ "",
+ "function bar()",
+ " return 42",
+ "end",
+ }, "lua", 1, 0)
+ end)
- after_each(function()
- test_utils.clean_files()
- end)
+ after_each(function()
+ test_utils.clean_files()
+ end)
- it("should create a mark at a specific point", function()
- local point = Point:new(2, 3)
- local mark = Mark.mark_point(buffer, point)
- local mark_point = Point.from_mark(mark)
+ it("should create a mark at a specific point", function()
+ local point = Point:new(2, 3)
+ local mark = Mark.mark_point(buffer, point)
+ local mark_point = Point.from_mark(mark)
- eq(point, mark_point)
+ eq(point, mark_point)
- mark:delete()
- end)
+ mark:delete()
+ end)
- it("marks range", function()
- local start_point = Point:new(2, 3)
- local end_point = Point:new(3, 10)
- local range = Range:new(buffer, start_point, end_point)
- local mark_start, mark_end = Mark.mark_range(range)
- local actual_start = Point.from_mark(mark_start)
- local actual_end = Point.from_mark(mark_end)
+ it("marks range", function()
+ local start_point = Point:new(2, 3)
+ local end_point = Point:new(3, 10)
+ local range = Range:new(buffer, start_point, end_point)
+ local mark_start, mark_end = Mark.mark_range(range)
+ local actual_start = Point.from_mark(mark_start)
+ local actual_end = Point.from_mark(mark_end)
- eq(start_point, actual_start)
- eq(end_point, actual_end)
+ eq(start_point, actual_start)
+ eq(end_point, actual_end)
- mark_start:delete()
- mark_end:delete()
- end)
+ mark_start:delete()
+ mark_end:delete()
+ end)
- it("should handle single-line ranges", function()
- local start_point = Point:new(2, 3)
- local end_point = Point:new(2, 10)
- local range = Range:new(buffer, start_point, end_point)
- local mark_start, mark_end = Mark.mark_range(range)
- local actual_start = Point.from_mark(mark_start)
- local actual_end = Point.from_mark(mark_end)
+ it("should handle single-line ranges", function()
+ local start_point = Point:new(2, 3)
+ local end_point = Point:new(2, 10)
+ local range = Range:new(buffer, start_point, end_point)
+ local mark_start, mark_end = Mark.mark_range(range)
+ local actual_start = Point.from_mark(mark_start)
+ local actual_end = Point.from_mark(mark_end)
- eq(start_point, actual_start)
- eq(end_point, actual_end)
+ eq(start_point, actual_start)
+ eq(end_point, actual_end)
- mark_start:delete()
- mark_end:delete()
- end)
+ mark_start:delete()
+ mark_end:delete()
+ end)
- it("should create mark one line above the range start", function()
- local above_point = Point:new(2, 14)
- local start_point = Point:new(3, 5)
- local end_point = Point:new(4, 3)
- local range = Range:new(buffer, start_point, end_point)
- local mark = Mark.mark_above_range(range)
- local mark_point = Point.from_mark(mark)
+ it("should create mark one line above the range start", function()
+ local above_point = Point:new(2, 14)
+ local start_point = Point:new(3, 5)
+ local end_point = Point:new(4, 3)
+ local range = Range:new(buffer, start_point, end_point)
+ local mark = Mark.mark_above_range(range)
+ local mark_point = Point.from_mark(mark)
- eq(above_point, mark_point)
+ eq(above_point, mark_point)
- mark:delete()
- end)
+ mark:delete()
+ end)
- it("should create mark at beginning when range starts at line 1", function()
- local start_point = Point:new(1, 5)
- local end_point = Point:new(2, 3)
- local range = Range:new(buffer, start_point, end_point)
- local mark = Mark.mark_above_range(range)
- local mark_point = Point.from_mark(mark)
+ it("should create mark at beginning when range starts at line 1", function()
+ local start_point = Point:new(1, 5)
+ local end_point = Point:new(2, 3)
+ local range = Range:new(buffer, start_point, end_point)
+ local mark = Mark.mark_above_range(range)
+ local mark_point = Point.from_mark(mark)
- local beginning_point = Point:new(1, 1)
- eq(beginning_point, mark_point)
- mark:delete()
- end)
+ local beginning_point = Point:new(1, 1)
+ eq(beginning_point, mark_point)
+ mark:delete()
+ end)
- it("should create mark at the end of the range", function()
- local start_point = Point:new(2, 3)
- local end_point = Point:new(3, 8)
- local range = Range:new(buffer, start_point, end_point)
- local mark = Mark.mark_end_of_range(buffer, range)
- local mark_point = Point.from_mark(mark)
- local expected_end_point = end_point:add(Point:new(0, 1))
+ it("should create mark at the end of the range", function()
+ local start_point = Point:new(2, 3)
+ local end_point = Point:new(3, 8)
+ local range = Range:new(buffer, start_point, end_point)
+ local mark = Mark.mark_end_of_range(buffer, range)
+ local mark_point = Point.from_mark(mark)
+ local expected_end_point = end_point:add(Point:new(0, 1))
- eq(expected_end_point, mark_point)
+ eq(expected_end_point, mark_point)
- mark:delete()
- end)
+ mark:delete()
+ end)
- it("should create mark above a function", function()
- local func_start = Point:new(6, 1)
- local func_end = Point:new(8, 4)
- local func_range = Range:new(buffer, func_start, func_end)
- local mock_func = {
- function_range = func_range,
- }
+ it("should create mark above a function", function()
+ local func_start = Point:new(6, 1)
+ local func_end = Point:new(8, 4)
+ local func_range = Range:new(buffer, func_start, func_end)
+ local mock_func = {
+ function_range = func_range,
+ }
- local mark = Mark.mark_above_func(buffer, mock_func)
- local mark_point = Point.from_mark(mark)
- local expected_mark_point = func_start:sub(Point:new(1, 0))
+ local mark = Mark.mark_above_func(buffer, mock_func)
+ local mark_point = Point.from_mark(mark)
+ local expected_mark_point = func_start:sub(Point:new(1, 0))
- eq(expected_mark_point, mark_point)
- mark:delete()
- end)
+ eq(expected_mark_point, mark_point)
+ mark:delete()
+ end)
- it("should create mark at function body start", function()
- local func_start = Point:new(6, 1)
- local func_end = Point:new(8, 4)
- local func_range = Range:new(buffer, func_start, func_end)
- local mock_func = {
- function_range = func_range,
- }
- local mark = Mark.mark_func_body(buffer, mock_func)
- local mark_point = Point.from_mark(mark)
+ it("should create mark at function body start", function()
+ local func_start = Point:new(6, 1)
+ local func_end = Point:new(8, 4)
+ local func_range = Range:new(buffer, func_start, func_end)
+ local mock_func = {
+ function_range = func_range,
+ }
+ local mark = Mark.mark_func_body(buffer, mock_func)
+ local mark_point = Point.from_mark(mark)
- eq(func_start, mark_point)
+ eq(func_start, mark_point)
- mark:delete()
- end)
+ mark:delete()
+ end)
- it("should delete the extmark", function()
- local point = Point:new(2, 3)
- local mark = Mark.mark_point(buffer, point)
- local mark_pos = Point.from_mark(mark)
- eq(point, mark_pos)
- mark:delete()
+ it("should delete the extmark", function()
+ local point = Point:new(2, 3)
+ local mark = Mark.mark_point(buffer, point)
+ local mark_pos = Point.from_mark(mark)
+ eq(point, mark_pos)
+ mark:delete()
- local deleted_pos = vim.api.nvim_buf_get_extmark_by_id(
- mark.buffer,
- mark.nsid,
- mark.id,
- {}
- )
- eq(0, #deleted_pos)
- end)
+ local deleted_pos =
+ vim.api.nvim_buf_get_extmark_by_id(mark.buffer, mark.nsid, mark.id, {})
+ eq(0, #deleted_pos)
+ end)
end)
diff --git a/lua/99/test/request_status_spec.lua b/lua/99/test/request_status_spec.lua
index fadae04..90bb145 100644
--- a/lua/99/test/request_status_spec.lua
+++ b/lua/99/test/request_status_spec.lua
@@ -3,17 +3,17 @@ local eq = assert.are.same
local RequestStatus = require("99.ops.request_status")
describe("request_status", function()
- it("setting lines and status line", function()
- local status = RequestStatus.new(2000000, 3, "TITLE")
- eq({ "⠙ TITLE" }, status:get())
+ it("setting lines and status line", function()
+ local status = RequestStatus.new(2000000, 3, "TITLE")
+ eq({ "⠙ TITLE" }, status:get())
- status:push("foo")
- status:push("bar")
+ status:push("foo")
+ status:push("bar")
- eq({ "⠙ TITLE", "foo", "bar" }, status:get())
+ eq({ "⠙ TITLE", "foo", "bar" }, status:get())
- status:push("baz")
+ status:push("baz")
- eq({ "⠙ TITLE", "bar", "baz" }, status:get())
- end)
+ eq({ "⠙ TITLE", "bar", "baz" }, status:get())
+ end)
end)
diff --git a/lua/99/test/test_utils.lua b/lua/99/test/test_utils.lua
index 29b7344..2f60b86 100644
--- a/lua/99/test/test_utils.lua
+++ b/lua/99/test/test_utils.lua
@@ -1,14 +1,14 @@
local M = {}
function M.next_frame()
- local next = false
- vim.schedule(function()
- next = true
- end)
+ local next = false
+ vim.schedule(function()
+ next = true
+ end)
- vim.wait(1000, function()
- return next
- end)
+ vim.wait(1000, function()
+ return next
+ end)
end
M.created_files = {}
@@ -25,64 +25,64 @@ local TestProvider = {}
TestProvider.__index = TestProvider
function TestProvider.new()
- return setmetatable({}, TestProvider)
+ return setmetatable({}, TestProvider)
end
--- @param query string
---@param request _99.Request
---@param observer _99.ProviderObserver?
function TestProvider:make_request(query, request, observer)
- local logger = request.context.logger:set_area("TestProvider")
- logger:debug("make_request", "tmp_file", request.context.tmp_file)
- self.request = {
- query = query,
- request = request,
- observer = observer,
- logger = logger,
- }
+ local logger = request.context.logger:set_area("TestProvider")
+ logger:debug("make_request", "tmp_file", request.context.tmp_file)
+ self.request = {
+ query = query,
+ request = request,
+ observer = observer,
+ logger = logger,
+ }
end
--- @param status _99.Request.ResponseState
--- @param result string
function TestProvider:resolve(status, result)
- assert(self.request, "you cannot call resolve until make_request is called")
- local obs = self.request.observer
- if obs then
- --- to match the behavior expected from the OpenCodeProvider
- if self.request.request:is_cancelled() then
- obs.on_complete("cancelled", result)
- else
- obs.on_complete(status, result)
- end
+ assert(self.request, "you cannot call resolve until make_request is called")
+ local obs = self.request.observer
+ if obs then
+ --- to match the behavior expected from the OpenCodeProvider
+ if self.request.request:is_cancelled() then
+ obs.on_complete("cancelled", result)
+ else
+ obs.on_complete(status, result)
end
- self.request = nil
+ end
+ self.request = nil
end
--- @param line string
function TestProvider:stdout(line)
- assert(self.request, "you cannot call stdout until make_request is called")
- local obs = self.request.observer
- if obs then
- obs.on_stdout(line)
- end
+ assert(self.request, "you cannot call stdout until make_request is called")
+ local obs = self.request.observer
+ if obs then
+ obs.on_stdout(line)
+ end
end
--- @param line string
function TestProvider:stderr(line)
- assert(self.request, "you cannot call stderr until make_request is called")
- local obs = self.request.observer
- if obs then
- obs.on_stderr(line)
- end
+ assert(self.request, "you cannot call stderr until make_request is called")
+ local obs = self.request.observer
+ if obs then
+ obs.on_stderr(line)
+ end
end
M.TestProvider = TestProvider
function M.clean_files()
- for _, bufnr in ipairs(M.created_files) do
- vim.api.nvim_buf_delete(bufnr, { force = true })
- end
- M.created_files = {}
+ for _, bufnr in ipairs(M.created_files) do
+ vim.api.nvim_buf_delete(bufnr, { force = true })
+ end
+ M.created_files = {}
end
---@param contents string[]
@@ -90,17 +90,17 @@ end
---@param row number?
---@param col number?
function M.create_file(contents, file_type, row, col)
- assert(type(contents) == "table", "contents must be a table of strings")
- file_type = file_type or "lua"
- local bufnr = vim.api.nvim_create_buf(false, false)
+ assert(type(contents) == "table", "contents must be a table of strings")
+ file_type = file_type or "lua"
+ local bufnr = vim.api.nvim_create_buf(false, false)
- vim.api.nvim_set_current_buf(bufnr)
- vim.bo[bufnr].ft = file_type
- vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, contents)
- vim.api.nvim_win_set_cursor(0, { row or 1, col or 0 })
+ vim.api.nvim_set_current_buf(bufnr)
+ vim.bo[bufnr].ft = file_type
+ vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, contents)
+ vim.api.nvim_win_set_cursor(0, { row or 1, col or 0 })
- table.insert(M.created_files, bufnr)
- return bufnr
+ table.insert(M.created_files, bufnr)
+ return bufnr
end
return M
diff --git a/lua/99/test/visual_spec.lua b/lua/99/test/visual_spec.lua
index bb02567..c4b1394 100644
--- a/lua/99/test/visual_spec.lua
+++ b/lua/99/test/visual_spec.lua
@@ -13,159 +13,156 @@ local Point = require("99.geo").Point
--- @param end_col number
--- @return _99.test.Provider, number, _99.Range
local function setup(content, start_row, start_col, end_row, end_col)
- local p = test_utils.TestProvider.new()
- _99.setup({
- provider = p,
- logger = {
- error_cache_level = Levels.ERROR,
- },
- })
+ local p = test_utils.TestProvider.new()
+ _99.setup({
+ provider = p,
+ logger = {
+ error_cache_level = Levels.ERROR,
+ },
+ })
- local buffer = test_utils.create_file(content, "lua", start_row, start_col)
+ local buffer = test_utils.create_file(content, "lua", start_row, start_col)
- -- Create a range for the visual selection
- local start_point = Point:new(start_row, start_col)
- local end_point = Point:new(end_row, end_col)
- local range = Range:new(buffer, start_point, end_point)
+ -- Create a range for the visual selection
+ local start_point = Point:new(start_row, start_col)
+ local end_point = Point:new(end_row, end_col)
+ local range = Range:new(buffer, start_point, end_point)
- return p, buffer, range
+ return p, buffer, range
end
--- @param buffer number
--- @return string[]
local function r(buffer)
- return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
+ return vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
end
local content = {
- "local function foo()",
- " -- TODO: implement",
- "end",
+ "local function foo()",
+ " -- TODO: implement",
+ "end",
}
describe("visual", function()
- it("should replace visual selection with AI response", function()
- local p, buffer, range = setup(content, 2, 1, 2, 23)
- local state = _99.__get_state()
- local visual_fn = require("99.ops.over-range")
+ it("should replace visual selection with AI response", function()
+ local p, buffer, range = setup(content, 2, 1, 2, 23)
+ local state = _99.__get_state()
+ local visual_fn = require("99.ops.over-range")
- local context =
- require("99.request-context").from_current_buffer(state, 100)
- visual_fn(context, range)
+ local context =
+ require("99.request-context").from_current_buffer(state, 100)
+ visual_fn(context, range)
- eq(1, state:active_request_count())
- eq(content, r(buffer))
+ eq(1, state:active_request_count())
+ eq(content, r(buffer))
- p:resolve("success", " return 'implemented!'")
- test_utils.next_frame()
+ p:resolve("success", " return 'implemented!'")
+ test_utils.next_frame()
- local expected_state = {
- "local function foo()",
- " return 'implemented!'",
- "end",
- }
- eq(expected_state, r(buffer))
- -- Note: Not checking active_request_count() == 0 due to logger bug with "id" key collision
- end)
+ local expected_state = {
+ "local function foo()",
+ " return 'implemented!'",
+ "end",
+ }
+ eq(expected_state, r(buffer))
+ -- Note: Not checking active_request_count() == 0 due to logger bug with "id" key collision
+ end)
- it("should handle multi-line replacement", function()
- local multi_line_content = {
- "local function bar()",
- " -- TODO: implement",
- " -- more comments",
- " -- even more",
- "end",
- }
- local p, buffer, range = setup(multi_line_content, 2, 1, 4, 17)
- local state = _99.__get_state()
- local visual_fn = require("99.ops.over-range")
+ it("should handle multi-line replacement", function()
+ local multi_line_content = {
+ "local function bar()",
+ " -- TODO: implement",
+ " -- more comments",
+ " -- even more",
+ "end",
+ }
+ local p, buffer, range = setup(multi_line_content, 2, 1, 4, 17)
+ local state = _99.__get_state()
+ local visual_fn = require("99.ops.over-range")
- local context =
- require("99.request-context").from_current_buffer(state, 200)
- visual_fn(context, range)
+ local context =
+ require("99.request-context").from_current_buffer(state, 200)
+ visual_fn(context, range)
- eq(1, state:active_request_count())
- eq(multi_line_content, r(buffer))
+ eq(1, state:active_request_count())
+ eq(multi_line_content, r(buffer))
- p:resolve(
- "success",
- " local x = 1\n local y = 2\n return x + y"
- )
- test_utils.next_frame()
+ p:resolve("success", " local x = 1\n local y = 2\n return x + y")
+ test_utils.next_frame()
- local expected_state = {
- "local function bar()",
- " local x = 1",
- " local y = 2",
- " return x + y",
- "end",
- }
- eq(expected_state, r(buffer))
- -- Note: Not checking active_request_count() == 0 due to logger bug with "id" key collision
- end)
+ local expected_state = {
+ "local function bar()",
+ " local x = 1",
+ " local y = 2",
+ " return x + y",
+ "end",
+ }
+ eq(expected_state, r(buffer))
+ -- Note: Not checking active_request_count() == 0 due to logger bug with "id" key collision
+ end)
- it("should cancel request when stop_all_requests is called", function()
- local p, buffer, range = setup(content, 2, 1, 2, 23)
- local visual_fn = require("99.ops.over-range")
- local state = _99.__get_state()
- local context =
- require("99.request-context").from_current_buffer(state, 300)
+ it("should cancel request when stop_all_requests is called", function()
+ local p, buffer, range = setup(content, 2, 1, 2, 23)
+ local visual_fn = require("99.ops.over-range")
+ local state = _99.__get_state()
+ local context =
+ require("99.request-context").from_current_buffer(state, 300)
- visual_fn(context, range)
+ visual_fn(context, range)
- eq(content, r(buffer))
+ eq(content, r(buffer))
- assert.is_false(p.request.request:is_cancelled())
- assert.is_not_nil(p.request)
- assert.is_not_nil(p.request.request)
+ assert.is_false(p.request.request:is_cancelled())
+ assert.is_not_nil(p.request)
+ assert.is_not_nil(p.request.request)
- _99.stop_all_requests()
- test_utils.next_frame()
+ _99.stop_all_requests()
+ test_utils.next_frame()
- assert.is_true(p.request.request:is_cancelled())
+ assert.is_true(p.request.request:is_cancelled())
- p:resolve("success", " return 'should not appear'")
- test_utils.next_frame()
+ p:resolve("success", " return 'should not appear'")
+ test_utils.next_frame()
- -- Buffer should remain unchanged after cancellation
- eq(content, r(buffer))
- end)
+ -- Buffer should remain unchanged after cancellation
+ eq(content, r(buffer))
+ end)
- it("should handle error cases with graceful failures", function()
- local p, buffer, range = setup(content, 2, 1, 2, 23)
- local visual_fn = require("99.ops.over-range")
- local state = _99.__get_state()
- local context =
- require("99.request-context").from_current_buffer(state, 400)
+ it("should handle error cases with graceful failures", function()
+ local p, buffer, range = setup(content, 2, 1, 2, 23)
+ local visual_fn = require("99.ops.over-range")
+ local state = _99.__get_state()
+ local context =
+ require("99.request-context").from_current_buffer(state, 400)
- visual_fn(context, range)
+ visual_fn(context, range)
- eq(content, r(buffer))
+ eq(content, r(buffer))
- p:resolve("failed", "Something went wrong")
- test_utils.next_frame()
+ p:resolve("failed", "Something went wrong")
+ test_utils.next_frame()
- -- Buffer should remain unchanged on failure
- eq(content, r(buffer))
- end)
+ -- Buffer should remain unchanged on failure
+ eq(content, r(buffer))
+ end)
- it("should handle cancelled status gracefully", function()
- local p, buffer, range = setup(content, 2, 1, 2, 23)
- local visual_fn = require("99.ops.over-range")
- local state = _99.__get_state()
- local context =
- require("99.request-context").from_current_buffer(state, 500)
+ it("should handle cancelled status gracefully", function()
+ local p, buffer, range = setup(content, 2, 1, 2, 23)
+ local visual_fn = require("99.ops.over-range")
+ local state = _99.__get_state()
+ local context =
+ require("99.request-context").from_current_buffer(state, 500)
- visual_fn(context, range)
+ visual_fn(context, range)
- eq(content, r(buffer))
+ eq(content, r(buffer))
- -- Manually cancel and resolve as cancelled
- p.request.request:cancel()
- p:resolve("cancelled", "Request was cancelled")
- test_utils.next_frame()
+ -- Manually cancel and resolve as cancelled
+ p.request.request:cancel()
+ p:resolve("cancelled", "Request was cancelled")
+ test_utils.next_frame()
- -- Buffer should remain unchanged on cancellation
- eq(content, r(buffer))
- end)
+ -- Buffer should remain unchanged on cancellation
+ eq(content, r(buffer))
+ end)
end)