Skip to content

Commit

Permalink
Add compare-output-lines-by-subset flag to compiletest
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Apr 20, 2023
1 parent 5546cb6 commit a30171c
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pub struct TestProps {
pub dont_check_compiler_stdout: bool,
// For UI tests, allows compiler to generate arbitrary output to stderr
pub dont_check_compiler_stderr: bool,
// When checking the output of stdout or stderr check
// that the lines of expected output are a subset of the actual output.
pub compare_output_lines_by_subset: bool,
// Don't force a --crate-type=dylib flag on the command line
//
// Set this for example if you have an auxiliary test file that contains
Expand Down Expand Up @@ -209,6 +212,7 @@ mod directives {
pub const KNOWN_BUG: &'static str = "known-bug";
pub const MIR_UNIT_TEST: &'static str = "unit-test";
pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
// This isn't a real directive, just one that is probably mistyped often
pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
}
Expand All @@ -233,6 +237,7 @@ impl TestProps {
check_run_results: false,
dont_check_compiler_stdout: false,
dont_check_compiler_stderr: false,
compare_output_lines_by_subset: false,
no_prefer_dynamic: false,
pretty_expanded: false,
pretty_mode: "normal".to_string(),
Expand Down Expand Up @@ -467,6 +472,11 @@ impl TestProps {
s.trim().to_string()
});
config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base);
config.set_name_directive(
ln,
COMPARE_OUTPUT_LINES_BY_SUBSET,
&mut self.compare_output_lines_by_subset,
);
});
}

Expand Down
66 changes: 58 additions & 8 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3238,17 +3238,35 @@ impl<'test> TestCx<'test> {
match output_kind {
TestOutput::Compile => {
if !self.props.dont_check_compiler_stdout {
errors +=
self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
errors += self.compare_output(
stdout_kind,
&normalized_stdout,
&expected_stdout,
self.props.compare_output_lines_by_subset,
);
}
if !self.props.dont_check_compiler_stderr {
errors +=
self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
errors += self.compare_output(
stderr_kind,
&normalized_stderr,
&expected_stderr,
self.props.compare_output_lines_by_subset,
);
}
}
TestOutput::Run => {
errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
errors += self.compare_output(
stdout_kind,
&normalized_stdout,
&expected_stdout,
self.props.compare_output_lines_by_subset,
);
errors += self.compare_output(
stderr_kind,
&normalized_stderr,
&expected_stderr,
self.props.compare_output_lines_by_subset,
);
}
}
errors
Expand Down Expand Up @@ -3332,7 +3350,12 @@ impl<'test> TestCx<'test> {
)
});

errors += self.compare_output("fixed", &fixed_code, &expected_fixed);
errors += self.compare_output(
"fixed",
&fixed_code,
&expected_fixed,
self.props.compare_output_lines_by_subset,
);
} else if !expected_fixed.is_empty() {
panic!(
"the `// run-rustfix` directive wasn't found but a `*.fixed` \
Expand Down Expand Up @@ -3790,11 +3813,38 @@ impl<'test> TestCx<'test> {
}
}

fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
fn compare_output(
&self,
kind: &str,
actual: &str,
expected: &str,
compare_output_by_lines: bool,
) -> usize {
if actual == expected {
return 0;
}

let tmp;
let (expected, actual): (&str, &str) = if compare_output_by_lines {
let actual_lines: HashSet<_> = actual.lines().collect();
let expected_lines: Vec<_> = expected.lines().collect();
let mut used = expected_lines.clone();
used.retain(|line| actual_lines.contains(line));
// check if `expected` contains a subset of the lines of `actual`
if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) {
return 0;
}
if expected_lines.is_empty() {
// if we have no lines to check, force a full overwite
("", actual)
} else {
tmp = (expected_lines.join("\n"), used.join("\n"));
(&tmp.0, &tmp.1)
}
} else {
(expected, actual)
};

if !self.config.bless {
if expected.is_empty() {
println!("normalized {}:\n{}\n", kind, actual);
Expand Down

0 comments on commit a30171c

Please sign in to comment.