Files
ARCADIA-Studio/crates/oa-desktop/src/document_save_as_tests.rs
T

155 lines
5.6 KiB
Rust

use super::*;
fn renamed(bundle: &SourceBundle, entry: &str) -> SourceBundle {
let mut out = bundle.clone();
let text = out.files.remove(&out.entry).unwrap();
out.entry = entry.into();
out.files.insert(entry.into(), text);
out
}
fn saved(document: &Document, entry: &str) -> CompiledSourceProject {
source_project::compile_bundle(&renamed(document.bundle(), entry), document.limits).unwrap()
}
#[test]
fn save_as_rebases_uniform_history_without_an_undo_step_or_lost_redo() {
let mut document = Document::from_project(Project::empty(), ProjectLimits::default()).unwrap();
let original = document.bundle().clone();
let mut comments = original.clone();
comments
.files
.get_mut(&comments.entry)
.unwrap()
.push_str("\r\n// exact rationale\r\n");
document.apply_bundle(comments.clone()).unwrap();
document
.execute(Command::Rename(
document.project().id,
"Engineering choice".into(),
))
.unwrap();
let future = document.bundle().clone();
document.undo();
let counts = (document.past.len(), document.future.len());
let receipt = saved(&document, "accepted.arcadia");
document.check_save_entry("accepted.arcadia").unwrap();
document
.adopt_saved_entry(&receipt, document.revision())
.unwrap();
document.mark_saved(Arc::new(receipt));
assert_eq!((document.past.len(), document.future.len()), counts);
assert!(!document.dirty());
assert!(document.undo());
assert_eq!(document.bundle(), &renamed(&original, "accepted.arcadia"));
assert!(document.redo());
assert_eq!(document.bundle(), &renamed(&comments, "accepted.arcadia"));
assert!(!document.dirty());
assert!(document.redo());
assert_eq!(document.bundle(), &renamed(&future, "accepted.arcadia"));
assert!(document.dirty());
let checked = source_project::compile_bundle(document.bundle(), document.limits).unwrap();
assert_eq!(document.compiled().index, checked.index);
assert_eq!(document.project(), &checked.decoded.project);
}
#[test]
fn save_as_preserves_explicit_source_entry_changes_in_history() {
let mut document = Document::from_project(Project::empty(), ProjectLimits::default()).unwrap();
let original = document.bundle().clone();
let authored = renamed(&original, "authored.arcadia");
document.apply_bundle(authored.clone()).unwrap();
document
.execute(Command::Rename(
document.project().id,
"Later meaning".into(),
))
.unwrap();
let receipt = saved(&document, "accepted.arcadia");
document
.adopt_saved_entry(&receipt, document.revision())
.unwrap();
assert_eq!(document.past.len(), 2);
assert!(document.undo());
assert_eq!(document.bundle(), &authored);
assert!(document.undo());
assert_eq!(document.bundle(), &original);
assert!(document.redo());
assert_eq!(document.bundle(), &authored);
assert!(document.redo());
assert_eq!(document.bundle(), &receipt.bundle);
}
#[test]
fn save_as_rejects_included_filename_collisions_in_past_and_future_without_mutation() {
for collision_in_future in [false, true] {
let base = source_project::format_bundle(&Project::empty());
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 engineering rationale\n".into(),
);
let mut document = if collision_in_future {
let mut d = Document::from_bundle(base, ProjectLimits::default()).unwrap();
d.apply_bundle(included).unwrap();
d.undo();
d
} else {
let mut d = Document::from_bundle(included, ProjectLimits::default()).unwrap();
d.apply_bundle(base).unwrap();
d
};
let current = document.snapshot();
let revision = document.revision();
let counts = (document.past.len(), document.future.len());
assert!(
document
.check_save_entry("taken.arcadia")
.unwrap_err()
.to_string()
.contains("Undo/Redo")
);
let receipt = saved(&document, "taken.arcadia");
assert!(document.adopt_saved_entry(&receipt, revision).is_err());
assert!(Arc::ptr_eq(&current, &document.snapshot()));
assert_eq!(document.revision(), revision);
assert_eq!((document.past.len(), document.future.len()), counts);
}
}
#[test]
fn save_as_rejects_stale_or_content_changing_receipt_atomically() {
let mut document = Document::from_project(Project::empty(), ProjectLimits::default()).unwrap();
let mut receipt = saved(&document, "accepted.arcadia");
let revision = document.revision();
document
.execute(Command::Rename(
document.project().id,
"Newer meaning".into(),
))
.unwrap();
let current = document.snapshot();
assert!(document.adopt_saved_entry(&receipt, revision).is_err());
assert!(
document
.adopt_saved_entry(&receipt, document.revision())
.is_err()
);
receipt = saved(&document, "accepted.arcadia");
receipt
.bundle
.files
.get_mut(&receipt.bundle.entry)
.unwrap()
.push_str("// unsaved receipt text\n");
assert!(
document
.adopt_saved_entry(&receipt, document.revision())
.is_err()
);
assert!(Arc::ptr_eq(&current, &document.snapshot()));
assert_eq!(document.past.len(), 1);
}