summaryrefslogtreecommitdiff
path: root/helix-term/tests/test
diff options
context:
space:
mode:
authorClément Delafargue2023-02-08 16:09:19 +0000
committerGitHub2023-02-08 16:09:19 +0000
commitf386ff795d4833cce02d57de921999284aadded3 (patch)
tree363078f7197e71ffc1aeedc27919e1076957a4f1 /helix-term/tests/test
parent00ecc556a8d3f7efe115f3d826c916ffacf6ab2e (diff)
Check for external file modifications when writing (#5805)
`:write` and other file-saving commands now check the file modification time before writing to protect against overwriting external changes. Co-authored-by: Gustavo Noronha Silva <gustavo@noronha.dev.br> Co-authored-by: LeoniePhiline <22329650+LeoniePhiline@users.noreply.github.com> Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
Diffstat (limited to 'helix-term/tests/test')
-rw-r--r--helix-term/tests/test/commands.rs2
-rw-r--r--helix-term/tests/test/helpers.rs6
-rw-r--r--helix-term/tests/test/write.rs36
3 files changed, 41 insertions, 3 deletions
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index da2e020e..2ca9e395 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -67,7 +67,7 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
const RANGE: RangeInclusive<i32> = 1..=1000;
for i in RANGE {
- let cmd = format!("%c{}<esc>:w<ret>", i);
+ let cmd = format!("%c{}<esc>:w!<ret>", i);
command.push_str(&cmd);
}
diff --git a/helix-term/tests/test/helpers.rs b/helix-term/tests/test/helpers.rs
index 8755b60f..fb12ef12 100644
--- a/helix-term/tests/test/helpers.rs
+++ b/helix-term/tests/test/helpers.rs
@@ -319,6 +319,12 @@ impl AppBuilder {
}
}
+pub async fn run_event_loop_until_idle(app: &mut Application) {
+ let (_, rx) = tokio::sync::mpsc::unbounded_channel();
+ let mut rx_stream = UnboundedReceiverStream::new(rx);
+ app.event_loop_until_idle(&mut rx_stream).await;
+}
+
pub fn assert_file_has_content(file: &mut File, content: &str) -> anyhow::Result<()> {
file.flush()?;
file.sync_all()?;
diff --git a/helix-term/tests/test/write.rs b/helix-term/tests/test/write.rs
index bbf14fc2..81459b2f 100644
--- a/helix-term/tests/test/write.rs
+++ b/helix-term/tests/test/write.rs
@@ -1,5 +1,5 @@
use std::{
- io::{Read, Write},
+ io::{Read, Seek, SeekFrom, Write},
ops::RangeInclusive,
};
@@ -38,6 +38,38 @@ async fn test_write() -> anyhow::Result<()> {
}
#[tokio::test(flavor = "multi_thread")]
+async fn test_overwrite_protection() -> anyhow::Result<()> {
+ let mut file = tempfile::NamedTempFile::new()?;
+ let mut app = helpers::AppBuilder::new()
+ .with_file(file.path(), None)
+ .build()?;
+
+ helpers::run_event_loop_until_idle(&mut app).await;
+
+ file.as_file_mut()
+ .write_all(helpers::platform_line("extremely important content").as_bytes())?;
+
+ file.as_file_mut().flush()?;
+ file.as_file_mut().sync_all()?;
+
+ test_key_sequence(&mut app, Some(":x<ret>"), None, false).await?;
+
+ file.as_file_mut().flush()?;
+ file.as_file_mut().sync_all()?;
+
+ file.seek(SeekFrom::Start(0))?;
+ let mut file_content = String::new();
+ file.as_file_mut().read_to_string(&mut file_content)?;
+
+ assert_eq!(
+ helpers::platform_line("extremely important content"),
+ file_content
+ );
+
+ Ok(())
+}
+
+#[tokio::test(flavor = "multi_thread")]
async fn test_write_quit() -> anyhow::Result<()> {
let mut file = tempfile::NamedTempFile::new()?;
let mut app = helpers::AppBuilder::new()
@@ -76,7 +108,7 @@ async fn test_write_concurrent() -> anyhow::Result<()> {
.build()?;
for i in RANGE {
- let cmd = format!("%c{}<esc>:w<ret>", i);
+ let cmd = format!("%c{}<esc>:w!<ret>", i);
command.push_str(&cmd);
}