-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 {
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);
}
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);
}
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);
}
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,
{
- let mut t = term::stdout().unwrap();
+ 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,
+{
for mismatch in diff {
let title = get_section_title(mismatch.line_number);
writeln!(t, "{}", title).unwrap();
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())],
+ },
+ ]
+ );
+ }
+}