use super::*;
#[test]
fn save_trims_trailing_whitespace_when_option_on() {
use std::io::Write;
let path = tmp_path(&format!(
"hjkl_tts_on_{}.txt",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let mut f = std::fs::File::create(&path).unwrap();
f.write_all(b"hello \nworld\t\nclean\n").unwrap();
drop(f);
let mut app = App::new(Some(path.clone()), false, None, None).unwrap();
app.active_editor_mut()
.settings_mut()
.trim_trailing_whitespace = true;
app.dispatch_ex("write");
let on_disk = std::fs::read_to_string(&path).unwrap();
assert!(
!on_disk.contains(" "),
"trailing spaces must be stripped from disk; got: {on_disk:?}"
);
assert!(
!on_disk.contains('\t'),
"trailing tabs must be stripped from disk; got: {on_disk:?}"
);
assert!(
on_disk.contains("hello"),
"content must be preserved; got: {on_disk:?}"
);
assert!(
on_disk.contains("world"),
"content must be preserved; got: {on_disk:?}"
);
let buf = app.active_editor().buffer().as_string();
assert!(
!buf.contains(" "),
"buffer must have no trailing spaces after trim; got: {buf:?}"
);
assert!(
!buf.contains('\t') || buf.trim_start_matches('\t').is_empty(),
"buffer must have no trailing tabs; got: {buf:?}"
);
let _ = std::fs::remove_file(&path);
}
#[test]
fn save_skips_trim_when_option_off() {
use std::io::Write;
let path = tmp_path(&format!(
"hjkl_tts_off_{}.txt",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let mut f = std::fs::File::create(&path).unwrap();
f.write_all(b"hello \nworld\n").unwrap();
drop(f);
let mut app = App::new(Some(path.clone()), false, None, None).unwrap();
app.active_editor_mut()
.settings_mut()
.trim_trailing_whitespace = false;
app.dispatch_ex("write");
let on_disk = std::fs::read_to_string(&path).unwrap();
assert!(
on_disk.contains("hello "),
"trailing whitespace must be preserved when option is off; got: {on_disk:?}"
);
let _ = std::fs::remove_file(&path);
}
#[test]
fn save_trim_noop_when_no_trailing_whitespace() {
use std::io::Write;
let path = tmp_path(&format!(
"hjkl_tts_noop_{}.txt",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let original = "clean\nlines\nonly\n";
let mut f = std::fs::File::create(&path).unwrap();
f.write_all(original.as_bytes()).unwrap();
drop(f);
let mut app = App::new(Some(path.clone()), false, None, None).unwrap();
app.active_editor_mut()
.settings_mut()
.trim_trailing_whitespace = true;
app.dispatch_ex("write");
let on_disk = std::fs::read_to_string(&path).unwrap();
assert!(
on_disk.contains("clean"),
"clean content must be preserved; got: {on_disk:?}"
);
let _ = std::fs::remove_file(&path);
}
#[test]
fn save_writes_unformatted_when_no_formatter_for_path() {
use std::io::Write;
let path = tmp_path(&format!(
"hjkl_fos_noext_{}.xyz",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let mut f = std::fs::File::create(&path).unwrap();
f.write_all(b"some content\n").unwrap();
drop(f);
let mut app = App::new(Some(path.clone()), false, None, None).unwrap();
app.active_editor_mut().settings_mut().format_on_save = true;
app.dispatch_ex("write");
let msg = app.bus.last_body_or_empty().to_string();
assert!(
!msg.to_lowercase().contains("error") && !msg.to_lowercase().contains("abort"),
"save with no formatter must succeed; got status: {msg:?}"
);
assert!(
path.exists(),
"file must be written when no formatter matches"
);
let _ = std::fs::remove_file(&path);
}
#[test]
fn set_fos_alias_enables_format_on_save_via_ex() {
let mut app = App::new(None, false, None, None).unwrap();
app.dispatch_ex("set nofos");
assert!(
!app.active_editor().settings().format_on_save,
":set nofos must disable format_on_save"
);
app.dispatch_ex("set fos");
assert!(
app.active_editor().settings().format_on_save,
":set fos must enable format_on_save"
);
}
#[test]
fn set_tts_alias_enables_trim_trailing_whitespace_via_ex() {
let mut app = App::new(None, false, None, None).unwrap();
assert!(
!app.active_editor().settings().trim_trailing_whitespace,
"trim_trailing_whitespace must start false"
);
app.dispatch_ex("set tts");
assert!(
app.active_editor().settings().trim_trailing_whitespace,
":set tts must enable trim_trailing_whitespace"
);
}
#[test]
fn set_nofos_disables_format_on_save_via_ex() {
let mut app = App::new(None, false, None, None).unwrap();
app.active_editor_mut().settings_mut().format_on_save = true;
app.dispatch_ex("set nofos");
assert!(
!app.active_editor().settings().format_on_save,
":set nofos must disable format_on_save"
);
}
#[test]
fn set_notts_disables_trim_trailing_whitespace_via_ex() {
let mut app = App::new(None, false, None, None).unwrap();
app.active_editor_mut()
.settings_mut()
.trim_trailing_whitespace = true;
app.dispatch_ex("set notts");
assert!(
!app.active_editor().settings().trim_trailing_whitespace,
":set notts must disable trim_trailing_whitespace"
);
}
#[test]
fn save_fos_missing_tool_warns_but_does_not_abort() {
use std::io::Write;
let path = tmp_path(&format!(
"hjkl_fos_notool_{}.xyz",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let mut f = std::fs::File::create(&path).unwrap();
f.write_all(b"data\n").unwrap();
drop(f);
let mut app = App::new(Some(path.clone()), false, None, None).unwrap();
app.active_editor_mut().settings_mut().format_on_save = true;
app.dispatch_ex("write");
assert!(
path.exists(),
"file must be written when formatter is missing"
);
let _ = std::fs::remove_file(&path);
}