Add randomized tests for incremental diff

This commit is contained in:
Antonio Scandurra 2023-08-23 09:09:01 +02:00
parent 3a511db5c9
commit a9871a7a70
5 changed files with 81 additions and 12 deletions

4
Cargo.lock generated
View file

@ -102,15 +102,19 @@ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
"collections", "collections",
"ctor",
"editor", "editor",
"env_logger 0.9.3",
"fs", "fs",
"futures 0.3.28", "futures 0.3.28",
"gpui", "gpui",
"indoc", "indoc",
"isahc", "isahc",
"language", "language",
"log",
"menu", "menu",
"project", "project",
"rand 0.8.5",
"regex", "regex",
"schemars", "schemars",
"search", "search",

View file

@ -37,3 +37,8 @@ tiktoken-rs = "0.4"
[dev-dependencies] [dev-dependencies]
editor = { path = "../editor", features = ["test-support"] } editor = { path = "../editor", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] } project = { path = "../project", features = ["test-support"] }
ctor.workspace = true
env_logger.workspace = true
log.workspace = true
rand.workspace = true

View file

@ -283,3 +283,11 @@ pub async fn stream_completion(
} }
} }
} }
#[cfg(test)]
#[ctor::ctor]
fn init_logger() {
if std::env::var("RUST_LOG").is_ok() {
env_logger::init();
}
}

View file

@ -204,14 +204,67 @@ impl Diff {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use std::env;
#[test] use super::*;
fn test_diff() { use rand::prelude::*;
let mut diff = Diff::new("hello world".to_string());
dbg!(diff.push_new("hello")); #[gpui::test(iterations = 100)]
dbg!(diff.push_new(" ciaone")); fn test_random_diffs(mut rng: StdRng) {
// dbg!(diff.push_new(" world")); let old_text_len = env::var("OLD_TEXT_LEN")
dbg!(diff.finish()); .map(|i| i.parse().expect("invalid `OLD_TEXT_LEN` variable"))
.unwrap_or(10);
let new_text_len = env::var("NEW_TEXT_LEN")
.map(|i| i.parse().expect("invalid `NEW_TEXT_LEN` variable"))
.unwrap_or(10);
let old = util::RandomCharIter::new(&mut rng)
.take(old_text_len)
.collect::<String>();
log::info!("old text: {:?}", old);
let mut diff = Diff::new(old.clone());
let mut hunks = Vec::new();
let mut new_len = 0;
let mut new = String::new();
while new_len < new_text_len {
let new_chunk_len = rng.gen_range(1..=new_text_len - new_len);
let new_chunk = util::RandomCharIter::new(&mut rng)
.take(new_len)
.collect::<String>();
log::info!("new chunk: {:?}", new_chunk);
new_len += new_chunk_len;
new.push_str(&new_chunk);
let new_hunks = diff.push_new(&new_chunk);
log::info!("hunks: {:?}", new_hunks);
hunks.extend(new_hunks);
}
let final_hunks = diff.finish();
log::info!("final hunks: {:?}", final_hunks);
hunks.extend(final_hunks);
log::info!("new text: {:?}", new);
let mut old_ix = 0;
let mut new_ix = 0;
let mut patched = String::new();
for hunk in hunks {
match hunk {
Hunk::Keep { len } => {
assert_eq!(&old[old_ix..old_ix + len], &new[new_ix..new_ix + len]);
patched.push_str(&old[old_ix..old_ix + len]);
old_ix += len;
new_ix += len;
}
Hunk::Remove { len } => {
old_ix += len;
}
Hunk::Insert { text } => {
assert_eq!(text, &new[new_ix..new_ix + text.len()]);
patched.push_str(&text);
new_ix += text.len();
}
}
}
assert_eq!(patched, new);
} }
} }

View file

@ -78,15 +78,14 @@ impl RefactoringAssistant {
} }
let hunks = diff.push_new(&new_text); let hunks = diff.push_new(&new_text);
hunks_tx.send((hunks, new_text)).await?; hunks_tx.send(hunks).await?;
} }
hunks_tx.send(diff.finish()).await?;
hunks_tx.send((diff.finish(), String::new())).await?;
anyhow::Ok(()) anyhow::Ok(())
}); });
while let Some((hunks, new_text)) = hunks_rx.next().await { while let Some(hunks) = hunks_rx.next().await {
editor.update(&mut cx, |editor, cx| { editor.update(&mut cx, |editor, cx| {
editor.buffer().update(cx, |buffer, cx| { editor.buffer().update(cx, |buffer, cx| {
buffer.start_transaction(cx); buffer.start_transaction(cx);