Skip to content

Create a more compact diff format #2400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 3 additions & 43 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 3 additions & 43 deletions ui_test/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui_test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ rustc_version = "0.4"
colored = "2"
# Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
pretty_assertions = "1.2.1"
diff = "0.1.13"
crossbeam = "0.8.1"
lazy_static = "1.4.0"
serde = { version = "1.0", features = ["derive"] }
Expand Down
134 changes: 134 additions & 0 deletions ui_test/src/diff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use colored::*;
use diff::{chars, lines, Result, Result::*};

#[derive(Default)]
struct DiffState<'a> {
/// When we skip lines, remember the last `CONTEXT` ones to
/// display after the "skipped N lines" message
skipped_lines: Vec<&'a str>,
/// When we see a removed line, we don't print it, we
/// keep it around to compare it with the next added line.
prev_left: Option<&'a str>,
}

/// How many lines of context are displayed around the actual diffs
const CONTEXT: usize = 2;

impl<'a> DiffState<'a> {
fn print_skip(&mut self) {
let half = self.skipped_lines.len() / 2;
if half < CONTEXT {
for line in self.skipped_lines.drain(..) {
eprintln!(" {line}");
}
} else {
for line in self.skipped_lines.iter().take(CONTEXT) {
eprintln!(" {line}");
}
let skipped = self.skipped_lines.len() - CONTEXT * 2;
match skipped {
0 => {}
1 => eprintln!(" {}", self.skipped_lines[CONTEXT]),
_ => eprintln!("... {skipped} lines skipped ..."),
}
for line in self.skipped_lines.iter().rev().take(CONTEXT).rev() {
eprintln!(" {line}");
}
}
self.skipped_lines.clear();
}

fn skip(&mut self, line: &'a str) {
self.skipped_lines.push(line);
}

fn print_prev(&mut self) {
if let Some(l) = self.prev_left.take() {
self.print_left(l);
}
}

fn print_left(&self, l: &str) {
eprintln!("{}{}", "-".red(), l.red());
}

fn print_right(&self, r: &str) {
eprintln!("{}{}", "+".green(), r.green());
}

fn row(&mut self, row: Result<&'a str>) {
match row {
Left(l) => {
self.print_skip();
self.print_prev();
self.prev_left = Some(l);
}
Both(l, _) => {
self.print_prev();
self.skip(l);
}
Right(r) => {
if let Some(l) = self.prev_left.take() {
// If the lines only add chars or only remove chars, display an inline diff
let diff = chars(l, r);
let mut seen_l = false;
let mut seen_r = false;
for char in &diff {
match char {
Left(l) if !l.is_whitespace() => seen_l = true,
Right(r) if !r.is_whitespace() => seen_r = true,
_ => {}
}
}
if seen_l && seen_r {
// the line both adds and removes chars, print both lines, but highlight their differences
eprint!("{}", "-".red());
for char in &diff {
match char {
Left(l) => eprint!("{}", l.to_string().red()),
Right(_) => {}
Both(l, _) => eprint!("{}", l),
}
}
eprintln!();
eprint!("{}", "+".green());
for char in &diff {
match char {
Left(_) => {}
Right(r) => eprint!("{}", r.to_string().green()),
Both(l, _) => eprint!("{}", l),
}
}
eprintln!();
} else {
eprint!("{}", "~".yellow());
for char in diff {
match char {
Left(l) => eprint!("{}", l.to_string().red()),
Both(l, _) => eprint!("{}", l),
Right(r) => eprint!("{}", r.to_string().green()),
}
}
eprintln!();
}
} else {
self.print_skip();
self.print_right(r);
}
}
}
}

fn finish(mut self) {
self.print_skip();
eprintln!()
}
}

pub fn print_diff(expected: &str, actual: &str) {
let mut state = DiffState::default();
for row in lines(expected, actual) {
state.row(row);
}
state.finish();
}
4 changes: 2 additions & 2 deletions ui_test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::dependencies::build_dependencies;
use crate::parser::{Comments, Condition};

mod dependencies;
mod diff;
mod parser;
mod rustc_stderr;
#[cfg(test)]
Expand Down Expand Up @@ -261,8 +262,7 @@ pub fn run_tests(mut config: Config) -> Result<()> {
eprintln!("{}", "error pattern found in success test".red()),
Error::OutputDiffers { path, actual, expected } => {
eprintln!("actual output differed from expected {}", path.display());
eprintln!("{}", pretty_assertions::StrComparison::new(expected, actual));
eprintln!()
diff::print_diff(expected, actual);
}
Error::ErrorsWithoutPattern { path: None, msgs } => {
eprintln!(
Expand Down