diff --git a/crates/text/src/tests.rs b/crates/text/src/tests.rs index e55f478c9f..e14baf47c1 100644 --- a/crates/text/src/tests.rs +++ b/crates/text/src/tests.rs @@ -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 { 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 Network { fn new(rng: R) -> Self { Network { diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index c9343eb7a2..fb00e4bba1 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -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());