228 lines
6.1 KiB
Rust
228 lines
6.1 KiB
Rust
#![cfg(feature = "vi")]
|
|
|
|
use std::sync::OnceLock;
|
|
|
|
use cosmic_text::{Buffer, Cursor, Edit, Metrics, SyntaxEditor, SyntaxSystem, ViEditor};
|
|
|
|
static SYNTAX_SYSTEM: OnceLock<SyntaxSystem> = OnceLock::new();
|
|
|
|
// New editor for tests
|
|
fn editor() -> ViEditor<'static, 'static> {
|
|
// More or less copied from cosmic-edit
|
|
let font_size: f32 = 14.0;
|
|
let line_height = (font_size * 1.4).ceil();
|
|
|
|
let metrics = Metrics::new(font_size, line_height);
|
|
let buffer = Buffer::new_empty(metrics);
|
|
let editor = SyntaxEditor::new(
|
|
buffer,
|
|
SYNTAX_SYSTEM.get_or_init(SyntaxSystem::new),
|
|
"base16-eighties.dark",
|
|
)
|
|
.expect("Default theme `base16-eighties.dark` should be found");
|
|
|
|
ViEditor::new(editor)
|
|
}
|
|
|
|
// Tests that inserting into an empty editor correctly sets the editor as modified.
|
|
#[test]
|
|
fn insert_in_empty_editor_sets_changed() {
|
|
let mut editor = editor();
|
|
|
|
assert!(!editor.changed());
|
|
editor.start_change();
|
|
editor.insert_at(Cursor::new(0, 0), "Robert'); DROP TABLE Students;--", None);
|
|
editor.finish_change();
|
|
assert!(editor.changed());
|
|
}
|
|
|
|
// Tests an edge case where a save point is never set.
|
|
// Undoing changes should set the editor back to unmodified.
|
|
#[test]
|
|
fn insert_and_undo_in_unsaved_editor_is_unchanged() {
|
|
let mut editor = editor();
|
|
|
|
assert!(!editor.changed());
|
|
editor.start_change();
|
|
editor.insert_at(Cursor::new(0, 0), "loop {}", None);
|
|
editor.finish_change();
|
|
assert!(editor.changed());
|
|
|
|
// Undoing the above change should set the editor as unchanged even if the save state is unset
|
|
editor.start_change();
|
|
editor.undo();
|
|
editor.finish_change();
|
|
assert!(!editor.changed());
|
|
}
|
|
|
|
#[test]
|
|
fn undo_to_save_point_sets_editor_to_unchanged() {
|
|
let mut editor = editor();
|
|
|
|
// Latest saved change is the first change
|
|
editor.start_change();
|
|
let cursor = editor.insert_at(Cursor::new(0, 0), "Ferris is Rust's ", None);
|
|
editor.finish_change();
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be set to changed after insertion"
|
|
);
|
|
editor.save_point();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be set to unchanged after setting a save point"
|
|
);
|
|
|
|
// A new insert should set the editor as modified and the pivot should still be on the first
|
|
// change from earlier
|
|
editor.start_change();
|
|
editor.insert_at(cursor, "mascot", None);
|
|
editor.finish_change();
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be set to changed after inserting text after a save point"
|
|
);
|
|
|
|
// Undoing the latest change should set the editor to unmodified again
|
|
editor.start_change();
|
|
editor.undo();
|
|
editor.finish_change();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be set to unchanged after undoing to save point"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn redoing_to_save_point_sets_editor_as_unchanged() {
|
|
let mut editor = editor();
|
|
|
|
// Initial change
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should start in an unchanged state"
|
|
);
|
|
editor.start_change();
|
|
editor.insert_at(Cursor::new(0, 0), "editor.start_change();", None);
|
|
editor.finish_change();
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be set as modified after insert() and finish_change()"
|
|
);
|
|
editor.save_point();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be unchanged after setting a save point"
|
|
);
|
|
|
|
// Change to undo then redo
|
|
editor.start_change();
|
|
editor.insert_at(Cursor::new(1, 0), "editor.finish_change()", None);
|
|
editor.finish_change();
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be set as modified after insert() and finish_change()"
|
|
);
|
|
editor.save_point();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be unchanged after setting a save point"
|
|
);
|
|
|
|
editor.undo();
|
|
assert!(
|
|
editor.changed(),
|
|
"Undoing past save point should set editor as changed"
|
|
);
|
|
editor.redo();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Redoing to save point should set editor as unchanged"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn redoing_past_save_point_sets_editor_to_changed() {
|
|
let mut editor = editor();
|
|
|
|
// Save point change to undo to and then redo past.
|
|
editor.start_change();
|
|
editor.insert_string("Walt Whitman ", None);
|
|
editor.finish_change();
|
|
|
|
// Set save point to the change above.
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be set as modified after insert() and finish_change()"
|
|
);
|
|
editor.save_point();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be unchanged after setting a save point"
|
|
);
|
|
|
|
editor.start_change();
|
|
editor.insert_string("Allen Ginsberg ", None);
|
|
editor.finish_change();
|
|
|
|
editor.start_change();
|
|
editor.insert_string("Jack Kerouac ", None);
|
|
editor.finish_change();
|
|
|
|
assert!(editor.changed(), "Editor should be modified insertion");
|
|
|
|
// Undo to Whitman
|
|
editor.undo();
|
|
editor.undo();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be unmodified after undoing to the save point"
|
|
);
|
|
|
|
// Redo to Kerouac
|
|
editor.redo();
|
|
editor.redo();
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be modified after redoing past the save point"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn undoing_past_save_point_sets_editor_to_changed() {
|
|
let mut editor = editor();
|
|
|
|
editor.start_change();
|
|
editor.insert_string("Robert Fripp ", None);
|
|
editor.finish_change();
|
|
|
|
// Save point change to undo past.
|
|
editor.start_change();
|
|
editor.insert_string("Thurston Moore ", None);
|
|
editor.finish_change();
|
|
|
|
assert!(editor.changed(), "Editor should be changed after insertion");
|
|
editor.save_point();
|
|
assert!(
|
|
!editor.changed(),
|
|
"Editor should be unchanged after setting a save point"
|
|
);
|
|
|
|
editor.start_change();
|
|
editor.insert_string("Kim Deal ", None);
|
|
editor.finish_change();
|
|
|
|
// Undo to the first change
|
|
editor.undo();
|
|
editor.undo();
|
|
assert!(
|
|
editor.changed(),
|
|
"Editor should be changed after undoing past save point"
|
|
);
|
|
}
|
|
|
|
// #[test]
|
|
// fn undo_all_changes() {
|
|
// unimplemented!()
|
|
// }
|