155 lines
5.6 KiB
Rust
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(¤t, &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(¤t, &document.snapshot()));
|
|
assert_eq!(document.past.len(), 1);
|
|
}
|