Skip to content

Commit c6e50d2

Browse files
committed
write reload unit test
1 parent 91def8e commit c6e50d2

File tree

5 files changed

+102
-4
lines changed

5 files changed

+102
-4
lines changed

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

helix-core/src/history.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl Revision {
118118
}
119119

120120
// Temporarily 3 for review.
121-
const HEADER_TAG: &str = "Helix Undofile 3\n";
121+
const HEADER_TAG: &str = "Helix Undofile 4\n";
122122

123123
fn get_hash<R: Read>(reader: &mut R) -> std::io::Result<[u8; 20]> {
124124
const BUF_SIZE: usize = 8192;
@@ -155,6 +155,7 @@ impl History {
155155
write_u64(writer, mtime)?;
156156
writer.write_all(&get_hash(&mut std::fs::File::open(path)?)?)?;
157157

158+
// Append new revisions to the end of the file.
158159
write_usize(writer, self.revisions.len())?;
159160
writer.seek(SeekFrom::End(0))?;
160161
for rev in &self.revisions[last_saved_revision..] {

helix-loader/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub fn local_config_dirs() -> Vec<PathBuf> {
7070
}
7171

7272
pub fn cache_dir() -> PathBuf {
73-
let mut path = if cfg!(feature = "integration") {
73+
let mut path = if cfg!(feature = "integration") || cfg!(test) {
7474
std::env::temp_dir()
7575
} else {
7676
// TODO: allow env var override

helix-view/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,6 @@ clipboard-win = { version = "4.5", features = ["std"] }
5252
libc = "0.2"
5353

5454
[dev-dependencies]
55+
quickcheck = { version = "1", default-features = false }
56+
tempfile = "3"
5557
helix-tui = { path = "../helix-tui" }

helix-view/src/document.rs

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ impl Document {
636636
.into_std()
637637
.await;
638638
tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
639+
// Truncate the file if it's not a valid undofile.
639640
if History::deserialize(&mut std::fs::File::open(&undofile_path)?, &path)
640641
.is_ok()
641642
{
@@ -1386,7 +1387,8 @@ impl Display for FormatterError {
13861387

13871388
#[cfg(test)]
13881389
mod test {
1389-
use arc_swap::ArcSwap;
1390+
use arc_swap::{access::Map, ArcSwap};
1391+
use quickcheck::Gen;
13901392

13911393
use super::*;
13921394

@@ -1556,6 +1558,98 @@ mod test {
15561558
);
15571559
}
15581560

1561+
#[tokio::test(flavor = "multi_thread")]
1562+
async fn reload_history() {
1563+
let test_fn: fn(Vec<String>) -> bool = |changes| -> bool {
1564+
let len = changes.len() / 3;
1565+
let mut original = Rope::new();
1566+
let mut iter = changes.into_iter();
1567+
1568+
let changes_a: Vec<_> = iter
1569+
.by_ref()
1570+
.take(len)
1571+
.map(|c| {
1572+
let c = Rope::from(c);
1573+
let transaction = helix_core::diff::compare_ropes(&original, &c);
1574+
original = c;
1575+
transaction
1576+
})
1577+
.collect();
1578+
let mut original_concurrent = original.clone();
1579+
1580+
let changes_b: Vec<_> = iter
1581+
.by_ref()
1582+
.take(len)
1583+
.map(|c| {
1584+
let c = Rope::from(c);
1585+
let transaction = helix_core::diff::compare_ropes(&original, &c);
1586+
original = c;
1587+
transaction
1588+
})
1589+
.collect();
1590+
let changes_c: Vec<_> = iter
1591+
.take(len)
1592+
.map(|c| {
1593+
let c = Rope::from(c);
1594+
let transaction = helix_core::diff::compare_ropes(&original_concurrent, &c);
1595+
original_concurrent = c;
1596+
transaction
1597+
})
1598+
.collect();
1599+
1600+
let file = tempfile::NamedTempFile::new().unwrap();
1601+
let mut config = Config::default();
1602+
config.persistent_undo = true;
1603+
1604+
let view_id = ViewId::default();
1605+
let config = Arc::new(ArcSwap::new(Arc::new(config)));
1606+
let mut doc_1 = Document::open(file.path(), None, None, config.clone()).unwrap();
1607+
doc_1.ensure_view_init(view_id);
1608+
1609+
// Make changes & save document A
1610+
for c in changes_a {
1611+
doc_1.apply(&c, view_id);
1612+
}
1613+
helix_lsp::block_on(doc_1.save::<PathBuf>(None, true).unwrap()).unwrap();
1614+
1615+
let mut doc_2 = Document::open(file.path(), None, None, config.clone()).unwrap();
1616+
let mut doc_3 = Document::open(file.path(), None, None, config.clone()).unwrap();
1617+
doc_2.ensure_view_init(view_id);
1618+
doc_3.ensure_view_init(view_id);
1619+
1620+
// Make changes in A and B at the same time.
1621+
for c in changes_b {
1622+
doc_1.apply(&c, view_id);
1623+
}
1624+
1625+
for c in changes_c {
1626+
doc_2.apply(&c, view_id);
1627+
}
1628+
helix_lsp::block_on(doc_2.save::<PathBuf>(None, true).unwrap()).unwrap();
1629+
1630+
doc_1.load_history().unwrap();
1631+
doc_3.load_history().unwrap();
1632+
1633+
assert_eq!(doc_2.history.get_mut(), doc_3.history.get_mut());
1634+
1635+
helix_lsp::block_on(doc_1.save::<PathBuf>(None, true).unwrap()).unwrap();
1636+
doc_2.load_history().unwrap();
1637+
doc_3.load_history().unwrap();
1638+
doc_1.history.get_mut() == doc_2.history.get_mut()
1639+
&& doc_1.history.get_mut() == doc_3.history.get_mut()
1640+
};
1641+
let handles: Vec<_> = (0..100)
1642+
.map(|_| {
1643+
tokio::task::spawn_blocking(move || {
1644+
quickcheck::QuickCheck::new()
1645+
.max_tests(1)
1646+
.quickcheck(test_fn);
1647+
})
1648+
})
1649+
.collect();
1650+
futures_util::future::try_join_all(handles).await.unwrap();
1651+
}
1652+
15591653
macro_rules! decode {
15601654
($name:ident, $label:expr, $label_override:expr) => {
15611655
#[test]

0 commit comments

Comments
 (0)