]> git.lizzy.rs Git - rust.git/blobdiff - src/rustfmt_diff.rs
Add test for trailing newline in diff.
[rust.git] / src / rustfmt_diff.rs
index 8c20b8f5a0f0a68d7dc7a9f5be65e61af8ce56bc..c2dac6c041689d3a6e3c36780c4b8056008a6cab 100644 (file)
@@ -1,13 +1,28 @@
-use std::collections::VecDeque;
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use config::Color;
 use diff;
+use std::collections::VecDeque;
+use std::io;
 use term;
+use utils::use_colored_tty;
 
+#[derive(Debug, PartialEq)]
 pub enum DiffLine {
     Context(String),
     Expected(String),
     Resulting(String),
 }
 
+#[derive(Debug, PartialEq)]
 pub struct Mismatch {
     pub line_number: u32,
     pub lines: Vec<DiffLine>,
@@ -33,7 +48,7 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
     for result in diff::lines(expected, actual) {
         match result {
             diff::Result::Left(str) => {
-                if lines_since_mismatch >= context_size {
+                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
                     results.push(mismatch);
                     mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                 }
@@ -46,7 +61,7 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
                 lines_since_mismatch = 0;
             }
             diff::Result::Right(str) => {
-                if lines_since_mismatch >= context_size {
+                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
                     results.push(mismatch);
                     mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                 }
@@ -66,7 +81,7 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
 
                 if lines_since_mismatch < context_size {
                     mismatch.lines.push(DiffLine::Context(str.to_owned()));
-                } else {
+                } else if context_size > 0 {
                     context_queue.push_back(str);
                 }
 
@@ -82,19 +97,33 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
     results
 }
 
-pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
-    where F: Fn(u32) -> String
+pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F, color: Color)
+where
+    F: Fn(u32) -> String,
+{
+    match term::stdout() {
+        Some(ref t) if use_colored_tty(color) && t.supports_color() => {
+            print_diff_fancy(diff, get_section_title, term::stdout().unwrap())
+        }
+        _ => print_diff_basic(diff, get_section_title),
+    }
+}
+
+fn print_diff_fancy<F>(
+    diff: Vec<Mismatch>,
+    get_section_title: F,
+    mut t: Box<term::Terminal<Output = io::Stdout>>,
+) where
+    F: Fn(u32) -> String,
 {
-    let mut t = term::stdout().unwrap();
     for mismatch in diff {
-        t.fg(term::color::BRIGHT_WHITE).unwrap();
         let title = get_section_title(mismatch.line_number);
         writeln!(t, "{}", title).unwrap();
 
         for line in mismatch.lines {
             match line {
                 DiffLine::Context(ref str) => {
-                    t.fg(term::color::WHITE).unwrap();
+                    t.reset().unwrap();
                     writeln!(t, " {}⏎", str).unwrap();
                 }
                 DiffLine::Expected(ref str) => {
@@ -107,6 +136,118 @@ pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
                 }
             }
         }
+        t.reset().unwrap();
+    }
+}
+
+pub fn print_diff_basic<F>(diff: Vec<Mismatch>, get_section_title: F)
+where
+    F: Fn(u32) -> String,
+{
+    for mismatch in diff {
+        let title = get_section_title(mismatch.line_number);
+        println!("{}", title);
+
+        for line in mismatch.lines {
+            match line {
+                DiffLine::Context(ref str) => {
+                    println!(" {}⏎", str);
+                }
+                DiffLine::Expected(ref str) => {
+                    println!("+{}⏎", str);
+                }
+                DiffLine::Resulting(ref str) => {
+                    println!("-{}⏎", str);
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::{make_diff, Mismatch};
+    use super::DiffLine::*;
+
+    #[test]
+    fn diff_simple() {
+        let src = "one\ntwo\nthree\nfour\nfive\n";
+        let dest = "one\ntwo\ntrois\nfour\nfive\n";
+        let diff = make_diff(src, dest, 1);
+        assert_eq!(
+            diff,
+            vec![
+                Mismatch {
+                    line_number: 2,
+                    lines: vec![
+                        Context("two".into()),
+                        Resulting("three".into()),
+                        Expected("trois".into()),
+                        Context("four".into()),
+                    ],
+                },
+            ]
+        );
+    }
+
+    #[test]
+    fn diff_simple2() {
+        let src = "one\ntwo\nthree\nfour\nfive\nsix\nseven\n";
+        let dest = "one\ntwo\ntrois\nfour\ncinq\nsix\nseven\n";
+        let diff = make_diff(src, dest, 1);
+        assert_eq!(
+            diff,
+            vec![
+                Mismatch {
+                    line_number: 2,
+                    lines: vec![
+                        Context("two".into()),
+                        Resulting("three".into()),
+                        Expected("trois".into()),
+                        Context("four".into()),
+                    ],
+                },
+                Mismatch {
+                    line_number: 5,
+                    lines: vec![
+                        Resulting("five".into()),
+                        Expected("cinq".into()),
+                        Context("six".into()),
+                    ],
+                },
+            ]
+        );
+    }
+
+    #[test]
+    fn diff_zerocontext() {
+        let src = "one\ntwo\nthree\nfour\nfive\n";
+        let dest = "one\ntwo\ntrois\nfour\nfive\n";
+        let diff = make_diff(src, dest, 0);
+        assert_eq!(
+            diff,
+            vec![
+                Mismatch {
+                    line_number: 3,
+                    lines: vec![Resulting("three".into()), Expected("trois".into())],
+                },
+            ]
+        );
+    }
+
+    #[test]
+    fn diff_trailing_newline() {
+        let src = "one\ntwo\nthree\nfour\nfive";
+        let dest = "one\ntwo\nthree\nfour\nfive\n";
+        let diff = make_diff(src, dest, 1);
+        assert_eq!(
+            diff,
+            vec![
+                Mismatch {
+                    line_number: 5,
+                    lines: vec![Context("five".into()), Expected("".into())],
+                },
+            ]
+        );
     }
-    t.reset().unwrap();
 }