Skip to content

Commit 93e2f7f

Browse files
committed
Replace OutputConflictHandling enum with function pointers instead
1 parent 6af9315 commit 93e2f7f

File tree

15 files changed

+73
-62
lines changed

15 files changed

+73
-62
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
* `only`/`ignore` filters now only accept integers, alphabetic characters, `-` and `_`
1717
* `only`/ `ignore` filters allow comments by ignoring everything from an `#` onwards
18+
* `OutputConflictHandling` has been replaced by `error_on_output_conflict`, `bless_output_files`,
19+
and `ignore_output_conflict` functions. Custom functions can now be used to implement special
20+
handling of output conflicts.
1821

1922
### Removed
2023

src/config.rs

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
diagnostics::Diagnostics,
1111
parser::CommandParserFunc,
1212
per_test_config::{Comments, Condition},
13-
CommandBuilder,
13+
CommandBuilder, Error, Errors,
1414
};
1515
pub use color_eyre;
1616
use color_eyre::eyre::Result;
@@ -36,7 +36,8 @@ pub struct Config {
3636
/// The binary to actually execute.
3737
pub program: CommandBuilder,
3838
/// What to do in case the stdout/stderr output differs from the expected one.
39-
pub output_conflict_handling: OutputConflictHandling,
39+
pub output_conflict_handling:
40+
fn(path: &Path, actual: Vec<u8>, errors: &mut Errors, config: &Config),
4041
/// The recommended command to bless failing tests.
4142
pub bless_command: Option<String>,
4243
/// Where to dump files like the binaries compiled from tests.
@@ -78,7 +79,7 @@ impl Config {
7879
target: Default::default(),
7980
root_dir: Default::default(),
8081
program: CommandBuilder::cmd(""),
81-
output_conflict_handling: OutputConflictHandling::Error,
82+
output_conflict_handling: error_on_output_conflict,
8283
bless_command: Default::default(),
8384
out_dir: Default::default(),
8485
skip_files: Default::default(),
@@ -159,7 +160,7 @@ impl Config {
159160
target: None,
160161
root_dir: root_dir.into(),
161162
program: CommandBuilder::rustc(),
162-
output_conflict_handling: OutputConflictHandling::Error,
163+
output_conflict_handling: error_on_output_conflict,
163164
bless_command: None,
164165
out_dir: std::env::var_os("CARGO_TARGET_DIR")
165166
.map(PathBuf::from)
@@ -273,9 +274,9 @@ impl Config {
273274
self.list = list;
274275

275276
if check {
276-
self.output_conflict_handling = OutputConflictHandling::Error;
277+
self.output_conflict_handling = error_on_output_conflict;
277278
} else if bless {
278-
self.output_conflict_handling = OutputConflictHandling::Bless;
279+
self.output_conflict_handling = bless_output_files;
279280
}
280281
}
281282

@@ -437,16 +438,41 @@ impl Config {
437438
}
438439
}
439440

440-
#[derive(Debug, Clone)]
441-
/// The different options for what to do when stdout/stderr files differ from the actual output.
442-
pub enum OutputConflictHandling {
443-
/// Fail the test when mismatches are found, if provided the command string
444-
/// in [`Config::bless_command`] will be suggested as a way to bless the
445-
/// test.
446-
Error,
447-
/// Ignore mismatches in the stderr/stdout files.
448-
Ignore,
449-
/// Instead of erroring if the stderr/stdout differs from the expected
450-
/// automatically replace it with the found output (after applying filters).
451-
Bless,
441+
/// Fail the test when mismatches are found, if provided the command string
442+
/// in [`Config::bless_command`] will be suggested as a way to bless the
443+
/// test.
444+
pub fn error_on_output_conflict(
445+
path: &Path,
446+
actual: Vec<u8>,
447+
errors: &mut Errors,
448+
config: &Config,
449+
) {
450+
let expected = std::fs::read(path).unwrap_or_default();
451+
if actual != expected {
452+
errors.push(Error::OutputDiffers {
453+
path: path.to_path_buf(),
454+
actual,
455+
expected,
456+
bless_command: config.bless_command.clone(),
457+
});
458+
}
459+
}
460+
461+
/// Ignore mismatches in the stderr/stdout files.
462+
pub fn ignore_output_conflict(
463+
_path: &Path,
464+
_actual: Vec<u8>,
465+
_errors: &mut Errors,
466+
_config: &Config,
467+
) {
468+
}
469+
470+
/// Instead of erroring if the stderr/stdout differs from the expected
471+
/// automatically replace it with the found output (after applying filters).
472+
pub fn bless_output_files(path: &Path, actual: Vec<u8>, _errors: &mut Errors, _config: &Config) {
473+
if actual.is_empty() {
474+
let _ = std::fs::remove_file(path);
475+
} else {
476+
std::fs::write(path, &actual).unwrap();
477+
}
452478
}

src/dependencies.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
custom_flags::Flag,
1717
per_test_config::TestConfig,
1818
test_result::Errored,
19-
CommandBuilder, Config, OutputConflictHandling,
19+
CommandBuilder, Config,
2020
};
2121

2222
#[derive(Default, Debug)]
@@ -100,12 +100,11 @@ fn build_dependencies_inner(
100100

101101
// Reusable closure for setting up the environment both for artifact generation and `cargo_metadata`
102102
let set_locking = |cmd: &mut Command| {
103-
if let OutputConflictHandling::Error = config.output_conflict_handling {
103+
if !info.bless_lockfile {
104104
cmd.arg("--locked");
105105
}
106106
};
107107

108-
set_locking(&mut build);
109108
build.arg("--message-format=json");
110109

111110
let output = match build.output() {
@@ -365,6 +364,8 @@ pub struct DependencyBuilder {
365364
/// Build with [`build-std`](https://doc.rust-lang.org/1.78.0/cargo/reference/unstable.html#build-std),
366365
/// which requires the nightly toolchain. The [`String`] can contain the standard library crates to build.
367366
pub build_std: Option<String>,
367+
/// Whether the lockfile can be overwritten
368+
pub bless_lockfile: bool,
368369
}
369370

370371
impl Default for DependencyBuilder {
@@ -373,6 +374,7 @@ impl Default for DependencyBuilder {
373374
crate_manifest_path: PathBuf::from("Cargo.toml"),
374375
program: CommandBuilder::cargo(),
375376
build_std: None,
377+
bless_lockfile: false,
376378
}
377379
}
378380
}

src/per_test_config.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use crate::parser::{Comments, Condition, Revisioned};
2020
use crate::parser::{ErrorMatch, ErrorMatchKind, OptWithLine};
2121
use crate::status_emitter::{SilentStatus, TestStatus};
2222
use crate::test_result::{Errored, TestOk, TestResult};
23-
use crate::{core::strip_path_prefix, Config, Error, Errors, OutputConflictHandling};
23+
use crate::{core::strip_path_prefix, Config, Error, Errors};
2424

2525
/// All information needed to run a single test
2626
pub struct TestConfig {
@@ -200,27 +200,7 @@ impl TestConfig {
200200
pub(crate) fn check_output(&self, output: &[u8], errors: &mut Errors, kind: &str) -> PathBuf {
201201
let output = self.normalize(output, kind);
202202
let path = self.output_path(kind);
203-
match &self.config.output_conflict_handling {
204-
OutputConflictHandling::Error => {
205-
let expected_output = std::fs::read(&path).unwrap_or_default();
206-
if output != expected_output {
207-
errors.push(Error::OutputDiffers {
208-
path: path.clone(),
209-
actual: output.clone(),
210-
expected: expected_output,
211-
bless_command: self.config.bless_command.clone(),
212-
});
213-
}
214-
}
215-
OutputConflictHandling::Bless => {
216-
if output.is_empty() {
217-
let _ = std::fs::remove_file(&path);
218-
} else {
219-
std::fs::write(&path, &output).unwrap();
220-
}
221-
}
222-
OutputConflictHandling::Ignore => {}
223-
}
203+
(self.config.output_conflict_handling)(&path, output, errors, &self.config);
224204
path
225205
}
226206

tests/integrations/basic-bin/tests/ui_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ fn main() -> ui_test::color_eyre::Result<()> {
44
let path = "../../../target";
55
let mut config = Config {
66
output_conflict_handling: if std::env::var_os("BLESS").is_some() {
7-
OutputConflictHandling::Bless
7+
ui_test::bless_output_files
88
} else {
9-
OutputConflictHandling::Error
9+
ui_test::error_on_output_conflict
1010
},
1111
bless_command: Some("cargo test".to_string()),
1212
..Config::rustc("tests/actual_tests")

tests/integrations/basic-fail-mode/tests/ui_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ fn main() -> ui_test::color_eyre::Result<()> {
44
let path = "../../../target";
55
let mut config = Config {
66
output_conflict_handling: if std::env::var_os("BLESS").is_some() {
7-
OutputConflictHandling::Bless
7+
ui_test::bless_output_files
88
} else {
9-
OutputConflictHandling::Error
9+
ui_test::error_on_output_conflict
1010
},
1111
bless_command: Some("cargo test".to_string()),
1212
..Config::rustc("tests/actual_tests")

tests/integrations/basic-fail/tests/ui_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn main() -> ui_test::color_eyre::Result<()> {
44
let path = "../../../target";
55
let mut config = Config {
66
// Never bless integrations-fail tests, we want to see stderr mismatches
7-
output_conflict_handling: OutputConflictHandling::Error,
7+
output_conflict_handling: ui_test::error_on_output_conflict,
88
bless_command: Some("DO NOT BLESS. These are meant to fail".to_string()),
99
..Config::rustc("tests/actual_tests")
1010
};

tests/integrations/basic-fail/tests/ui_tests_bless.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ fn main() -> ui_test::color_eyre::Result<()> {
1414

1515
let mut config = Config {
1616
output_conflict_handling: if std::env::var_os("BLESS").is_some() {
17-
OutputConflictHandling::Bless
17+
ui_test::bless_output_files
1818
} else {
19-
OutputConflictHandling::Error
19+
ui_test::error_on_output_conflict
2020
},
2121
bless_command: Some("cargo test".to_string()),
2222
..Config::rustc(root_dir)

tests/integrations/basic-fail/tests/ui_tests_diff_only.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use ui_test::*;
33
fn main() -> ui_test::color_eyre::Result<()> {
44
let config = Config {
55
// Never bless integrations-fail tests, we want to see stderr mismatches
6-
output_conflict_handling: OutputConflictHandling::Error,
6+
output_conflict_handling: ui_test::error_on_output_conflict,
77
bless_command: Some("DO NOT BLESS. These are meant to fail".to_string()),
88
..Config::rustc("tests/actual_tests")
99
};

tests/integrations/basic-fail/tests/ui_tests_invalid_program.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn main() -> ui_test::color_eyre::Result<()> {
44
let config = Config {
55
program: CommandBuilder::cmd("invalid_foobarlaksdfalsdfj"),
66
// Never bless integrations-fail tests, we want to see stderr mismatches
7-
output_conflict_handling: OutputConflictHandling::Error,
7+
output_conflict_handling: ui_test::error_on_output_conflict,
88
bless_command: Some("DO NOT BLESS. These are meant to fail".to_string()),
99
..Config::rustc("tests/actual_tests")
1010
};

0 commit comments

Comments
 (0)