#![allow(clippy::significant_drop_tightening)]
use super::super::*;
use {
reovim_driver_command::{Command, CommandContext, CommandResult},
reovim_driver_session::{
ClientId, ExtensionMap, Session, SessionRuntime, WindowLayout, testing::StubExecutor,
},
reovim_kernel::{
api::{
ModeStack,
v1::{
Buffer, BufferId, HistoryRing, Jumplist, KernelContext, MarkBank, ModeId, ModuleId,
Position, RegisterBank,
},
},
testing::create_test_context,
},
};
use crate::modes::VIM_MODULE;
struct TestState {
session: Session,
mode_stack: ModeStack,
windows: WindowLayout,
extensions: ExtensionMap,
compositor: Option<Box<dyn reovim_driver_layout::RootCompositor>>,
tabs: reovim_driver_session::TabPageSet,
registers: RegisterBank,
clipboard_history: HistoryRing,
local_marks: MarkBank,
jumplist: Jumplist,
active_buffer: Option<BufferId>,
terminal_size: (u16, u16),
}
impl TestState {
fn with_buffer(buffer_id: Option<BufferId>) -> Self {
let home_mode = ModeId::new(ModuleId::new("test"), "normal");
let session = Session::new(ClientId::new(1), home_mode.clone()); let mode_stack = ModeStack::new(home_mode);
let mut windows = WindowLayout::empty();
let extensions = ExtensionMap::new();
let mut window = reovim_driver_session::Window::new();
if let Some(buffer_id) = buffer_id {
window.buffer_id = Some(buffer_id);
}
windows.add(window);
Self {
session,
mode_stack,
windows,
extensions,
compositor: None,
tabs: reovim_driver_session::TabPageSet::new(),
registers: RegisterBank::new(),
clipboard_history: HistoryRing::new(),
local_marks: MarkBank::new(),
jumplist: Jumplist::new(),
active_buffer: None,
terminal_size: (80, 24),
}
}
fn with_selection(
buffer_id: BufferId,
selection: reovim_driver_session::api::Selection,
) -> Self {
let home_mode = ModeId::new(ModuleId::new("test"), "normal");
let session = Session::new(ClientId::new(1), home_mode.clone()); let mode_stack = ModeStack::new(home_mode);
let mut windows = WindowLayout::empty();
let extensions = ExtensionMap::new();
let mut window = reovim_driver_session::Window::new();
window.buffer_id = Some(buffer_id);
window.selection = Some(selection);
windows.add(window);
Self {
session,
mode_stack,
windows,
extensions,
compositor: None,
tabs: reovim_driver_session::TabPageSet::new(),
registers: RegisterBank::new(),
clipboard_history: HistoryRing::new(),
local_marks: MarkBank::new(),
jumplist: Jumplist::new(),
active_buffer: None,
terminal_size: (80, 24),
}
}
fn runtime<'a>(&'a mut self, kernel: &'a KernelContext) -> SessionRuntime<'a> {
SessionRuntime::new(
&mut self.session,
reovim_driver_session::ClientContext {
mode_stack: &mut self.mode_stack,
windows: &mut self.windows,
extensions: &mut self.extensions,
compositor: &mut self.compositor,
tabs: &mut self.tabs,
registers: &mut self.registers,
clipboard_history: &mut self.clipboard_history,
local_marks: &mut self.local_marks,
jumplist: &mut self.jumplist,
active_buffer: &mut self.active_buffer,
terminal_size: &mut self.terminal_size,
},
kernel,
&StubExecutor,
)
}
}
fn run_command<C: CommandHandler>(
cmd: &C,
ctx: &KernelContext,
args: &CommandContext,
) -> CommandResult {
let mut state = TestState::with_buffer(args.buffer_id());
let mut runtime = state.runtime(ctx);
cmd.execute(&mut runtime, args)
}
fn run_command_with_session<C: CommandHandler>(
cmd: &C,
ctx: &KernelContext,
args: &CommandContext,
) -> (CommandResult, WindowLayout) {
let mut state = TestState::with_buffer(args.buffer_id());
let mut runtime = state.runtime(ctx);
let result = cmd.execute(&mut runtime, args);
drop(runtime);
(result, state.windows)
}
fn run_command_with_selection<C: CommandHandler>(
cmd: &C,
ctx: &KernelContext,
args: &CommandContext,
selection: reovim_driver_session::api::Selection,
) -> (CommandResult, WindowLayout) {
let buffer_id = args
.buffer_id()
.expect("buffer_id required for selection test");
let mut state = TestState::with_selection(buffer_id, selection);
let mut runtime = state.runtime(ctx);
let result = cmd.execute(&mut runtime, args);
drop(runtime);
(result, state.windows)
}
#[test]
fn test_enter_visual_command_id() {
let cmd = EnterVisualMode;
assert_eq!(cmd.id().name(), "enter-visual");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_enter_visual_line_command_id() {
let cmd = EnterVisualLineMode;
assert_eq!(cmd.id().name(), "enter-visual-line");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_enter_visual_block_command_id() {
let cmd = EnterVisualBlockMode;
assert_eq!(cmd.id().name(), "enter-visual-block");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_exit_visual_command_id() {
let cmd = ExitVisualMode;
assert_eq!(cmd.id().name(), "exit-visual");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_enter_visual_activates_selection() {
use reovim_driver_session::SelectionMode;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let (result, windows) = run_command_with_session(&EnterVisualMode, &ctx, &args);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
assert_eq!(window.selection.as_ref().unwrap().mode, SelectionMode::Character);
}
#[test]
fn test_enter_visual_line_activates_line_selection() {
use reovim_driver_session::SelectionMode;
let ctx = create_test_context();
let buffer = Buffer::from_string("line 1\nline 2");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let (result, windows) = run_command_with_session(&EnterVisualLineMode, &ctx, &args);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
assert_eq!(window.selection.as_ref().unwrap().mode, SelectionMode::Line);
}
#[test]
fn test_enter_visual_block_activates_block_selection() {
use reovim_driver_session::SelectionMode;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello\nworld");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let (result, windows) = run_command_with_session(&EnterVisualBlockMode, &ctx, &args);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
assert_eq!(window.selection.as_ref().unwrap().mode, SelectionMode::Block);
}
#[test]
fn test_enter_visual_no_buffer_succeeds_with_window() {
let ctx = create_test_context();
let args = CommandContext::new();
let result = run_command(&EnterVisualMode, &ctx, &args);
assert_eq!(result, CommandResult::Success);
}
#[test]
fn test_exit_visual_clears_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let (_, windows) = run_command_with_session(&EnterVisualMode, &ctx, &args);
assert!(windows.active().unwrap().selection.is_some());
let (result, windows) = run_command_with_session(&ExitVisualMode, &ctx, &args);
assert_eq!(result, CommandResult::Success);
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_exit_visual_without_buffer_succeeds() {
let ctx = create_test_context();
let args = CommandContext::new();
let result = run_command(&ExitVisualMode, &ctx, &args);
assert_eq!(result, CommandResult::Success);
}
#[test]
fn test_swap_anchor_command_id() {
let cmd = SwapAnchor;
assert_eq!(cmd.id().name(), "visual-swap-anchor");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_swap_anchor_swaps_positions() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let (_, windows) = run_command_with_session(&EnterVisualMode, &ctx, &args);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
let sel = window.selection.as_ref().unwrap();
assert_eq!(sel.start, Position::new(0, 0));
let (result, _) = run_command_with_session(&SwapAnchor, &ctx, &args);
assert_eq!(result, CommandResult::Success);
}
#[test]
fn test_swap_anchor_noop_without_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&SwapAnchor, &ctx, &args);
assert_eq!(result, CommandResult::Success);
}
#[test]
fn test_toggle_visual_char_exits_if_already_char() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&ToggleVisualChar, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_toggle_visual_char_switches_from_line() {
use reovim_driver_session::{SelectionMode, api::Selection};
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::line(Position::new(0, 0), Position::new(1, 0));
let (result, windows) = run_command_with_selection(&ToggleVisualChar, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
assert_eq!(window.selection.as_ref().unwrap().mode, SelectionMode::Character);
}
#[test]
fn test_toggle_visual_line_exits_if_already_line() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::line(Position::new(0, 0), Position::new(1, 0));
let (result, windows) = run_command_with_selection(&ToggleVisualLine, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_toggle_visual_block_switches_mode() {
use reovim_driver_session::{SelectionMode, api::Selection};
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&ToggleVisualBlock, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
assert_eq!(window.selection.as_ref().unwrap().mode, SelectionMode::Block);
}
#[test]
fn test_visual_selection_commands_count() {
let cmds = visual_selection_commands();
assert_eq!(cmds.len(), 5); }
#[test]
fn test_visual_entry_commands_count() {
let cmds = visual_entry_commands();
assert_eq!(cmds.len(), 3);
}
#[test]
fn test_visual_exit_commands_count() {
let cmds = visual_exit_commands();
assert_eq!(cmds.len(), 1);
}
#[test]
fn test_visual_commands_count() {
let cmds = visual_commands();
assert_eq!(cmds.len(), 17); }
#[test]
fn test_visual_operator_commands_count() {
let cmds = visual_operator_commands();
assert_eq!(cmds.len(), 8); }
#[test]
fn test_reselect_last_command_id() {
let cmd = ReselectLast;
assert_eq!(cmd.id().name(), "reselect-last");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_reselect_last_returns_success() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&ReselectLast, &ctx, &args);
assert!(result.is_success());
}
#[test]
fn test_delete_selection_command_id() {
let cmd = DeleteSelection;
assert_eq!(cmd.id().name(), "delete-selection");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_yank_selection_command_id() {
let cmd = YankSelection;
assert_eq!(cmd.id().name(), "yank-selection");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_change_selection_command_id() {
let cmd = ChangeSelection;
assert_eq!(cmd.id().name(), "change-selection");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_indent_selection_command_id() {
let cmd = IndentSelection;
assert_eq!(cmd.id().name(), "indent-selection");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_dedent_selection_command_id() {
let cmd = DedentSelection;
assert_eq!(cmd.id().name(), "dedent-selection");
assert_eq!(cmd.id().module(), &VIM_MODULE);
}
#[test]
fn test_delete_selection_noop_without_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&DeleteSelection, &ctx, &args);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), "hello world");
}
#[test]
fn test_yank_selection_noop_without_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&YankSelection, &ctx, &args);
assert_eq!(result, CommandResult::Success);
}
#[test]
fn test_change_selection_noop_without_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&ChangeSelection, &ctx, &args);
assert_eq!(result, CommandResult::Success);
}
#[test]
fn test_delete_selection_deletes_text() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&DeleteSelection, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), " world");
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_indent_selection_adds_indentation() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("line1\nline2\nline3");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::line(Position::new(0, 0), Position::new(2, 0));
let (result, _session) = run_command_with_selection(&IndentSelection, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert!(buffer.line(0).unwrap().starts_with(" ")); assert!(buffer.line(1).unwrap().starts_with(" "));
assert!(!buffer.line(2).unwrap().starts_with(" ")); }
#[test]
fn test_dedent_selection_removes_indentation() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string(" line1\n line2\nline3");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::line(Position::new(0, 0), Position::new(2, 0));
let (result, _session) = run_command_with_selection(&DedentSelection, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), "line1");
assert_eq!(buffer.line(1).unwrap(), "line2");
assert_eq!(buffer.line(2).unwrap(), "line3"); }
#[test]
fn test_yank_selection_yanks_text() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&YankSelection, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), "hello world");
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_change_selection_changes_text() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&ChangeSelection, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), " world");
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_delete_selection_line_mode_deletes_entire_lines() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("line one\nline two\nline three");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::line(Position::new(0, 0), Position::new(2, 0));
let (result, _session) = run_command_with_selection(&DeleteSelection, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line_count(), 1);
assert_eq!(buffer.line(0).unwrap(), "line three");
}
#[test]
fn test_visual_commands_total_is_correct() {
let total = visual_commands();
let entry = visual_entry_commands();
let exit = visual_exit_commands();
let sel = visual_selection_commands();
let ops = visual_operator_commands();
assert_eq!(total.len(), entry.len() + exit.len() + sel.len() + ops.len());
}
#[test]
#[cfg_attr(coverage_nightly, coverage(off))]
fn test_all_visual_commands_have_vim_module() {
let cmds = visual_commands();
for cmd in &cmds {
assert_eq!(
cmd.id().module(),
&VIM_MODULE,
"command '{}' should be in vim module",
cmd.id().name()
);
}
}
#[test]
fn test_visual_entry_commands_unique_ids() {
let cmds = visual_entry_commands();
let ids: Vec<_> = cmds.iter().map(|c| c.id()).collect();
let mut seen = std::collections::HashSet::new();
for id in &ids {
assert!(seen.insert(id.name()), "Duplicate command id: {}", id.name());
}
}
#[test]
fn test_visual_operator_commands_unique_ids() {
let cmds = visual_operator_commands();
let ids: Vec<_> = cmds.iter().map(|c| c.id()).collect();
let mut seen = std::collections::HashSet::new();
for id in &ids {
assert!(seen.insert(id.name()), "Duplicate command id: {}", id.name());
}
}
#[test]
fn test_visual_selection_commands_unique_ids() {
let cmds = visual_selection_commands();
let ids: Vec<_> = cmds.iter().map(|c| c.id()).collect();
let mut seen = std::collections::HashSet::new();
for id in &ids {
assert!(seen.insert(id.name()), "Duplicate command id: {}", id.name());
}
}
#[test]
#[cfg_attr(coverage_nightly, coverage(off))]
fn test_all_visual_commands_unique_ids() {
let cmds = visual_commands();
let ids: Vec<_> = cmds.iter().map(|c| c.id()).collect();
let mut seen = std::collections::HashSet::new();
for id in &ids {
assert!(
seen.insert(format!("{}:{}", id.module().as_str(), id.name())),
"Duplicate command id: {}",
id.name()
);
}
}
#[test]
fn test_indent_selection_noop_without_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string("hello\nworld");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&IndentSelection, &ctx, &args);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), "hello");
}
#[test]
fn test_dedent_selection_noop_without_selection() {
let ctx = create_test_context();
let buffer = Buffer::from_string(" hello\n world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let result = run_command(&DedentSelection, &ctx, &args);
assert_eq!(result, CommandResult::Success);
let buffer_arc = ctx.buffers.get(buffer_id).unwrap();
let buffer = buffer_arc.read();
assert_eq!(buffer.line(0).unwrap(), " hello");
}
#[test]
fn test_toggle_visual_line_from_char_keeps_selection() {
use reovim_driver_session::{SelectionMode, api::Selection};
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&ToggleVisualLine, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
assert!(window.selection.is_some());
assert_eq!(window.selection.as_ref().unwrap().mode, SelectionMode::Line);
}
#[test]
fn test_toggle_visual_block_exits_if_already_block() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello world");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::block(Position::new(0, 0), Position::new(0, 5));
let (result, windows) = run_command_with_selection(&ToggleVisualBlock, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
assert!(windows.active().unwrap().selection.is_none());
}
#[test]
fn test_swap_anchor_with_different_lines() {
use reovim_driver_session::api::Selection;
let ctx = create_test_context();
let buffer = Buffer::from_string("hello\nworld\nfoo");
let buffer_id = ctx.buffers.register(buffer);
let mut args = CommandContext::new();
args.set_buffer_id(buffer_id);
let selection = Selection::character(Position::new(0, 2), Position::new(2, 1));
let (result, windows) = run_command_with_selection(&SwapAnchor, &ctx, &args, selection);
assert_eq!(result, CommandResult::Success);
let window = windows.active().unwrap();
let sel = window.selection.as_ref().unwrap();
assert_eq!(sel.start, Position::new(2, 1));
assert_eq!(sel.end, Position::new(0, 2));
}