mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-09 20:04:25 +00:00
Add randomized test for DisplayMap::buffer_rows
and fix logic errors
This commit is contained in:
parent
72fdd3fb9a
commit
62ad97a728
3 changed files with 88 additions and 17 deletions
|
@ -272,9 +272,73 @@ mod tests {
|
|||
language::{Language, LanguageConfig},
|
||||
settings::Theme,
|
||||
test::*,
|
||||
util::RandomCharIter,
|
||||
};
|
||||
use buffer::History;
|
||||
use std::sync::Arc;
|
||||
use rand::prelude::*;
|
||||
use std::{env, sync::Arc};
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_random(mut cx: gpui::TestAppContext) {
|
||||
cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
|
||||
let iterations = env::var("ITERATIONS")
|
||||
.map(|i| i.parse().expect("invalid `ITERATIONS` variable"))
|
||||
.unwrap_or(100);
|
||||
let operations = env::var("OPERATIONS")
|
||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||
.unwrap_or(10);
|
||||
let seed_range = if let Ok(seed) = env::var("SEED") {
|
||||
let seed = seed.parse().expect("invalid `SEED` variable");
|
||||
seed..seed + 1
|
||||
} else {
|
||||
0..iterations
|
||||
};
|
||||
let font_cache = cx.font_cache();
|
||||
|
||||
for seed in seed_range {
|
||||
dbg!(seed);
|
||||
let mut rng = StdRng::seed_from_u64(seed);
|
||||
let settings = Settings {
|
||||
buffer_font_family: font_cache.load_family(&["Helvetica"]).unwrap(),
|
||||
ui_font_family: font_cache.load_family(&["Helvetica"]).unwrap(),
|
||||
buffer_font_size: 12.0,
|
||||
ui_font_size: 12.0,
|
||||
tab_size: rng.gen_range(1..=4),
|
||||
theme: Arc::new(Theme::default()),
|
||||
};
|
||||
|
||||
let buffer = cx.add_model(|cx| {
|
||||
let len = rng.gen_range(0..10);
|
||||
let text = RandomCharIter::new(&mut rng).take(len).collect::<String>();
|
||||
log::info!("Initial buffer text: {:?}", text);
|
||||
Buffer::new(0, text, cx)
|
||||
});
|
||||
let wrap_width = Some(rng.gen_range(20.0..=100.0));
|
||||
let map = cx.read(|cx| DisplayMap::new(buffer.clone(), settings, wrap_width, cx));
|
||||
|
||||
for _op_ix in 0..operations {
|
||||
buffer.update(&mut cx, |buffer, cx| buffer.randomly_mutate(&mut rng, cx));
|
||||
let snapshot = cx.read(|cx| map.snapshot(cx));
|
||||
let expected_buffer_rows = (0..=snapshot.max_point().row())
|
||||
.map(|display_row| {
|
||||
DisplayPoint::new(display_row, 0)
|
||||
.to_buffer_point(&snapshot, Bias::Left)
|
||||
.row
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
for start_display_row in 0..expected_buffer_rows.len() {
|
||||
assert_eq!(
|
||||
snapshot
|
||||
.buffer_rows(start_display_row as u32)
|
||||
.collect::<Vec<_>>(),
|
||||
&expected_buffer_rows[start_display_row..],
|
||||
"invalid buffer_rows({}..)",
|
||||
start_display_row
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_soft_wraps(mut cx: gpui::TestAppContext) {
|
||||
|
|
|
@ -167,14 +167,15 @@ impl Snapshot {
|
|||
pub fn buffer_rows(&self, start_row: u32) -> BufferRows {
|
||||
let mut transforms = self.transforms.cursor::<OutputPoint, InputPoint>();
|
||||
transforms.seek(&OutputPoint::new(start_row, 0), Bias::Right, &());
|
||||
let input_row = transforms.sum_start().row();
|
||||
let mut input_buffer_rows = self.input.buffer_rows(start_row);
|
||||
let input_row = transforms.sum_start().row() + (start_row - transforms.seek_start().row());
|
||||
let mut input_buffer_rows = self.input.buffer_rows(input_row);
|
||||
let input_buffer_row = input_buffer_rows.next().unwrap();
|
||||
BufferRows {
|
||||
transforms,
|
||||
input_row,
|
||||
input_buffer_row,
|
||||
input_buffer_rows,
|
||||
output_row: start_row,
|
||||
max_output_row: self.max_point().row(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,8 +213,9 @@ pub struct HighlightedChunks<'a> {
|
|||
|
||||
pub struct BufferRows<'a> {
|
||||
input_buffer_rows: fold_map::BufferRows<'a>,
|
||||
input_row: u32,
|
||||
input_buffer_row: u32,
|
||||
output_row: u32,
|
||||
max_output_row: u32,
|
||||
transforms: Cursor<'a, Transform, OutputPoint, InputPoint>,
|
||||
}
|
||||
|
||||
|
@ -299,18 +301,19 @@ impl<'a> Iterator for BufferRows<'a> {
|
|||
type Item = u32;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let result = self.input_buffer_row;
|
||||
if self.input_row + 1 < self.transforms.sum_end(&()).row() {
|
||||
self.input_row += 1;
|
||||
self.input_buffer_row = self.input_buffer_rows.next().unwrap();
|
||||
} else {
|
||||
self.transforms.seek_forward(
|
||||
&OutputPoint::new(self.transforms.seek_start().row() + 1, 0),
|
||||
Bias::Right,
|
||||
&(),
|
||||
);
|
||||
if self.output_row > self.max_output_row {
|
||||
return None;
|
||||
}
|
||||
Some(result)
|
||||
|
||||
let buffer_row = self.input_buffer_row;
|
||||
self.output_row += 1;
|
||||
self.transforms
|
||||
.seek_forward(&OutputPoint::new(self.output_row, 0), Bias::Left, &());
|
||||
if self.transforms.item().map_or(false, |t| t.is_isomorphic()) {
|
||||
self.input_buffer_row = self.input_buffer_rows.next().unwrap();
|
||||
}
|
||||
|
||||
Some(buffer_row)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,11 @@ impl<T: Rng> Iterator for RandomCharIter<T> {
|
|||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.0.gen_bool(1.0 / 5.0) {
|
||||
Some('\n')
|
||||
match self.0.gen_range(0..=2) {
|
||||
0 => Some('\t'),
|
||||
1 => Some(' '),
|
||||
_ => Some('\n'),
|
||||
}
|
||||
}
|
||||
// two-byte greek letters
|
||||
else if self.0.gen_bool(1.0 / 8.0) {
|
||||
|
|
Loading…
Reference in a new issue