Skip to content

Commit 0586c8d

Browse files
Add comprehensive tests for range selection functionality
- Add tests for get_range_selection() function covering valid/invalid ranges - Add tests for send_at_mention_for_visual_selection() with range parameters - Add unit tests for ClaudeCodeSend command range integration - Tests cover edge cases like buffer bounds, empty buffers, and error conditions - Ensures backward compatibility with existing functionality Co-authored-by: ThomasK33 <[email protected]>
1 parent 61ead43 commit 0586c8d

File tree

2 files changed

+422
-0
lines changed

2 files changed

+422
-0
lines changed

tests/selection_test.lua

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,177 @@ describe("Selection module", function()
454454
assert(selection.has_selection_changed(new_selection_diff_pos) == true)
455455
end)
456456
end)
457+
458+
-- Tests for range selection functionality (fix for issue #25)
459+
describe("Range Selection Tests", function()
460+
local selection
461+
462+
before_each(function()
463+
-- Reset vim state
464+
_G.vim._buffers = {
465+
[1] = {
466+
name = "/test/file.lua",
467+
lines = {
468+
"line 1",
469+
"line 2",
470+
"line 3",
471+
"line 4",
472+
"line 5",
473+
"line 6",
474+
"line 7",
475+
"line 8",
476+
"line 9",
477+
"line 10"
478+
}
479+
}
480+
}
481+
_G.vim._windows = {
482+
[1] = {
483+
cursor = { 1, 0 }
484+
}
485+
}
486+
_G.vim._current_mode = "n"
487+
488+
-- Add nvim_buf_line_count function
489+
_G.vim.api.nvim_buf_line_count = function(bufnr)
490+
return _G.vim._buffers[bufnr] and #_G.vim._buffers[bufnr].lines or 0
491+
end
492+
493+
-- Reload the selection module
494+
package.loaded["claudecode.selection"] = nil
495+
selection = require("claudecode.selection")
496+
end)
497+
498+
describe("get_range_selection", function()
499+
it("should return valid selection for valid range", function()
500+
local result = selection.get_range_selection(2, 4)
501+
502+
assert(result ~= nil)
503+
assert(result.text == "line 2\nline 3\nline 4")
504+
assert(result.filePath == "/test/file.lua")
505+
assert(result.fileUrl == "file:///test/file.lua")
506+
assert(result.selection.start.line == 1) -- 0-indexed
507+
assert(result.selection.start.character == 0)
508+
assert(result.selection["end"].line == 3) -- 0-indexed
509+
assert(result.selection["end"].character == 6) -- length of "line 4"
510+
assert(result.selection.isEmpty == false)
511+
end)
512+
513+
it("should return valid selection for single line range", function()
514+
local result = selection.get_range_selection(3, 3)
515+
516+
assert(result ~= nil)
517+
assert(result.text == "line 3")
518+
assert(result.selection.start.line == 2) -- 0-indexed
519+
assert(result.selection["end"].line == 2) -- 0-indexed
520+
assert(result.selection.isEmpty == false)
521+
end)
522+
523+
it("should handle range that exceeds buffer bounds", function()
524+
local result = selection.get_range_selection(8, 15) -- buffer only has 10 lines
525+
526+
assert(result ~= nil)
527+
assert(result.text == "line 8\nline 9\nline 10")
528+
assert(result.selection.start.line == 7) -- 0-indexed
529+
assert(result.selection["end"].line == 9) -- 0-indexed, clamped to buffer size
530+
end)
531+
532+
it("should return nil for invalid range (line1 > line2)", function()
533+
local result = selection.get_range_selection(5, 3)
534+
assert(result == nil)
535+
end)
536+
537+
it("should return nil for invalid range (line1 < 1)", function()
538+
local result = selection.get_range_selection(0, 3)
539+
assert(result == nil)
540+
end)
541+
542+
it("should return nil for invalid range (line2 < 1)", function()
543+
local result = selection.get_range_selection(2, 0)
544+
assert(result == nil)
545+
end)
546+
547+
it("should return nil for nil parameters", function()
548+
local result1 = selection.get_range_selection(nil, 3)
549+
local result2 = selection.get_range_selection(2, nil)
550+
local result3 = selection.get_range_selection(nil, nil)
551+
552+
assert(result1 == nil)
553+
assert(result2 == nil)
554+
assert(result3 == nil)
555+
end)
556+
557+
it("should handle empty buffer", function()
558+
_G.vim._buffers[1].lines = {}
559+
local result = selection.get_range_selection(1, 1)
560+
assert(result == nil)
561+
end)
562+
end)
563+
564+
describe("send_at_mention_for_visual_selection with range", function()
565+
local mock_server
566+
567+
before_each(function()
568+
mock_server = {
569+
broadcast = function(event, params)
570+
mock_server.last_broadcast = {
571+
event = event,
572+
params = params
573+
}
574+
return true
575+
end
576+
}
577+
578+
selection.state.tracking_enabled = true
579+
selection.server = mock_server
580+
end)
581+
582+
it("should send range selection successfully", function()
583+
local result = selection.send_at_mention_for_visual_selection(2, 4)
584+
585+
assert(result == true)
586+
assert(mock_server.last_broadcast ~= nil)
587+
assert(mock_server.last_broadcast.event == "at_mentioned")
588+
assert(mock_server.last_broadcast.params.filePath == "/test/file.lua")
589+
assert(mock_server.last_broadcast.params.lineStart == 1) -- 0-indexed
590+
assert(mock_server.last_broadcast.params.lineEnd == 3) -- 0-indexed
591+
end)
592+
593+
it("should fail for invalid range", function()
594+
local result = selection.send_at_mention_for_visual_selection(5, 3)
595+
assert(result == false)
596+
end)
597+
598+
it("should fall back to existing logic when no range provided", function()
599+
-- Set up a tracked selection
600+
selection.state.latest_selection = {
601+
text = "tracked text",
602+
filePath = "/test/file.lua",
603+
fileUrl = "file:///test/file.lua",
604+
selection = {
605+
start = { line = 0, character = 0 },
606+
["end"] = { line = 0, character = 12 },
607+
isEmpty = false
608+
}
609+
}
610+
611+
local result = selection.send_at_mention_for_visual_selection()
612+
613+
assert(result == true)
614+
assert(mock_server.last_broadcast.params.lineStart == 0)
615+
assert(mock_server.last_broadcast.params.lineEnd == 0)
616+
end)
617+
618+
it("should fail when server is not available", function()
619+
selection.server = nil
620+
local result = selection.send_at_mention_for_visual_selection(2, 4)
621+
assert(result == false)
622+
end)
623+
624+
it("should fail when tracking is disabled", function()
625+
selection.state.tracking_enabled = false
626+
local result = selection.send_at_mention_for_visual_selection(2, 4)
627+
assert(result == false)
628+
end)
629+
end)
630+
end)

0 commit comments

Comments
 (0)