Skip to content

Commit

Permalink
Add --output
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcefrog committed Mar 30, 2022
1 parent 5b638e0 commit 6a6d743
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 8 deletions.
6 changes: 6 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,9 @@ up the CPU will continue.

Therefore we need to also intercept the signal to cargo-mutants and manually
pass it on to the subprocess group.

## Output directory handling

Various output files, including the text output from all the cargo commands are
written into `mutants.out` within the directory specified by `--output`, or by
default the source directory.
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
`Default`. cargo-mutants can not yet generate good mutations for these so they
are generally false positives.

- Better display of `<impl Foo for Bar>::foo`.
- Improved: Better display of `<impl Foo for Bar>::foo` and similar type paths.

- New: `--output` directory to write `mutants.out` somewhere other than the
source directory.

## 0.2.4

Expand Down
7 changes: 6 additions & 1 deletion src/lab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ pub fn test_unmutated_then_all_mutants(
) -> Result<LabOutcome> {
let mut options: Options = options.clone();
let mut lab_outcome = LabOutcome::default();
let output_dir = OutputDir::new(source_tree.root())?;
let output_in_dir = if let Some(o) = &options.output_in_dir {
o.as_path()
} else {
source_tree.root()
};
let output_dir = OutputDir::new(output_in_dir)?;
let mut lab_activity = LabActivity::new(&options);

if options.build_source {
Expand Down
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ struct Args {
#[argh(switch)]
no_times: bool,

/// create mutants.out within this directory.
#[argh(option, short = 'o')]
output: Option<PathBuf>,

/// run mutants in random order.
#[argh(switch)]
shuffle: bool,
Expand Down
4 changes: 4 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub struct Options {

/// Files to examine.
pub globset: Option<GlobSet>,

/// Create `mutants.out` within this directory (by default, the source directory).
pub output_in_dir: Option<PathBuf>,
}

impl Options {
Expand Down Expand Up @@ -84,6 +87,7 @@ impl TryFrom<&Args> for Options {
check_only: args.check,
copy_target: !args.no_copy_target,
globset,
output_in_dir: args.output.clone(),
print_caught: args.caught,
print_unviable: args.unviable,
shuffle: !args.no_shuffle,
Expand Down
12 changes: 6 additions & 6 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ impl OutputDir {
///
/// If the directory already exists, it's rotated to `mutants.out.old`. If that directory
/// exists, it's deleted.
pub fn new<P: AsRef<Path>>(in_dir: P) -> Result<OutputDir> {
let path: PathBuf = in_dir.as_ref().join(OUTDIR_NAME);
pub fn new(in_dir: &Path) -> Result<OutputDir> {
let path = in_dir.join(OUTDIR_NAME);
if path.exists() {
let rotated = in_dir.as_ref().join(ROTATED_NAME);
let rotated = in_dir.join(ROTATED_NAME);
if rotated.exists() {
fs::remove_dir_all(&rotated).with_context(|| format!("remove {:?}", &rotated))?;
}
Expand Down Expand Up @@ -104,15 +104,15 @@ mod test {
let temp_dir = tempfile::TempDir::new().unwrap();

// Create an initial output dir with one log.
let output_dir = OutputDir::new(&temp_dir).unwrap();
let output_dir = OutputDir::new(temp_dir.path()).unwrap();
output_dir.create_log(&Scenario::SourceTree).unwrap();
assert!(temp_dir
.path()
.join("mutants.out/log/source_tree.log")
.is_file());

// The second time we create it in the same directory, the old one is moved away.
let output_dir = OutputDir::new(&temp_dir).unwrap();
let output_dir = OutputDir::new(temp_dir.path()).unwrap();
output_dir.create_log(&Scenario::SourceTree).unwrap();
output_dir.create_log(&Scenario::Baseline).unwrap();
assert!(temp_dir
Expand All @@ -129,7 +129,7 @@ mod test {
.is_file());

// The third time (and later), the .old directory is removed.
let output_dir = OutputDir::new(&temp_dir).unwrap();
let output_dir = OutputDir::new(temp_dir.path()).unwrap();
output_dir.create_log(&Scenario::SourceTree).unwrap();
assert!(temp_dir
.path()
Expand Down
41 changes: 41 additions & 0 deletions tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,47 @@ fn factorial_mutants_no_copy_target() {
}));
}

#[test]
fn output_option() {
let tmp_src_dir = copy_of_testdata("factorial");
let output_tmpdir = TempDir::new().unwrap();
assert!(
!tmp_src_dir.path().join("mutants.out").exists(),
"mutants.out should not be in a clean copy of the test data"
);
run_assert_cmd()
.arg("mutants")
.arg("--output")
.arg(&output_tmpdir.path())
.args(["--check", "--no-times"])
.arg("-d")
.arg(&tmp_src_dir.path())
.assert()
.success();
assert!(
!tmp_src_dir.path().join("mutants.out").exists(),
"mutants.out should not be in the source directory after --output was given"
);
assert!(
output_tmpdir.path().join("mutants.out").exists(),
"mutants.out is in --output directory"
);
assert!(
output_tmpdir
.path()
.join("mutants.out/mutants.json")
.is_file(),
"mutants.out/mutants.json is in --output directory"
);
assert!(
output_tmpdir
.path()
.join("mutants.out/outcomes.json")
.is_file(),
"mutants.out/outcomes.json is in --output directory"
);
}

#[test]
fn check_succeeds_in_tree_that_builds_but_fails_tests() {
// --check doesn't actually run the tests so won't discover that they fail.
Expand Down

0 comments on commit 6a6d743

Please sign in to comment.