on master help sign in
use a read only file to ensure write failure
acf9317Skyler Hawthorne
helix-term/tests/integration/commands.rs+3−1
@@ -10,10 +10,12 @@ use super::*;
10
10
11#[tokio::test]
11#[tokio::test]
12async fn test_write_quit_fail() -> anyhow::Result<()> {
12async fn test_write_quit_fail() -> anyhow::Result<()> {
13+ let file = helpers::new_readonly_tempfile()?;
14+
13 test_key_sequence(
15 test_key_sequence(
14 &mut Application::new(
16 &mut Application::new(
15 Args {
17 Args {
16− files: vec![(PathBuf::from("/foo"), Position::default())],
18+ files: vec![(file.path().to_path_buf(), Position::default())],
17 ..Default::default()
19 ..Default::default()
18 },
20 },
19 Config::default(),
21 Config::default(),
helix-term/tests/integration/helpers.rs+12
@@ -5,6 +5,7 @@ use crossterm::event::{Event, KeyEvent};
5use helix_core::{test, Selection, Transaction};
5use helix_core::{test, Selection, Transaction};
6use helix_term::{application::Application, args::Args, config::Config};
6use helix_term::{application::Application, args::Args, config::Config};
7use helix_view::{doc, input::parse_macro};
7use helix_view::{doc, input::parse_macro};
8+use tempfile::NamedTempFile;
8use tokio_stream::wrappers::UnboundedReceiverStream;
9use tokio_stream::wrappers::UnboundedReceiverStream;
9
10
10#[derive(Clone, Debug)]
11#[derive(Clone, Debug)]
@@ -155,3 +156,14 @@ pub fn platform_line(input: &str) -> String {
155
156
156 output
157 output
157}
158}
159+
160+/// Creates a new temporary file that is set to read only. Useful for
161+/// testing write failures.
162+pub fn new_readonly_tempfile() -> anyhow::Result<NamedTempFile> {
163+ let mut file = tempfile::NamedTempFile::new()?;
164+ let metadata = file.as_file().metadata()?;
165+ let mut perms = metadata.permissions();
166+ perms.set_readonly(true);
167+ file.as_file_mut().set_permissions(perms)?;
168+ Ok(file)
169+}
helix-term/tests/integration/write.rs+14−4
@@ -75,10 +75,12 @@ async fn test_write_concurrent() -> anyhow::Result<()> {
75
75
76#[tokio::test]
76#[tokio::test]
77async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
77async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
78+ let file = helpers::new_readonly_tempfile()?;
79+
78 test_key_sequences(
80 test_key_sequences(
79 &mut Application::new(
81 &mut Application::new(
80 Args {
82 Args {
81− files: vec![(PathBuf::from("/foo"), Position::default())],
83+ files: vec![(file.path().to_path_buf(), Position::default())],
82 ..Default::default()
84 ..Default::default()
83 },
85 },
84 Config::default(),
86 Config::default(),
@@ -116,6 +118,8 @@ async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
116
118
117#[tokio::test]
119#[tokio::test]
118async fn test_write_fail_new_path() -> anyhow::Result<()> {
120async fn test_write_fail_new_path() -> anyhow::Result<()> {
121+ let file = helpers::new_readonly_tempfile()?;
122+
119 test_key_sequences(
123 test_key_sequences(
120 &mut Application::new(Args::default(), Config::default())?,
124 &mut Application::new(Args::default(), Config::default())?,
121 vec![
125 vec![
@@ -123,15 +127,21 @@ async fn test_write_fail_new_path() -> anyhow::Result<()> {
123 None,
127 None,
124 Some(&|app| {
128 Some(&|app| {
125 let doc = doc!(app.editor);
129 let doc = doc!(app.editor);
130+ assert_ne!(
131+ Some(&Severity::Error),
126− assert_eq!(None, app.editor.get_status());
132+ app.editor.get_status().map(|status| status.1)
133+ );
127 assert_eq!(None, doc.path());
134 assert_eq!(None, doc.path());
128 }),
135 }),
129 ),
136 ),
130 (
137 (
131− Some(":w /foo<ret>"),
138+ Some(&format!(":w {}<ret>", file.path().to_string_lossy())),
132 Some(&|app| {
139 Some(&|app| {
133 let doc = doc!(app.editor);
140 let doc = doc!(app.editor);
141+ assert_eq!(
142+ Some(&Severity::Error),
134− assert_eq!(&Severity::Error, app.editor.get_status().unwrap().1);
143+ app.editor.get_status().map(|status| status.1)
144+ );
135 assert_eq!(None, doc.path());
145 assert_eq!(None, doc.path());
136 }),
146 }),
137 ),
147 ),