use editor_core::{
Command, CommandExecutor, CursorCommand, EditCommand, Position, Selection, SelectionDirection,
};
#[test]
fn test_undo_history_snapshot_restore_roundtrip_preserves_clean_point_and_redo() {
let mut executor = CommandExecutor::new("one\ntwo\nthree\n", 80);
let selections = vec![
Selection {
start: Position::new(0, 0),
end: Position::new(0, 0),
direction: SelectionDirection::Forward,
},
Selection {
start: Position::new(1, 0),
end: Position::new(1, 0),
direction: SelectionDirection::Forward,
},
Selection {
start: Position::new(2, 0),
end: Position::new(2, 0),
direction: SelectionDirection::Forward,
},
];
executor
.execute(Command::Cursor(CursorCommand::SetSelections {
selections,
primary_index: 1,
}))
.unwrap();
executor
.execute(Command::Edit(EditCommand::InsertText {
text: "X".to_string(),
}))
.unwrap();
assert_eq!(executor.editor().get_text(), "Xone\nXtwo\nXthree\n");
executor.mark_clean();
assert!(executor.is_clean());
executor
.execute(Command::Edit(EditCommand::InsertText {
text: "Y".to_string(),
}))
.unwrap();
executor
.execute(Command::Edit(EditCommand::InsertText {
text: "Z".to_string(),
}))
.unwrap();
assert!(!executor.is_clean());
executor.execute(Command::Edit(EditCommand::Undo)).unwrap();
assert!(executor.is_clean());
executor.execute(Command::Edit(EditCommand::Undo)).unwrap();
assert_eq!(executor.editor().get_text(), "one\ntwo\nthree\n");
assert!(!executor.is_clean());
assert!(!executor.can_undo());
assert!(executor.can_redo());
let snapshot = executor.undo_history_snapshot();
let current_text = executor.editor().get_text().to_string();
let mut restored = CommandExecutor::new(¤t_text, 80);
restored.restore_undo_history(snapshot).unwrap();
assert_eq!(restored.editor().get_text(), executor.editor().get_text());
assert_eq!(restored.can_undo(), executor.can_undo());
assert_eq!(restored.can_redo(), executor.can_redo());
assert_eq!(restored.undo_depth(), executor.undo_depth());
assert_eq!(restored.redo_depth(), executor.redo_depth());
assert_eq!(restored.is_clean(), executor.is_clean());
restored.execute(Command::Edit(EditCommand::Redo)).unwrap();
assert_eq!(restored.editor().get_text(), "Xone\nXtwo\nXthree\n");
assert!(restored.is_clean());
restored.execute(Command::Edit(EditCommand::Redo)).unwrap();
assert_eq!(restored.editor().get_text(), "XYZone\nXYZtwo\nXYZthree\n");
assert!(!restored.is_clean());
restored.execute(Command::Edit(EditCommand::Undo)).unwrap();
assert_eq!(restored.editor().get_text(), "Xone\nXtwo\nXthree\n");
assert!(restored.is_clean());
}
#[cfg(feature = "serde")]
#[test]
fn test_undo_history_snapshot_can_load_json_fixture() {
use editor_core::UndoHistorySnapshot;
let json = include_str!("fixtures/undo_history_snapshot_v1.json");
let snapshot: UndoHistorySnapshot = serde_json::from_str(json).expect("fixture parse");
let mut executor = CommandExecutor::empty(80);
executor.restore_undo_history(snapshot).unwrap();
assert!(executor.can_redo());
executor.execute(Command::Edit(EditCommand::Redo)).unwrap();
assert_eq!(executor.editor().get_text(), "X");
executor.execute(Command::Edit(EditCommand::Undo)).unwrap();
assert_eq!(executor.editor().get_text(), "");
}