use super::*; fn complete_save(app: &mut App, path: PathBuf) { let receipt = write_snapshot( app.canvas_document, app.document.revision(), app.document.snapshot(), path, app.disk_project.clone(), ) .unwrap(); let _ = app.update(Message::Saved(Ok(Some(receipt)))); } #[test] fn save_as_receipt_then_one_undo_restores_meaning_and_saving_preserves_redo() { let directory = tempfile::tempdir().unwrap(); let path = directory.path().join("semantic-accepted.arcadia"); let mut app = App::with_project(Project::empty()); app.document.mark_recovered(); let original = app.document.bundle().files[&app.document.bundle().entry].clone(); app.execute(Command::Rename( app.project().id, "Accepted semantic change".into(), )); let after = app.document.bundle().files[&app.document.bundle().entry].clone(); complete_save(&mut app, path.clone()); assert!(!app.dirty()); assert_eq!(app.path.as_ref(), Some(&path)); assert_eq!(std::fs::read_to_string(&path).unwrap(), after); let _ = app.update(Message::Undo); assert_eq!(app.document.bundle().entry, "semantic-accepted.arcadia"); assert_eq!( app.document.bundle().files[&app.document.bundle().entry], original ); assert!( !app.document.can_undo(), "Save as did not insert a history step" ); assert!(app.document.can_redo()); complete_save(&mut app, path.clone()); assert_eq!(std::fs::read_to_string(&path).unwrap(), original); assert!( app.document.can_redo(), "Saving an undone state preserves the future" ); let _ = app.update(Message::Redo); assert_eq!( app.document.bundle().files[&app.document.bundle().entry], after ); assert!(app.dirty()); assert_eq!( source_project::compile_bundle(app.document.bundle(), LIMITS) .unwrap() .decoded .project, *app.project() ); } #[test] fn save_as_preflight_rejects_historical_collision_before_starting_io() { let directory = tempfile::tempdir().unwrap(); let path = directory.path().join("taken.arcadia"); let mut app = App::with_project(Project::empty()); let base = app.document.bundle().clone(); let mut included = base.clone(); let text = included.files.get_mut(&included.entry).unwrap(); text.insert_str(text.rfind('}').unwrap(), "\n include \"taken.arcadia\";\n"); included .files .insert("taken.arcadia".into(), "// retained\n".into()); app.document.apply_bundle(included).unwrap(); app.document.apply_bundle(base).unwrap(); app.sync_source(); let before = app.document.snapshot(); let task = app.save_to(path.clone()); assert!(iced_runtime::task::into_stream(task).is_none()); assert!(!path.exists()); assert!(!app.busy); assert!(app.status.contains("Undo/Redo")); assert!(Arc::ptr_eq(&before, &app.document.snapshot())); let json = app.save_to(directory.path().join("taken.json")); assert!( iced_runtime::task::into_stream(json).is_some(), "JSON exports do not relocate source entries" ); } #[test] fn save_as_late_receipt_preserves_newer_raw_source_draft_and_destination() { let directory = tempfile::tempdir().unwrap(); let mut app = App::with_project(Project::empty()); let entry = app.document.bundle().entry.clone(); let receipt = write_snapshot( app.canvas_document, app.document.revision(), app.document.snapshot(), directory.path().join("accepted.arcadia"), None, ) .unwrap(); let raw = format!("{}\nunfinished {{", app.source_workspace.text()); let cursor = app.source_workspace.files[&entry].cursor; app.source_workspace.edit(raw.clone(), cursor); let _ = app.update(Message::Saved(Ok(Some(receipt)))); assert_eq!(app.source_workspace.text(), raw); assert_eq!(app.document.bundle().entry, entry); assert!(app.path.is_none()); assert!(app.dirty()); assert!(app.status.contains("Newer edits")); }