use super::*;
use crate::code::text::{Position, Range};
fn insert(line: u32, character: u32, text: &str) -> Change {
let p = Position { line, character };
Change { range: Some(Range { start: p, end: p }), text: text.to_owned() }
}
#[test]
fn test20076_the_server_copy_follows_the_page_that_asks() {
let mut r = Registry::default();
assert_eq!(
r.open("a", "f.py", "python", 1, "x = 1\n"),
vec![Outgoing::Open { path: "f.py".into(), language_id: "python".into(), version: 1, text: "x = 1\n".into() }]
);
assert_eq!(r.open("b", "f.py", "python", 1, "x = 1\n"), vec![]);
assert_eq!(
r.change("b", "f.py", 1, 2, &[insert(0, 0, "#")]).unwrap(),
vec![Outgoing::Edit { path: "f.py".into(), version: 2, changes: vec![insert(0, 0, "#")] }],
"the owner's edit goes as it was made"
);
assert_eq!(
r.change("a", "f.py", 1, 2, &[insert(0, 0, "!")]).unwrap(),
vec![Outgoing::Replace { path: "f.py".into(), version: 3, text: "!x = 1\n".into() }]
);
assert_eq!(
r.change("b", "f.py", 2, 3, &[insert(0, 1, "?")]).unwrap(),
vec![Outgoing::Replace { path: "f.py".into(), version: 4, text: "#?x = 1\n".into() }]
);
assert_eq!(r.server_copy("f.py"), Some((4, "#?x = 1\n")));
assert_eq!(
r.ensure("a", "f.py", 2).unwrap(),
vec![Outgoing::Replace { path: "f.py".into(), version: 5, text: "!x = 1\n".into() }]
);
assert_eq!(r.ensure("a", "f.py", 2).unwrap(), vec![], "asking again moves nothing");
}
#[test]
fn test20077_stale_questions_and_gapped_edits_are_refused() {
let mut r = Registry::default();
r.open("a", "f.go", "go", 5, "package f\n");
assert_eq!(r.ensure("a", "f.go", 4), Err(SyncError::Stale { path: "f.go".into(), have: 5, asked: 4 }));
assert_eq!(
r.change("a", "f.go", 3, 4, &[insert(0, 0, "x")]),
Err(SyncError::Gap { path: "f.go".into(), have: 5, from: 3 })
);
let invalid = r.change("a", "f.go", 5, 6, &[insert(9, 0, "x")]).unwrap_err();
assert!(matches!(invalid, SyncError::Invalid { .. }), "{invalid:?}");
assert_eq!(r.server_copy("f.go"), Some((1, "package f\n")), "a refused edit changed the server's copy");
assert_eq!(r.ensure("a", "f.go", 5).unwrap(), vec![], "a refused edit moved the page's version");
assert_eq!(r.ensure("z", "f.go", 1), Err(SyncError::NotOpen { path: "f.go".into() }));
}
#[test]
fn test20078_closing_hands_the_file_to_a_page_that_has_it() {
let mut r = Registry::default();
r.open("a", "f.rs", "rust", 1, "fn a() {}\n");
r.open("b", "f.rs", "rust", 1, "fn a() {}\n");
r.open("a", "g.rs", "rust", 1, "fn g() {}\n");
r.change("b", "f.rs", 1, 2, &[insert(0, 0, "//\n")]).unwrap();
r.change("a", "f.rs", 1, 2, &[insert(0, 0, "#[test]\n")]).unwrap();
assert_eq!(
r.close("a", "f.rs"),
vec![Outgoing::Replace { path: "f.rs".into(), version: 4, text: "//\nfn a() {}\n".into() }]
);
assert_eq!(r.close_client("a"), vec![Outgoing::Close { path: "g.rs".into() }]);
assert_eq!(r.replay(), vec![Outgoing::Open {
path: "f.rs".into(),
language_id: "rust".into(),
version: 4,
text: "//\nfn a() {}\n".into()
}]);
assert_eq!(r.close("b", "f.rs"), vec![Outgoing::Close { path: "f.rs".into() }]);
assert!(r.is_empty());
}