66 lines
2.0 KiB
Rust
66 lines
2.0 KiB
Rust
#[macro_use]
|
|
extern crate proptest;
|
|
|
|
use proptest::collection::vec;
|
|
use proptest::test_runner::Config;
|
|
|
|
use ropey::Rope;
|
|
|
|
use backend::change::Change;
|
|
|
|
fn make_edit_list_valid(edits: &mut Vec<(usize, usize, String)>, start_text: &str) {
|
|
edits.sort_by_key(|e| e.0);
|
|
let mut tail = 0;
|
|
for e in edits.iter_mut() {
|
|
e.0 = e.0.max(tail);
|
|
while e.0 < start_text.len() && !start_text.is_char_boundary(e.0) {
|
|
e.0 += 1;
|
|
}
|
|
while (e.0 + e.1) < start_text.len() && !start_text.is_char_boundary(e.0 + e.1) {
|
|
e.1 += 1;
|
|
}
|
|
tail = e.0 + e.1;
|
|
}
|
|
for i in (0..edits.len()).rev() {
|
|
if edits[i].0 > start_text.len() {
|
|
edits.remove(i);
|
|
} else if (edits[i].0 + edits[i].1) > start_text.len() {
|
|
edits[i].1 = start_text.len() - edits[i].0;
|
|
}
|
|
}
|
|
}
|
|
|
|
proptest! {
|
|
#![proptest_config(Config::with_cases(512))]
|
|
|
|
#[test]
|
|
fn compose(
|
|
ref start_text in "\\PC{0, 200}",
|
|
mut edits1 in vec((0usize..100, 0usize..10, "\\PC{0, 10}"), 0..5),
|
|
mut edits2 in vec((0usize..100, 0usize..10, "\\PC{0, 10}"), 0..5),
|
|
) {
|
|
// Make edits1 valid and compute the post-edits1 string.
|
|
make_edit_list_valid(&mut edits1, start_text);
|
|
let change1 = Change::from_ordered_edit_set(edits1.iter().map(|e| {
|
|
(e.0, &start_text[e.0..(e.0+e.1)], &e.2[..])
|
|
}));
|
|
let mut r1 = Rope::from_str(start_text);
|
|
change1.apply(&mut r1);
|
|
let text1: String = r1.clone().into();
|
|
|
|
// Make edits2 valid and compute the post-edits2 string.
|
|
make_edit_list_valid(&mut edits2, &text1);
|
|
let change2 = Change::from_ordered_edit_set(edits2.iter().map(|e| {
|
|
(e.0, &text1[e.0..(e.0+e.1)], &e.2[..])
|
|
}));
|
|
change2.apply(&mut r1);
|
|
|
|
// Do the test!
|
|
let change3 = change1.compose(&change2);
|
|
let mut r2 = Rope::from_str(start_text);
|
|
change3.apply(&mut r2);
|
|
|
|
assert_eq!(r1, r2);
|
|
}
|
|
}
|