mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-26 03:59:55 +00:00
WIP: Track down bugs with longest_row on wrap map
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
c5956a0363
commit
213aa36e1c
5 changed files with 216 additions and 25 deletions
|
@ -767,7 +767,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::random_char_iter::RandomCharIter;
|
use crate::random_char_iter::RandomCharIter;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use std::env;
|
use std::{cmp::Ordering, env};
|
||||||
use Bias::{Left, Right};
|
use Bias::{Left, Right};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -814,7 +814,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
fn test_random(mut rng: StdRng) {
|
fn test_random_rope(mut rng: StdRng) {
|
||||||
let operations = env::var("OPERATIONS")
|
let operations = env::var("OPERATIONS")
|
||||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||||
.unwrap_or(10);
|
.unwrap_or(10);
|
||||||
|
@ -898,6 +898,38 @@ mod tests {
|
||||||
TextSummary::from(&expected[start_ix..end_ix])
|
TextSummary::from(&expected[start_ix..end_ix])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut expected_longest_rows = Vec::new();
|
||||||
|
let mut longest_line_len = -1_isize;
|
||||||
|
for (row, line) in expected.split('\n').enumerate() {
|
||||||
|
let row = row as u32;
|
||||||
|
assert_eq!(
|
||||||
|
actual.line_len(row),
|
||||||
|
line.len() as u32,
|
||||||
|
"invalid line len for row {}",
|
||||||
|
row
|
||||||
|
);
|
||||||
|
|
||||||
|
let line_char_count = line.chars().count() as isize;
|
||||||
|
match line_char_count.cmp(&longest_line_len) {
|
||||||
|
Ordering::Less => {}
|
||||||
|
Ordering::Equal => expected_longest_rows.push(row),
|
||||||
|
Ordering::Greater => {
|
||||||
|
longest_line_len = line_char_count;
|
||||||
|
expected_longest_rows.clear();
|
||||||
|
expected_longest_rows.push(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let longest_row = actual.summary().longest_row;
|
||||||
|
assert!(
|
||||||
|
expected_longest_rows.contains(&longest_row),
|
||||||
|
"incorrect longest row {}. expected {:?} with length {}",
|
||||||
|
longest_row,
|
||||||
|
expected_longest_rows,
|
||||||
|
longest_line_len,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1330,23 +1330,26 @@ mod tests {
|
||||||
row
|
row
|
||||||
);
|
);
|
||||||
|
|
||||||
match (line.len() as isize).cmp(&longest_line_len) {
|
let line_char_count = line.chars().count() as isize;
|
||||||
|
match line_char_count.cmp(&longest_line_len) {
|
||||||
Ordering::Less => {}
|
Ordering::Less => {}
|
||||||
Ordering::Equal => expected_longest_rows.push(row),
|
Ordering::Equal => expected_longest_rows.push(row),
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
longest_line_len = line.len() as isize;
|
longest_line_len = line_char_count;
|
||||||
expected_longest_rows.clear();
|
expected_longest_rows.clear();
|
||||||
expected_longest_rows.push(row);
|
expected_longest_rows.push(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("getting longest row >>>>>>>>>>>>>>>>>>>>>>>>");
|
||||||
let longest_row = blocks_snapshot.longest_row();
|
let longest_row = blocks_snapshot.longest_row();
|
||||||
assert!(
|
assert!(
|
||||||
expected_longest_rows.contains(&longest_row),
|
expected_longest_rows.contains(&longest_row),
|
||||||
"incorrect longest row {}. expected {:?}",
|
"incorrect longest row {}. expected {:?} with length {}",
|
||||||
longest_row,
|
longest_row,
|
||||||
expected_longest_rows,
|
expected_longest_rows,
|
||||||
|
longest_line_len,
|
||||||
);
|
);
|
||||||
|
|
||||||
for row in 0..=blocks_snapshot.wrap_snapshot.max_point().row() {
|
for row in 0..=blocks_snapshot.wrap_snapshot.max_point().row() {
|
||||||
|
|
|
@ -110,34 +110,31 @@ impl Snapshot {
|
||||||
.text_summary_for_range(input_start..input_end);
|
.text_summary_for_range(input_start..input_end);
|
||||||
|
|
||||||
let mut first_line_chars = 0;
|
let mut first_line_chars = 0;
|
||||||
let mut first_line_bytes = 0;
|
let line_end = if range.start.row() == range.end.row() {
|
||||||
|
range.end
|
||||||
|
} else {
|
||||||
|
self.max_point()
|
||||||
|
};
|
||||||
for c in self
|
for c in self
|
||||||
.chunks(range.start..self.max_point(), false)
|
.chunks(range.start..line_end, false)
|
||||||
.flat_map(|chunk| chunk.text.chars())
|
.flat_map(|chunk| chunk.text.chars())
|
||||||
{
|
{
|
||||||
if c == '\n'
|
if c == '\n' {
|
||||||
|| (range.start.row() == range.end.row() && first_line_bytes == range.end.column())
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
first_line_chars += 1;
|
first_line_chars += 1;
|
||||||
first_line_bytes += c.len_utf8() as u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut last_line_chars = 0;
|
let mut last_line_chars = 0;
|
||||||
let mut last_line_bytes = 0;
|
if range.start.row() == range.end.row() {
|
||||||
for c in self
|
last_line_chars = first_line_chars;
|
||||||
.chunks(
|
} else {
|
||||||
TabPoint::new(range.end.row(), 0).max(range.start)..self.max_point(),
|
for _ in self
|
||||||
false,
|
.chunks(TabPoint::new(range.end.row(), 0)..self.max_point(), false)
|
||||||
)
|
.flat_map(|chunk| chunk.text.chars())
|
||||||
.flat_map(|chunk| chunk.text.chars())
|
{
|
||||||
{
|
last_line_chars += 1;
|
||||||
if last_line_bytes == range.end.column() {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
last_line_chars += 1;
|
|
||||||
last_line_bytes += c.len_utf8() as u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSummary {
|
TextSummary {
|
||||||
|
@ -427,6 +424,12 @@ impl<'a> Iterator for Chunks<'a> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use buffer::RandomCharIter;
|
||||||
|
use language::Buffer;
|
||||||
|
use rand::{prelude::StdRng, Rng};
|
||||||
|
|
||||||
|
use crate::display_map::fold_map::FoldMap;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -435,4 +438,19 @@ mod tests {
|
||||||
assert_eq!(Snapshot::expand_tabs("\t".chars(), 1, 4), 4);
|
assert_eq!(Snapshot::expand_tabs("\t".chars(), 1, 4), 4);
|
||||||
assert_eq!(Snapshot::expand_tabs("\ta".chars(), 2, 4), 5);
|
assert_eq!(Snapshot::expand_tabs("\ta".chars(), 2, 4), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test(iterations = 100)]
|
||||||
|
fn test_text_summary_for_range(cx: &mut gpui::MutableAppContext, mut rng: StdRng) {
|
||||||
|
let tab_size = rng.gen_range(1..=4);
|
||||||
|
let buffer = cx.add_model(|cx| {
|
||||||
|
let len = rng.gen_range(0..30);
|
||||||
|
let text = RandomCharIter::new(&mut rng).take(len).collect::<String>();
|
||||||
|
Buffer::new(0, text, cx)
|
||||||
|
});
|
||||||
|
let (_, folds_snapshot) = FoldMap::new(buffer.clone(), cx);
|
||||||
|
let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size);
|
||||||
|
|
||||||
|
println!("{:?}", tabs_snapshot.text());
|
||||||
|
// TODO: Test text_summary_for_range with random ranges
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,11 +299,20 @@ impl Snapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interpolate(&mut self, new_tab_snapshot: TabSnapshot, tab_edits: &[TabEdit]) -> Patch {
|
fn interpolate(&mut self, new_tab_snapshot: TabSnapshot, tab_edits: &[TabEdit]) -> Patch {
|
||||||
|
log::info!("INTERPOLATING");
|
||||||
|
|
||||||
|
log::info!("updating transforms... old transforms are:");
|
||||||
|
for transform in self.transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
|
|
||||||
let mut new_transforms;
|
let mut new_transforms;
|
||||||
if tab_edits.is_empty() {
|
if tab_edits.is_empty() {
|
||||||
new_transforms = self.transforms.clone();
|
new_transforms = self.transforms.clone();
|
||||||
} else {
|
} else {
|
||||||
let mut old_cursor = self.transforms.cursor::<TabPoint>();
|
let mut old_cursor = self.transforms.cursor::<TabPoint>();
|
||||||
|
|
||||||
let mut tab_edits_iter = tab_edits.iter().peekable();
|
let mut tab_edits_iter = tab_edits.iter().peekable();
|
||||||
new_transforms = old_cursor.slice(
|
new_transforms = old_cursor.slice(
|
||||||
&tab_edits_iter.peek().unwrap().old_lines.start,
|
&tab_edits_iter.peek().unwrap().old_lines.start,
|
||||||
|
@ -311,12 +320,26 @@ impl Snapshot {
|
||||||
&(),
|
&(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
log::info!("sliced, new_transforms are:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(edit) = tab_edits_iter.next() {
|
while let Some(edit) = tab_edits_iter.next() {
|
||||||
|
log::info!("processing edit {:?}", edit);
|
||||||
|
|
||||||
if edit.new_lines.start > TabPoint::from(new_transforms.summary().input.lines) {
|
if edit.new_lines.start > TabPoint::from(new_transforms.summary().input.lines) {
|
||||||
let summary = new_tab_snapshot.text_summary_for_range(
|
let summary = new_tab_snapshot.text_summary_for_range(
|
||||||
TabPoint::from(new_transforms.summary().input.lines)..edit.new_lines.start,
|
TabPoint::from(new_transforms.summary().input.lines)..edit.new_lines.start,
|
||||||
);
|
);
|
||||||
|
log::info!("pushing prefix before edit: {:?}", summary);
|
||||||
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
||||||
|
log::info!("new transforms are now:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !edit.new_lines.is_empty() {
|
if !edit.new_lines.is_empty() {
|
||||||
|
@ -325,6 +348,12 @@ impl Snapshot {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("pushed summary within edit new range; new transforms now:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
|
|
||||||
old_cursor.seek_forward(&edit.old_lines.end, Bias::Right, &());
|
old_cursor.seek_forward(&edit.old_lines.end, Bias::Right, &());
|
||||||
if let Some(next_edit) = tab_edits_iter.peek() {
|
if let Some(next_edit) = tab_edits_iter.peek() {
|
||||||
if next_edit.old_lines.start > old_cursor.end(&()) {
|
if next_edit.old_lines.start > old_cursor.end(&()) {
|
||||||
|
@ -334,21 +363,46 @@ impl Snapshot {
|
||||||
.text_summary_for_range(edit.old_lines.end..old_cursor.end(&()));
|
.text_summary_for_range(edit.old_lines.end..old_cursor.end(&()));
|
||||||
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("pushed transform suffix after edit; new transforms now:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
|
|
||||||
old_cursor.next(&());
|
old_cursor.next(&());
|
||||||
new_transforms.push_tree(
|
new_transforms.push_tree(
|
||||||
old_cursor.slice(&next_edit.old_lines.start, Bias::Right, &()),
|
old_cursor.slice(&next_edit.old_lines.start, Bias::Right, &()),
|
||||||
&(),
|
&(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
log::info!("pushed tree suffix after edit; new transforms now:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
log::info!("no more edits");
|
||||||
if old_cursor.end(&()) > edit.old_lines.end {
|
if old_cursor.end(&()) > edit.old_lines.end {
|
||||||
let summary = self
|
let summary = self
|
||||||
.tab_snapshot
|
.tab_snapshot
|
||||||
.text_summary_for_range(edit.old_lines.end..old_cursor.end(&()));
|
.text_summary_for_range(edit.old_lines.end..old_cursor.end(&()));
|
||||||
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
new_transforms.push_or_extend(Transform::isomorphic(summary));
|
||||||
|
|
||||||
|
log::info!("pushed transform suffix after edit; new transforms now:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
old_cursor.next(&());
|
old_cursor.next(&());
|
||||||
new_transforms.push_tree(old_cursor.suffix(&()), &());
|
new_transforms.push_tree(old_cursor.suffix(&()), &());
|
||||||
|
log::info!("pushed suffix:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,6 +432,12 @@ impl Snapshot {
|
||||||
new_rows: Range<u32>,
|
new_rows: Range<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("updating transforms... old transforms are:");
|
||||||
|
for transform in self.transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
|
|
||||||
let mut tab_edits_iter = tab_edits.into_iter().peekable();
|
let mut tab_edits_iter = tab_edits.into_iter().peekable();
|
||||||
let mut row_edits = Vec::new();
|
let mut row_edits = Vec::new();
|
||||||
while let Some(edit) = tab_edits_iter.next() {
|
while let Some(edit) = tab_edits_iter.next() {
|
||||||
|
@ -399,6 +459,11 @@ impl Snapshot {
|
||||||
row_edits.push(row_edit);
|
row_edits.push(row_edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("row edits are:");
|
||||||
|
for edit in &row_edits {
|
||||||
|
log::info!(" {:?}", edit);
|
||||||
|
}
|
||||||
|
|
||||||
let mut new_transforms;
|
let mut new_transforms;
|
||||||
if row_edits.is_empty() {
|
if row_edits.is_empty() {
|
||||||
new_transforms = self.transforms.clone();
|
new_transforms = self.transforms.clone();
|
||||||
|
@ -412,6 +477,12 @@ impl Snapshot {
|
||||||
&(),
|
&(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
log::info!("sliced a prefix:");
|
||||||
|
for transform in new_transforms.items(&()) {
|
||||||
|
log::info!(" - i {:?}", transform.summary.input);
|
||||||
|
log::info!(" o {:?}", transform.summary.output);
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(edit) = row_edits.next() {
|
while let Some(edit) = row_edits.next() {
|
||||||
if edit.new_rows.start > new_transforms.summary().input.lines.row {
|
if edit.new_rows.start > new_transforms.summary().input.lines.row {
|
||||||
let summary = new_tab_snapshot.text_summary_for_range(
|
let summary = new_tab_snapshot.text_summary_for_range(
|
||||||
|
@ -465,9 +536,15 @@ impl Snapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut edit_transforms = edit_transforms.into_iter();
|
let mut edit_transforms = edit_transforms.into_iter();
|
||||||
|
log::info!("extending tree with edit transforms");
|
||||||
if let Some(transform) = edit_transforms.next() {
|
if let Some(transform) = edit_transforms.next() {
|
||||||
|
log::info!(
|
||||||
|
"push or extend with first transform: {:?}",
|
||||||
|
transform.summary.output
|
||||||
|
);
|
||||||
new_transforms.push_or_extend(transform);
|
new_transforms.push_or_extend(transform);
|
||||||
}
|
}
|
||||||
|
log::info!("extending with remaining transforms");
|
||||||
new_transforms.extend(edit_transforms, &());
|
new_transforms.extend(edit_transforms, &());
|
||||||
|
|
||||||
old_cursor.seek_forward(&TabPoint::new(edit.old_rows.end, 0), Bias::Right, &());
|
old_cursor.seek_forward(&TabPoint::new(edit.old_rows.end, 0), Bias::Right, &());
|
||||||
|
@ -859,10 +936,17 @@ impl sum_tree::Item for Transform {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_isomorphic(transforms: &mut Vec<Transform>, summary: TextSummary) {
|
fn push_isomorphic(transforms: &mut Vec<Transform>, summary: TextSummary) {
|
||||||
|
log::info!("push_isomorphic: {:?}", summary);
|
||||||
if let Some(last_transform) = transforms.last_mut() {
|
if let Some(last_transform) = transforms.last_mut() {
|
||||||
if last_transform.is_isomorphic() {
|
if last_transform.is_isomorphic() {
|
||||||
last_transform.summary.input += &summary;
|
last_transform.summary.input += &summary;
|
||||||
last_transform.summary.output += &summary;
|
last_transform.summary.output += &summary;
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
" extended previous isomorphic: {:?}",
|
||||||
|
last_transform.summary.output
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -879,15 +963,28 @@ impl SumTreeExt for SumTree<Transform> {
|
||||||
self.update_last(
|
self.update_last(
|
||||||
|last_transform| {
|
|last_transform| {
|
||||||
if last_transform.is_isomorphic() && transform.as_ref().unwrap().is_isomorphic() {
|
if last_transform.is_isomorphic() && transform.as_ref().unwrap().is_isomorphic() {
|
||||||
|
// log::info!("extending last transform in tree");
|
||||||
|
// log::info!(
|
||||||
|
// " extending with: {:?}",
|
||||||
|
// transform.as_ref().map(|t| t.summary.output.clone()),
|
||||||
|
// );
|
||||||
|
// log::info!(" last transform was: {:?}", last_transform.summary.output);
|
||||||
|
|
||||||
let transform = transform.take().unwrap();
|
let transform = transform.take().unwrap();
|
||||||
last_transform.summary.input += &transform.summary.input;
|
last_transform.summary.input += &transform.summary.input;
|
||||||
last_transform.summary.output += &transform.summary.output;
|
last_transform.summary.output += &transform.summary.output;
|
||||||
|
|
||||||
|
// log::info!(
|
||||||
|
// " last transform is now {:?}",
|
||||||
|
// last_transform.summary.output,
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&(),
|
&(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(transform) = transform {
|
if let Some(transform) = transform {
|
||||||
|
log::info!("!!!!!!!!!!! push transform: {:?}", transform.summary.output,);
|
||||||
self.push(transform, &());
|
self.push(transform, &());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1011,7 +1108,7 @@ mod tests {
|
||||||
let unwrapped_text = tabs_snapshot.text();
|
let unwrapped_text = tabs_snapshot.text();
|
||||||
let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
|
let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper);
|
||||||
|
|
||||||
let (wrap_map, initial_snapshot) =
|
let (wrap_map, _) =
|
||||||
cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx));
|
cx.update(|cx| WrapMap::new(tabs_snapshot.clone(), font_id, font_size, wrap_width, cx));
|
||||||
let (_observer, notifications) = Observer::new(&wrap_map, &mut cx);
|
let (_observer, notifications) = Observer::new(&wrap_map, &mut cx);
|
||||||
|
|
||||||
|
@ -1019,6 +1116,11 @@ mod tests {
|
||||||
notifications.recv().await.unwrap();
|
notifications.recv().await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (initial_snapshot, _) = wrap_map.update(&mut cx, |map, cx| {
|
||||||
|
assert!(!map.is_rewrapping());
|
||||||
|
map.sync(tabs_snapshot.clone(), Vec::new(), cx)
|
||||||
|
});
|
||||||
|
|
||||||
let actual_text = initial_snapshot.text();
|
let actual_text = initial_snapshot.text();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual_text, expected_text,
|
actual_text, expected_text,
|
||||||
|
@ -1029,6 +1131,8 @@ mod tests {
|
||||||
|
|
||||||
let mut edits = Vec::new();
|
let mut edits = Vec::new();
|
||||||
for _i in 0..operations {
|
for _i in 0..operations {
|
||||||
|
log::info!("{} ==============================================", _i);
|
||||||
|
|
||||||
match rng.gen_range(0..=100) {
|
match rng.gen_range(0..=100) {
|
||||||
0..=19 => {
|
0..=19 => {
|
||||||
wrap_width = if rng.gen_bool(0.2) {
|
wrap_width = if rng.gen_bool(0.2) {
|
||||||
|
@ -1088,15 +1192,48 @@ mod tests {
|
||||||
let (mut wrapped_snapshot, wrap_edits) =
|
let (mut wrapped_snapshot, wrap_edits) =
|
||||||
wrap_map.update(&mut cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx));
|
wrap_map.update(&mut cx, |map, cx| map.sync(tabs_snapshot, Vec::new(), cx));
|
||||||
let actual_text = wrapped_snapshot.text();
|
let actual_text = wrapped_snapshot.text();
|
||||||
|
let actual_longest_row = wrapped_snapshot.longest_row();
|
||||||
log::info!("Wrapping finished: {:?}", actual_text);
|
log::info!("Wrapping finished: {:?}", actual_text);
|
||||||
wrapped_snapshot.check_invariants();
|
wrapped_snapshot.check_invariants();
|
||||||
wrapped_snapshot.verify_chunks(&mut rng);
|
wrapped_snapshot.verify_chunks(&mut rng);
|
||||||
edits.push((wrapped_snapshot, wrap_edits));
|
edits.push((wrapped_snapshot.clone(), wrap_edits));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual_text, expected_text,
|
actual_text, expected_text,
|
||||||
"unwrapped text is: {:?}",
|
"unwrapped text is: {:?}",
|
||||||
unwrapped_text
|
unwrapped_text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut summary = TextSummary::default();
|
||||||
|
for (ix, item) in wrapped_snapshot
|
||||||
|
.transforms
|
||||||
|
.items(&())
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
summary += &item.summary.output;
|
||||||
|
log::info!("{} summary: {:?}", ix, item.summary.output,);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut expected_longest_rows = Vec::new();
|
||||||
|
let mut longest_line_len = -1;
|
||||||
|
for (row, line) in expected_text.split('\n').enumerate() {
|
||||||
|
let line_char_count = line.chars().count() as isize;
|
||||||
|
if line_char_count > longest_line_len {
|
||||||
|
expected_longest_rows.clear();
|
||||||
|
longest_line_len = line_char_count;
|
||||||
|
}
|
||||||
|
if line_char_count >= longest_line_len {
|
||||||
|
expected_longest_rows.push(row as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
expected_longest_rows.contains(&actual_longest_row),
|
||||||
|
"incorrect longest row {}. expected {:?} with length {}",
|
||||||
|
actual_longest_row,
|
||||||
|
expected_longest_rows,
|
||||||
|
longest_line_len,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::marker::PhantomData;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[ctor::ctor]
|
#[ctor::ctor]
|
||||||
fn init_logger() {
|
fn init_logger() {
|
||||||
|
// std::env::set_var("RUST_LOG", "info");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue