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",
"chrono",
"collections",
"ctor",
"editor",
"env_logger 0.9.3",
"fs",
"futures 0.3.28",
"gpui",
"indoc",
"isahc",
"language",
"log",
"menu",
"project",
"rand 0.8.5",
"regex",
"schemars",
"search",

View File

@ -37,3 +37,8 @@ tiktoken-rs = "0.4"
[dev-dependencies]
editor = { path = "../editor", 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)]
mod tests {
use super::*;
use std::env;
#[test]
fn test_diff() {
let mut diff = Diff::new("hello world".to_string());
dbg!(diff.push_new("hello"));
dbg!(diff.push_new(" ciaone"));
// dbg!(diff.push_new(" world"));
dbg!(diff.finish());
use super::*;
use rand::prelude::*;
#[gpui::test(iterations = 100)]
fn test_random_diffs(mut rng: StdRng) {
let old_text_len = env::var("OLD_TEXT_LEN")
.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);
hunks_tx.send((hunks, new_text)).await?;
hunks_tx.send(hunks).await?;
}
hunks_tx.send((diff.finish(), String::new())).await?;
hunks_tx.send(diff.finish()).await?;
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.buffer().update(cx, |buffer, cx| {
buffer.start_transaction(cx);