Files
vectorcraft/crates/ui-egui/src/tests_aisave.rs
T
bflatasticandClaude Opus 5.5 bf4614669e M4.38: native and .ai save options: each artboard to its own file, linked files, ICC profiles, PDF content
- document.save / Save As / Save a Copy to a native or .ai file take
  separateArtboards + range (also write <name>-<artboard>.<ext> per artboard
  beside the master file, holding that artboard and the art touching it; the
  result lists every file), includeLinked (linked images keep their files' own
  pixels), embedProfiles (ICC profiles loaded from files that the document is
  tagged with; opening installs them where missing) and pdfCompatible (native:
  also carry a PDF of every artboard; .ai: false writes blank pages around the
  native document). .ai files also take compress (compression.compressText).
- File > Save As to a native or .ai file shows the options dialog (VectorCraft
  Options) after the save panel: Save each artboard to a separate file (All or a
  range), Include Linked Files, Embed ICC Profiles, Create PDF-Compatible File,
  Use Compression, Preview; the web's Save As dialog shows them too. Save, Save a
  Copy and Save as Template reuse the options as last saved.
- Format: optional "profiles" and "pdf" members (load_file, pdf_content),
  SaveOptions.include_linked/profiles/pdf; files without them are unchanged.
- Changed test: tests_aisave::save_as_ai_writes_a_pdf_that_reopens_editable now
  confirms the options dialog Save As .ai shows before writing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 15:24:19 +07:00

44 lines
2.1 KiB
Rust

//! Save As .ai in the app: the options dialog, then a PDF-compatible file, which reopens as the
//! document and saves as .ai again (without asking); Save a Copy as .ai leaves the document's path
//! alone.
use serde_json::{Value, json};
use crate::tests_svg::app;
#[test]
fn save_as_ai_writes_a_pdf_that_reopens_editable() {
let (mut app, written) = app("/tmp/art.ai");
// Save As asks for the .ai options first (M4.38), then writes.
let r = app.run("file.saveAs", Value::Null).unwrap();
assert_eq!(r["pending"], "saveOptions", "{r}");
let d = app.ui.dialog.as_ref().unwrap();
assert_eq!((d.str("format").as_str(), d.str("path").as_str(), d.bool("pdfCompatible")), ("ai", "/tmp/art.ai", true));
let r = crate::dialogs::confirm(&mut app).unwrap();
assert_eq!(r["path"], "/tmp/art.ai", "{r}");
assert!(app.ui.dialog.is_none());
let ai = written.borrow()[0].1.clone();
assert!(ai.starts_with(b"%PDF"));
assert_eq!(app.session.active().unwrap().path.as_deref(), Some("/tmp/art.ai"));
// Save writes .ai again; the document reopens from it.
app.run("shape.ellipse", json!({"x": 50, "y": 40, "width": 20, "height": 20})).unwrap();
app.run("file.save", Value::Null).unwrap();
let saved = written.borrow()[1].clone();
assert_eq!(saved.0, "/tmp/art.ai");
let layers = app.session.doc().unwrap().doc.layers.clone();
crate::io::open_bytes(&mut app, "/tmp/art.ai", &saved.1, Some("/tmp/art.ai".into())).unwrap();
assert_eq!(app.session.doc().unwrap().doc.layers, layers);
assert_eq!(app.session.active().unwrap().path.as_deref(), Some("/tmp/art.ai"));
}
#[test]
fn save_a_copy_as_ai_keeps_the_path() {
let (mut app, written) = app("/tmp/copy.ai");
app.session.doc_mut().unwrap().path = Some("/tmp/doc.vectorcraft".into());
app.run("file.saveCopy", json!({"compression": {"compressText": false}})).unwrap();
let w = written.borrow();
assert_eq!(w[0].0, "/tmp/copy.ai");
assert!(vectorcraft_pdf::editing(&w[0].1).is_some_and(|e| e.intact));
assert_eq!(app.session.active().unwrap().path.as_deref(), Some("/tmp/doc.vectorcraft"));
}