From 18712783da6fec2658773286445f14af1fb999ea Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 29 Dec 2023 22:02:45 +0100 Subject: [PATCH] Always call finish (#58) --- CHANGELOG.md | 4 ++++ src/algorithms/lcs.rs | 32 ++++++++++++++++++++++++++++++++ src/algorithms/myers.rs | 29 +++++++++++++++++++++++++++++ src/algorithms/patience.rs | 29 +++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index adcbf42..a0d9aff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to similar are documented here. +## 2.4.0 + +* Fixed a bug where the LCS diff algorithm didn't always call `D::finish`. (#58) + ## 2.3.0 * Added support for `Change::value_ref` and `Change::value_mut`. diff --git a/src/algorithms/lcs.rs b/src/algorithms/lcs.rs index 65c9bf3..ffead40 100644 --- a/src/algorithms/lcs.rs +++ b/src/algorithms/lcs.rs @@ -55,9 +55,11 @@ where { if is_empty_range(&new_range) { d.delete(old_range.start, old_range.len(), new_range.start)?; + d.finish()?; return Ok(()); } else if is_empty_range(&old_range) { d.insert(old_range.start, new_range.start, new_range.len())?; + d.finish()?; return Ok(()); } @@ -67,6 +69,7 @@ where // If the sequences are not different then we're done if common_prefix_len == old_range.len() && (old_range.len() == new_range.len()) { d.equal(0, 0, old_range.len())?; + d.finish()?; return Ok(()); } @@ -234,3 +237,32 @@ fn test_same() { diff(&mut d, a, 0..a.len(), b, 0..b.len()).unwrap(); insta::assert_debug_snapshot!(d.ops()); } + +#[test] +fn test_finish_called() { + struct HasRunFinish(bool); + + impl DiffHook for HasRunFinish { + type Error = (); + fn finish(&mut self) -> Result<(), Self::Error> { + self.0 = true; + Ok(()) + } + } + + let mut d = HasRunFinish(false); + let slice = &[1, 2]; + let slice2 = &[1, 2, 3]; + diff(&mut d, slice, 0..slice.len(), slice2, 0..slice2.len()).unwrap(); + assert!(d.0); + + let mut d = HasRunFinish(false); + let slice = &[1, 2]; + diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap(); + assert!(d.0); + + let mut d = HasRunFinish(false); + let slice: &[u8] = &[]; + diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap(); + assert!(d.0); +} diff --git a/src/algorithms/myers.rs b/src/algorithms/myers.rs index 8a0c21d..733c5ad 100644 --- a/src/algorithms/myers.rs +++ b/src/algorithms/myers.rs @@ -413,3 +413,32 @@ fn test_deadline_reached() { .unwrap(); insta::assert_debug_snapshot!(d.into_inner().ops()); } + +#[test] +fn test_finish_called() { + struct HasRunFinish(bool); + + impl DiffHook for HasRunFinish { + type Error = (); + fn finish(&mut self) -> Result<(), Self::Error> { + self.0 = true; + Ok(()) + } + } + + let mut d = HasRunFinish(false); + let slice = &[1, 2]; + let slice2 = &[1, 2, 3]; + diff(&mut d, slice, 0..slice.len(), slice2, 0..slice2.len()).unwrap(); + assert!(d.0); + + let mut d = HasRunFinish(false); + let slice = &[1, 2]; + diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap(); + assert!(d.0); + + let mut d = HasRunFinish(false); + let slice: &[u8] = &[]; + diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap(); + assert!(d.0); +} diff --git a/src/algorithms/patience.rs b/src/algorithms/patience.rs index 2b2faa2..8cc807f 100644 --- a/src/algorithms/patience.rs +++ b/src/algorithms/patience.rs @@ -167,3 +167,32 @@ fn test_patience_out_of_bounds_bug() { insta::assert_debug_snapshot!(d.into_inner().ops()); } + +#[test] +fn test_finish_called() { + struct HasRunFinish(bool); + + impl DiffHook for HasRunFinish { + type Error = (); + fn finish(&mut self) -> Result<(), Self::Error> { + self.0 = true; + Ok(()) + } + } + + let mut d = HasRunFinish(false); + let slice = &[1, 2]; + let slice2 = &[1, 2, 3]; + diff(&mut d, slice, 0..slice.len(), slice2, 0..slice2.len()).unwrap(); + assert!(d.0); + + let mut d = HasRunFinish(false); + let slice = &[1, 2]; + diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap(); + assert!(d.0); + + let mut d = HasRunFinish(false); + let slice: &[u8] = &[]; + diff(&mut d, slice, 0..slice.len(), slice, 0..slice.len()).unwrap(); + assert!(d.0); +}