johannhof / difference.rs

Rust text diffing and assertion library
https://docs.rs/difference
MIT License
241 stars 35 forks source link

weird edge case #19

Closed colin-kiegel closed 6 years ago

colin-kiegel commented 7 years ago

Steps to reproduce

extern crate difference;
use difference::Changeset;

fn main() {
    let ch = Changeset::new("a b : g",
                            "b a : b b : g g", " ");
    println!("{}", ch);
}

Got

-a
 b
+a
 :
-g
+b b
 : g
+g

Expected

-a
 b
+a
 :
-g
+b b : g g
colin-kiegel commented 7 years ago

I pushed a PR, which adds a testcase for this (plus fuzzy testing) #20 :-)

colin-kiegel commented 7 years ago

The bug is in the LCS algorithm:

// src/lcs.rs
#[test]
fn test_lcs() {
    assert_eq!(lcs("a b : g", "b a : b b : g g", " "), (3, "a b : g ".to_string()));
}

fails with

---- lcs::test_lcs stdout ----
        thread 'lcs::test_lcs' panicked at 'assertion failed: `(left == right)`
  left: `(4, "b : : g ")`,
 right: `(3, "a b : g ")`'

Note that "b : : g " is not a substring of "a b : g" at all.

colin-kiegel commented 7 years ago

@johannhof Is this a common algorithm? If you could paste a link to a proof or explanation of this algorithm, I could try to spot the mistake in the implementation. But without documentation it's a bit hard to understand how this algorithm is supposed to work.

colin-kiegel commented 7 years ago

I'm currently testing a new implementation. I'll let you know if I make any progress.