mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Package: a file the writer refuses is named once in the error
File › Package… put the file's path in front of every error its writer returned. A refusal from the automation write root already names the path, so the dialog's error and the status bar named the file twice, for example on Windows for a document named aux: `<path>: automation path rejected: reserved device names are not allowed: <path>`. The dialog now keeps a writer error that already contains the path as it is, and puts the path in front of one that does not, such as the desktop's "Access is denied. (os error 5)".
This commit is contained in:
@@ -129,7 +129,9 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
let later = Rc::new(Cell::new(false));
|
||||
let in_background = later.clone();
|
||||
let work = move |write: Writer| {
|
||||
let mut write = |path: &str, bytes: &[u8]| write(path, bytes).map_err(|e| EngineError::Other(format!("{path}: {e}")));
|
||||
// A writer error that already names the file (an automation root's refusal) is kept as it is.
|
||||
let mut write =
|
||||
|path: &str, bytes: &[u8]| write(path, bytes).map_err(|e| EngineError::Other(if e.contains(path) { e } else { format!("{path}: {e}") }));
|
||||
package.write(&mut write).map_err(|e| e.to_string())
|
||||
};
|
||||
let r = background::run(app, enabled, label, None, work, move |app, r| packaged(app, r, web, in_background.get()))?;
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::sync::Arc;
|
||||
|
||||
use serde_json::json;
|
||||
use vectorcraft_engine::Session;
|
||||
use vectorcraft_engine::file_access::{Access, AutomationRoots};
|
||||
|
||||
use super::*;
|
||||
use crate::background;
|
||||
@@ -298,6 +299,33 @@ fn package_status_without_notes_has_no_extra_spaces() {
|
||||
assert!(!detail.contains(" ."), "{detail}");
|
||||
}
|
||||
|
||||
/// A file the writer refuses is named once in the status bar: a refusal from the automation-root
|
||||
/// check already names the path, and an error without it gets the path in front.
|
||||
#[test]
|
||||
fn a_refused_file_is_named_once() {
|
||||
let dir = Folder::new("refused");
|
||||
let mut app = saved(&dir);
|
||||
app.session.execute("prefs.set", &json!({"values": {"backgroundExport": false}})).unwrap();
|
||||
let (out, elsewhere, other) = (dir.path("out"), dir.path("elsewhere"), dir.path("other"));
|
||||
std::fs::create_dir_all(&elsewhere).unwrap();
|
||||
std::fs::create_dir_all(&other).unwrap();
|
||||
let doc = std::path::Path::new(&out).join("card Folder").join("card.vectorcraft").to_string_lossy().into_owned();
|
||||
let (elsewhere, other) = (std::path::Path::new(&elsewhere), std::path::Path::new(&other));
|
||||
for write_roots in [vec![elsewhere], vec![elsewhere, other]] {
|
||||
let roots = AutomationRoots::new(&[], &write_roots).unwrap().unwrap();
|
||||
let refused = roots.check(&doc, Access::Write).unwrap_err();
|
||||
assert!(refused.ends_with(&doc), "{refused}");
|
||||
app.services.write = Some(Box::new(move |p: &str, _: &[u8]| roots.check(p, Access::Write)));
|
||||
package_dialog(&mut app, &out);
|
||||
assert_eq!(confirm(&mut app), Err(refused.clone()));
|
||||
assert_eq!(app.ui.status, refused);
|
||||
}
|
||||
app.services.write = Some(Box::new(|_: &str, _: &[u8]| Err("Access is denied. (os error 5)".into())));
|
||||
package_dialog(&mut app, &out);
|
||||
assert!(confirm(&mut app).is_err());
|
||||
assert_eq!(app.ui.status, format!("{doc}: Access is denied. (os error 5)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn package_without_a_location_says_so() {
|
||||
let dir = Folder::new("empty");
|
||||
|
||||
Reference in New Issue
Block a user