use crate::change::*;
use crate::changestore::*;
use crate::pristine::*;
use crate::working_copy::*;
use crate::*;
use std::io::Write;
use super::*;
#[cfg(feature = "text-changes")]
#[test]
fn text_changes() -> Result<(), anyhow::Error> {
env_logger::try_init().unwrap_or(());
let contents = b"a\nb\nc\nd\ne\nf\n";
let repo = working_copy::memory::Memory::new();
let store = changestore::memory::Memory::new();
repo.add_file("file", contents.to_vec());
repo.add_file("file2", contents.to_vec());
let env = pristine::sanakirja::Pristine::new_anon()?;
let txn = env.arc_txn_begin().unwrap();
let channel = txn.write().open_or_create_channel("main")?;
txn.write().add_file("file", 0)?;
txn.write().add_file("file2", 0)?;
let h0 = record_all(&repo, &store, &txn, &channel, "")?;
write!(repo.write_file("file", Inode::ROOT)?, "a\nx\nc\ne\ny\nf\n")?;
let h1 = record_all(&repo, &store, &txn, &channel, "")?;
let _change1 = store.get_change(&h1).unwrap();
repo.remove_path("file2", false)?;
let h2 = record_all(&repo, &store, &txn, &channel, "")?;
let _change2 = store.get_change(&h2).unwrap();
repo.rename("file", "file3")?;
txn.write().move_file("file", "file3", 0)?;
let h3 = record_all(&repo, &store, &txn, &channel, "")?;
let _change3 = store.get_change(&h3).unwrap();
let env2 = pristine::sanakirja::Pristine::new_anon()?;
let txn2 = env2.arc_txn_begin().unwrap();
let channel2 = txn2.write().open_or_create_channel("main")?;
let repo2 = working_copy::memory::Memory::new();
apply::apply_change(&store, &mut *txn2.write(), &mut *channel2.write(), &h0)?;
apply::apply_change(&store, &mut *txn2.write(), &mut *channel2.write(), &h1)?;
apply::apply_change(&store, &mut *txn2.write(), &mut *channel2.write(), &h2)?;
output::output_repository_no_pending(&repo2, &store, &txn2, &channel2, "", true, None, 1, 0)?;
repo2.rename("file", "file4")?;
txn2.write().move_file("file", "file4", 0)?;
record_all(&repo2, &store, &txn2, &channel2, "")?;
apply::apply_change(&store, &mut *txn2.write(), &mut *channel2.write(), &h3)?;
output::output_repository_no_pending(&repo2, &store, &txn2, &channel2, "", true, None, 1, 0)?;
let h = record_all(&repo2, &store, &txn2, &channel2, "")?;
let _solution = store.get_change(&h).unwrap();
Ok(())
}
quickcheck! {
fn string_roundtrip(s1: String) -> () {
let mut w = Vec::new();
write!(&mut w, "{}", Escaped(&s1)).unwrap();
let utf = std::str::from_utf8(&w).unwrap();
let (_, s2) = parse_string(&utf).unwrap();
assert_eq!(s1, s2);
}
}
use crate::quickcheck::{Arbitrary, Gen};
#[test]
#[cfg(feature = "text-changes")]
fn hunk_roundtrip_test() {
fn go(mut hunk: PrintableHunk) {
match hunk {
PrintableHunk::FileAddition {
ref perms,
ref mut contents,
..
} => {
if let PrintablePerms::IsDir = perms {
contents.clear()
}
}
PrintableHunk::FileDel {
ref mut del_edges, ..
} => {
if del_edges.is_empty() {
del_edges.push(PrintableEdge::arbitrary(&mut Gen::new(3)))
}
}
PrintableHunk::FileUndel {
ref mut undel_edges,
..
} => {
if undel_edges.is_empty() {
undel_edges.push(PrintableEdge::arbitrary(&mut Gen::new(3)))
}
}
PrintableHunk::Replace {
ref mut change_contents,
ref mut replacement_contents,
..
} => {
if change_contents.is_empty() {
change_contents.push(b'a')
}
if replacement_contents.is_empty() {
replacement_contents.push(b'b')
}
}
PrintableHunk::Edit {
ref mut change,
ref mut contents,
..
} => {
if let PrintableAtom::Edges(ref mut change) = change {
if change.is_empty() {
change.push(PrintableEdge::arbitrary(&mut Gen::new(3)))
}
}
if std::str::from_utf8(contents).is_err() {
contents.clear();
contents.extend(b"bla\n".iter().cloned())
}
}
_ => {}
}
let mut w = Vec::new();
hunk.write(&mut &mut w).unwrap();
let s = std::str::from_utf8(&w).unwrap();
match parse_hunk(&s) {
Ok((_, hunk2)) => {
if hunk != hunk2 {
eprintln!("## Hunk: \n\n{}", s);
eprintln!("In: {:?}\n\nOut: {:?}\n", hunk, hunk2);
panic!("Hunks don't match.");
}
}
Err(e) => {
eprintln!("Hunk: \n\n{}", s);
panic!("Can't parse hunk. Error: {:?}", e);
}
}
}
std::thread::Builder::new()
.stack_size(20 * 1024 * 1024)
.spawn(move || {
quickcheck::QuickCheck::new()
.tests(1000)
.gen(quickcheck::Gen::new(3))
.max_tests(100000000)
.quickcheck(go as fn(PrintableHunk) -> ());
})
.unwrap()
.join()
.unwrap();
}