diff --git a/Cargo.toml b/Cargo.toml index d470a97..798c90d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,8 @@ httparse = "1.3.3" regex = "1.0.5" lazy_static = "1.1.0" serde_json = "1.0.17" -difference = "2.0" +similar = "2.1" + colored = { version = "2.0.0", optional = true } log = "0.4.6" assert-json-diff = "2.0.0" diff --git a/src/diff.rs b/src/diff.rs index ea70ff3..b1eab1d 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -1,6 +1,6 @@ #[cfg(feature = "color")] use colored::*; -use difference::{Changeset, Difference}; +use similar::{Change, ChangeTag, TextDiff}; pub fn compare(expected: &str, actual: &str) -> String { let mut result = String::new(); @@ -8,62 +8,53 @@ pub fn compare(expected: &str, actual: &str) -> String { let clean_expected = expected.replace("\r\n", "\n"); let clean_actual = actual.replace("\r\n", "\n"); - let Changeset { diffs, .. } = Changeset::new(&clean_expected, &clean_actual, "\n"); - - for i in 0..diffs.len() { - match diffs[i] { - Difference::Same(ref x) => { + let mut last: Option> = None; + for diff in TextDiff::from_lines(&clean_expected, &clean_actual).iter_all_changes() { + let x = diff.value(); + match diff.tag() { + ChangeTag::Equal => { result.push_str(x); - result.push('\n'); } - Difference::Add(ref x) => { - if let Difference::Rem(ref y) = diffs[i - 1] { - let Changeset { diffs, .. } = Changeset::new(y, x, " "); - for (i, change) in diffs.iter().enumerate() { - match change { - Difference::Same(ref z) => { + ChangeTag::Insert => { + if let Some((y, ChangeTag::Delete)) = last.map(|d| (d.value(), d.tag())) { + for change in TextDiff::from_words(y, x).iter_all_changes() { + match change.tag() { + ChangeTag::Equal => { + let z = change.value(); #[cfg(feature = "color")] result.push_str(&z.green().to_string()); #[cfg(not(feature = "color"))] - result.push_str(&z); - - if i < diffs.len() - 1 { - result.push(' '); - } + result.push_str(z); } - Difference::Add(ref z) => { + ChangeTag::Insert => { + let z = change.value(); #[cfg(feature = "color")] result.push_str(&z.white().on_green().to_string()); #[cfg(not(feature = "color"))] - result.push_str(&z); - - if i < diffs.len() - 1 { - result.push(' '); - } + result.push_str(z); } _ => (), } } - result.push('\n'); } else { #[cfg(feature = "color")] result.push_str(&x.bright_green().to_string()); #[cfg(not(feature = "color"))] - result.push_str(&x); - - result.push('\n'); + result.push_str(x); } } - Difference::Rem(ref x) => { + ChangeTag::Delete => { #[cfg(feature = "color")] result.push_str(&x.red().to_string()); #[cfg(not(feature = "color"))] - result.push_str(&x); - - result.push('\n'); + result.push_str(x); } } + + last = Some(diff); } + result.push('\n'); + result } diff --git a/tests/lib.rs b/tests/lib.rs index a54a5be..9d02f73 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1127,7 +1127,7 @@ fn test_assert_panics_with_too_many_requests() { #[test] #[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\n\n> Difference:\n\n\u{1b}[31mGET /hello\u{1b}[0m\n\u{1b}[32mGET\u{1b}[0m \u{1b}[42;37m/bye\u{1b}[0m\n\n\n" + expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\n\n> Difference:\n\n\u{1b}[31mGET /hello\n\u{1b}[0m\u{1b}[32mGET\u{1b}[0m\u{1b}[32m \u{1b}[0m\u{1b}[42;37m/bye\u{1b}[0m\u{1b}[32m\n\u{1b}[0m\n\n" )] #[cfg(feature = "color")] fn test_assert_with_last_unmatched_request() { @@ -1154,7 +1154,7 @@ fn test_assert_with_last_unmatched_request() { #[test] #[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\nauthorization: 1234\r\naccept: text\r\n\n> Difference:\n\n\u{1b}[31mGET /hello\u{1b}[0m\n\u{1b}[32mGET\u{1b}[0m \u{1b}[42;37m/bye\nauthorization: 1234\naccept: text\u{1b}[0m\n\n\n" + expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\nauthorization: 1234\r\naccept: text\r\n\n> Difference:\n\n\u{1b}[31mGET /hello\n\u{1b}[0m\u{1b}[32mGET\u{1b}[0m\u{1b}[32m \u{1b}[0m\u{1b}[42;37m/bye\u{1b}[0m\u{1b}[32m\n\u{1b}[0m\u{1b}[92mauthorization: 1234\n\u{1b}[0m\u{1b}[92maccept: text\n\u{1b}[0m\n\n" )] #[cfg(feature = "color")] fn test_assert_with_last_unmatched_request_and_headers() {