From 4ecde410c44f86b0cef8134ff3e2483435979908 Mon Sep 17 00:00:00 2001
From: Marcus Klaas <mail@marcusklaas.nl>
Date: Tue, 12 May 2015 02:16:46 +0200
Subject: [PATCH] Show diffs for failing tests

---
 Cargo.lock    |  6 ++++++
 Cargo.toml    |  3 +++
 tests/idem.rs | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/Cargo.lock b/Cargo.lock
index 0d3b11ac492..60496ff2ccd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,9 +2,15 @@
 name = "rustfmt"
 version = "0.0.1"
 dependencies = [
+ "diff 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "strings 0.0.1 (git+https://github.com/nrc/strings.rs.git)",
 ]
 
+[[package]]
+name = "diff"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "strings"
 version = "0.0.1"
diff --git a/Cargo.toml b/Cargo.toml
index 49c473fb008..a78a31d11c3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,3 +11,6 @@ license = "Apache-2.0/MIT"
 [dependencies.strings]
 strings = "0.0.1"
 git = "https://github.com/nrc/strings.rs.git"
+
+[dev-dependencies]
+diff = "0.1.0"
diff --git a/tests/idem.rs b/tests/idem.rs
index d19bcc6fa55..1b74b1aa83e 100644
--- a/tests/idem.rs
+++ b/tests/idem.rs
@@ -11,6 +11,7 @@
 #![feature(catch_panic)]
 
 extern crate rustfmt;
+extern crate diff;
 
 use std::collections::HashMap;
 use std::fs;
@@ -89,6 +90,7 @@ fn handle_result(result: HashMap<String, String>) {
         // TODO: speedup by running through bytes iterator
         f.read_to_string(&mut text).unwrap();
         if fmt_text != text {
+            show_diff(&file_name, &fmt_text, &text);
             failures.insert(file_name, fmt_text);
         }
     }
@@ -96,3 +98,33 @@ fn handle_result(result: HashMap<String, String>) {
         panic!(failures);
     }
 }
+
+
+fn show_diff(file_name: &str, expected: &str, actual: &str) {
+    let mut line_number = 1;
+    let mut prev_both = true;
+
+    for result in diff::lines(expected, actual) {
+        match result {
+            diff::Result::Left(str) => {
+                if prev_both {
+                    println!("Mismatch @ {}:{}", file_name, line_number);
+                }
+                println!("-{}⏎", str);
+                prev_both = false;
+            }
+            diff::Result::Right(str) => {
+                if prev_both {
+                    println!("Mismatch @ {}:{}", file_name, line_number);
+                }
+                println!("+{}⏎", str);
+                prev_both = false;
+                line_number += 1;
+            }
+            diff::Result::Both(..) => {
+                line_number += 1;
+                prev_both = true;
+            }
+        }
+    }
+}