@@ -51,7 +51,7 @@ fn test_random_edits(mut rng: StdRng) {
);
for _i in 0..operations {
- let (old_ranges, new_text, _) = buffer.randomly_edit(&mut rng, 1);
+ let (old_ranges, new_text, _) = buffer.randomly_edit(&mut rng, 5);
for old_range in old_ranges.iter().rev() {
reference_string.replace_range(old_range.clone(), &new_text);
}
@@ -78,26 +78,7 @@ fn test_random_edits(mut rng: StdRng) {
TextSummary::from(&reference_string[range])
);
- // Ensure every fragment is ordered by locator in the fragment tree and corresponds
- // to an insertion fragment in the insertions tree.
- let mut prev_fragment_id = Locator::min();
- for fragment in buffer.snapshot.fragments.items(&None) {
- assert!(fragment.id > prev_fragment_id);
- prev_fragment_id = fragment.id.clone();
-
- let insertion_fragment = buffer
- .snapshot
- .insertions
- .get(
- &InsertionFragmentKey {
- timestamp: fragment.insertion_timestamp,
- split_offset: fragment.insertion_offset,
- },
- &(),
- )
- .unwrap();
- assert_eq!(insertion_fragment.fragment_id, fragment.id);
- }
+ buffer.check_invariants();
if rng.gen_bool(0.3) {
buffer_versions.push((buffer.clone(), buffer.subscribe()));
@@ -639,6 +620,37 @@ struct Network<T: Clone, R: rand::Rng> {
rng: R,
}
+impl Buffer {
+ fn check_invariants(&self) {
+ // Ensure every fragment is ordered by locator in the fragment tree and corresponds
+ // to an insertion fragment in the insertions tree.
+ let mut prev_fragment_id = Locator::min();
+ for fragment in self.snapshot.fragments.items(&None) {
+ assert!(fragment.id > prev_fragment_id);
+ prev_fragment_id = fragment.id.clone();
+
+ let insertion_fragment = self
+ .snapshot
+ .insertions
+ .get(
+ &InsertionFragmentKey {
+ timestamp: fragment.insertion_timestamp,
+ split_offset: fragment.insertion_offset,
+ },
+ &(),
+ )
+ .unwrap();
+ assert_eq!(insertion_fragment.fragment_id, fragment.id);
+ }
+
+ let insertions = self.snapshot.insertions.items(&());
+ assert_eq!(
+ HashSet::from_iter(insertions.iter().map(|i| &i.fragment_id)).len(),
+ insertions.len()
+ );
+ }
+}
+
impl<T: Clone, R: rand::Rng> Network<T, R> {
fn new(rng: R) -> Self {
Network {
@@ -580,6 +580,7 @@ impl Buffer {
new_text: None,
};
let mut new_insertions = Vec::new();
+ let mut insertion_offset = 0;
let mut ranges = ranges
.map(|range| range.start.to_offset(&*self)..range.end.to_offset(&*self))
@@ -626,12 +627,6 @@ impl Buffer {
let mut prefix = old_fragments.item().unwrap().clone();
prefix.len = range.start - fragment_start;
prefix.insertion_offset += fragment_start - old_fragments.start().visible;
-
- // log::info!(
- // "pushing prefix between {:?} and {:?}",
- // new_fragments.summary().max_id,
- // prefix.id
- // );
prefix.id = Locator::between(&new_fragments.summary().max_id, &prefix.id);
new_insertions.push(InsertionFragment::insert_new(&prefix));
new_ropes.push_fragment(&prefix, prefix.visible);
@@ -646,15 +641,6 @@ impl Buffer {
old: fragment_start..fragment_start,
new: new_start..new_start + new_text.len(),
});
-
- // log::info!(
- // "pushing new fragment between {:?} and {:?}",
- // new_fragments.summary().max_id,
- // old_fragments
- // .item()
- // .map_or(&Locator::max(), |old_fragment| &old_fragment.id)
- // );
-
let fragment = Fragment {
id: Locator::between(
&new_fragments.summary().max_id,
@@ -663,7 +649,7 @@ impl Buffer {
.map_or(&Locator::max(), |old_fragment| &old_fragment.id),
),
insertion_timestamp: timestamp,
- insertion_offset: 0,
+ insertion_offset,
len: new_text.len(),
deletions: Default::default(),
max_undos: Default::default(),
@@ -672,6 +658,7 @@ impl Buffer {
new_insertions.push(InsertionFragment::insert_new(&fragment));
new_ropes.push_str(new_text);
new_fragments.push(fragment, &None);
+ insertion_offset += new_text.len();
}
// Advance through every fragment that intersects this range, marking the intersecting
@@ -683,6 +670,7 @@ impl Buffer {
let intersection_end = cmp::min(range.end, fragment_end);
if fragment.visible {
intersection.len = intersection_end - fragment_start;
+ intersection.insertion_offset += fragment_start - old_fragments.start().visible;
intersection.id =
Locator::between(&new_fragments.summary().max_id, &intersection.id);
intersection.deletions.insert(timestamp.local());