mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 02:46:43 +00:00
Start on a simple randomized test for FragmentList
This commit is contained in:
parent
8354d1520d
commit
e37908cf3b
5 changed files with 99 additions and 6 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2576,6 +2576,8 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clock",
|
"clock",
|
||||||
"collections",
|
"collections",
|
||||||
|
"ctor",
|
||||||
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
"gpui",
|
"gpui",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
|
@ -46,6 +46,8 @@ gpui = { path = "../gpui", features = ["test-support"] }
|
||||||
lsp = { path = "../lsp", features = ["test-support"] }
|
lsp = { path = "../lsp", features = ["test-support"] }
|
||||||
text = { path = "../text", features = ["test-support"] }
|
text = { path = "../text", features = ["test-support"] }
|
||||||
util = { path = "../util", features = ["test-support"] }
|
util = { path = "../util", features = ["test-support"] }
|
||||||
|
ctor = "0.1"
|
||||||
|
env_logger = "0.8"
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
tree-sitter-rust = "0.20.0"
|
tree-sitter-rust = "0.20.0"
|
||||||
unindent = "0.1.7"
|
unindent = "0.1.7"
|
||||||
|
|
|
@ -157,21 +157,22 @@ impl FragmentList {
|
||||||
for edit in patches[patch_ix].edits() {
|
for edit in patches[patch_ix].edits() {
|
||||||
let edit_start = edit.new.start;
|
let edit_start = edit.new.start;
|
||||||
let edit_end = edit.new.start + edit.old_len();
|
let edit_end = edit.new.start + edit.old_len();
|
||||||
if edit_end < new_range.start {
|
if edit_start > new_range.end {
|
||||||
|
break;
|
||||||
|
} else if edit_end < new_range.start {
|
||||||
let delta = edit.new_len() as isize - edit.old_len() as isize;
|
let delta = edit.new_len() as isize - edit.old_len() as isize;
|
||||||
new_range.start = (new_range.start as isize + delta) as usize;
|
new_range.start = (new_range.start as isize + delta) as usize;
|
||||||
new_range.end = (new_range.end as isize + delta) as usize;
|
new_range.end = (new_range.end as isize + delta) as usize;
|
||||||
} else if edit_start >= new_range.end {
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
let mut new_range_len = new_range.len();
|
let mut new_range_len = new_range.len();
|
||||||
new_range_len -=
|
new_range_len -=
|
||||||
cmp::min(new_range.end, edit_end) - cmp::max(new_range.start, edit_start);
|
cmp::min(new_range.end, edit_end) - cmp::max(new_range.start, edit_start);
|
||||||
if edit_start > new_range.start {
|
if edit_start < new_range.start {
|
||||||
|
new_range.start = edit.new.end;
|
||||||
|
} else {
|
||||||
new_range_len += edit.new_len();
|
new_range_len += edit.new_len();
|
||||||
}
|
}
|
||||||
|
|
||||||
new_range.start = cmp::min(new_range.start, edit.new.end);
|
|
||||||
new_range.end = new_range.start + new_range_len;
|
new_range.end = new_range.start + new_range_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,11 +363,13 @@ impl Location {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::env;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Buffer;
|
use crate::Buffer;
|
||||||
use gpui::MutableAppContext;
|
use gpui::MutableAppContext;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use text::Point;
|
use text::{Point, RandomCharIter};
|
||||||
use util::test::sample_text;
|
use util::test::sample_text;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -451,6 +454,77 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test(iterations = 100)]
|
||||||
|
fn test_random(cx: &mut MutableAppContext, mut rng: StdRng) {
|
||||||
|
let operations = env::var("OPERATIONS")
|
||||||
|
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||||
|
.unwrap_or(10);
|
||||||
|
|
||||||
|
let mut buffers: Vec<ModelHandle<Buffer>> = Vec::new();
|
||||||
|
let list = cx.add_model(|_| FragmentList::new());
|
||||||
|
let mut fragment_ids = Vec::new();
|
||||||
|
let mut expected_fragments = Vec::new();
|
||||||
|
|
||||||
|
for _ in 0..operations {
|
||||||
|
match rng.gen_range(0..100) {
|
||||||
|
0..=19 if !buffers.is_empty() => {
|
||||||
|
let buffer = buffers.choose(&mut rng).unwrap();
|
||||||
|
buffer.update(cx, |buf, cx| buf.randomly_edit(&mut rng, 5, cx));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let buffer_handle = if buffers.is_empty() || rng.gen_bool(0.4) {
|
||||||
|
let base_text = RandomCharIter::new(&mut rng).take(10).collect::<String>();
|
||||||
|
buffers.push(cx.add_model(|cx| Buffer::new(0, base_text, cx)));
|
||||||
|
buffers.last().unwrap()
|
||||||
|
} else {
|
||||||
|
buffers.choose(&mut rng).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let buffer = buffer_handle.read(cx);
|
||||||
|
let end_ix = buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right);
|
||||||
|
let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
|
||||||
|
let header_height = rng.gen_range(0..=5);
|
||||||
|
let anchor_range = buffer.anchor_before(start_ix)..buffer.anchor_after(end_ix);
|
||||||
|
log::info!(
|
||||||
|
"Pushing fragment for buffer {}: {:?}[{:?}] = {:?}",
|
||||||
|
buffer_handle.id(),
|
||||||
|
buffer.text(),
|
||||||
|
start_ix..end_ix,
|
||||||
|
&buffer.text()[start_ix..end_ix]
|
||||||
|
);
|
||||||
|
|
||||||
|
let fragment_id = list.update(cx, |list, cx| {
|
||||||
|
list.push(
|
||||||
|
FragmentProperties {
|
||||||
|
buffer: &buffer_handle,
|
||||||
|
range: start_ix..end_ix,
|
||||||
|
header_height,
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
fragment_ids.push(fragment_id);
|
||||||
|
expected_fragments.push((buffer_handle.clone(), anchor_range, header_height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let snapshot = list.read(cx).snapshot(cx);
|
||||||
|
let mut expected_text = String::new();
|
||||||
|
for (buffer, range, header_height) in &expected_fragments {
|
||||||
|
let buffer = buffer.read(cx);
|
||||||
|
if !expected_text.is_empty() {
|
||||||
|
expected_text.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..*header_height {
|
||||||
|
expected_text.push('\n');
|
||||||
|
}
|
||||||
|
expected_text.extend(buffer.text_for_range(range.clone()));
|
||||||
|
}
|
||||||
|
assert_eq!(snapshot.text(), expected_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
fn test_location(mut rng: StdRng) {
|
fn test_location(mut rng: StdRng) {
|
||||||
let mut lhs = Default::default();
|
let mut lhs = Default::default();
|
||||||
|
|
|
@ -12,6 +12,13 @@ use std::{
|
||||||
};
|
};
|
||||||
use unindent::Unindent as _;
|
use unindent::Unindent as _;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[ctor::ctor]
|
||||||
|
fn init_logger() {
|
||||||
|
// std::env::set_var("RUST_LOG", "info");
|
||||||
|
env_logger::init();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_select_language() {
|
fn test_select_language() {
|
||||||
let registry = LanguageRegistry {
|
let registry = LanguageRegistry {
|
||||||
|
|
|
@ -12,6 +12,14 @@ impl<T: Rng> Iterator for RandomCharIter<T> {
|
||||||
type Item = char;
|
type Item = char;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if std::env::var("SIMPLE_TEXT").map_or(false, |v| !v.is_empty()) {
|
||||||
|
return if self.0.gen_range(0..100) < 5 {
|
||||||
|
Some('\n')
|
||||||
|
} else {
|
||||||
|
Some(self.0.gen_range(b'a'..b'z' + 1).into())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
match self.0.gen_range(0..100) {
|
match self.0.gen_range(0..100) {
|
||||||
// whitespace
|
// whitespace
|
||||||
0..=19 => [' ', '\n', '\t'].choose(&mut self.0).copied(),
|
0..=19 => [' ', '\n', '\t'].choose(&mut self.0).copied(),
|
||||||
|
|
Loading…
Reference in a new issue