Skip to content

Commit 68cfeab

Browse files
authored
Merge pull request #119 from sourcefrog/return-error
Optionally return errors from functions returning Result
2 parents 289447d + e291a01 commit 68cfeab

31 files changed

+522
-150
lines changed

.cargo/mutants.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# cargo-mutants configuration
22

3-
exclude_globs = [ "src/console.rs" ]
3+
error_values = ["::anyhow::anyhow!(\"mutated\")"]
4+
exclude_globs = ["src/console.rs"]

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ exclude = [
8989
"testdata/tree/cfg_attr_mutants_skip",
9090
"testdata/tree/cfg_attr_test_skip",
9191
"testdata/tree/dependency",
92+
"testdata/tree/error_value",
9293
"testdata/tree/everything_skipped",
9394
"testdata/tree/factorial",
9495
"testdata/tree/fails_without_feature",

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
- Minimum supported Rust version increased to 1.65 due to changes in dependencies.
1313

14+
- New `--error` option, to cause functions returning `Result` to be mutated to return the
15+
specified error.
16+
17+
- New `--no-config` option, to disable reading `.cargo/mutants.toml`.
18+
1419
## 1.2.2
1520

1621
Released 2023-04-01

book/src/SUMMARY.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
- [Exit codes](exit-codes.md)
99
- [The `mutants.out` directory](mutants-out.md)
1010
- [Skipping untestable code](skip.md)
11+
- [Skipping functions with an attribute](attrs.md)
12+
- [Filtering files](skip_files.md)
13+
- [Filtering functions and mutants](filter_mutants.md)
1114
- [Controlling cargo-mutants](controlling.md)
1215
- [Listing and previewing mutations](list.md)
13-
- [Filtering files](skip_files.md)
14-
- [Filtering mutants](filter_mutants.md)
1516
- [Workspaces and packages](workspaces.md)
1617
- [Passing options to Cargo](cargo-args.md)
17-
- [The `mutants.toml` config file](config.md)
18+
- [Generating mutants](mutants.md)
19+
- [Error values](error-values.md)
1820
- [Improving performance](performance.md)
1921
- [Parallelism](parallelism.md)
2022
- [Integrations](integrations.md)

book/src/attrs.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Skipping functions with an attribute
2+
3+
To mark functions as skipped, so they are not mutated:
4+
5+
1. Add a Cargo dependency on the [mutants](https://crates.io/crates/mutants)
6+
crate, version "0.0.3" or later. (This must be a regular `dependency` not a
7+
`dev-dependency`, because the annotation will be on non-test code.)
8+
9+
2. Mark functions with `#[mutants::skip]` or other attributes containing
10+
`mutants::skip` (e.g. `#[cfg_attr(test, mutants::skip)]`).
11+
12+
The `mutants` create is tiny and the attribute has no effect on the compiled
13+
code. It only flags the function for cargo-mutants. However, you can avoid the
14+
dependency by using the slightly longer `#[cfg_attr(test, mutants::skip)]` form.
15+
16+
**Note:** Currently, `cargo-mutants` does not (yet) evaluate attributes like
17+
`cfg_attr`, it only looks for the sequence `mutants::skip` in the attribute.
18+
19+
You may want to also add a comment explaining why the function is skipped.
20+
21+
For example:
22+
23+
```rust
24+
use std::time::{Duration, Instant};
25+
26+
/// Returns true if the program should stop
27+
#[cfg_attr(test, mutants::skip)] // Returning false would cause a hang
28+
fn should_stop() -> bool {
29+
true
30+
}
31+
32+
pub fn controlled_loop() {
33+
let start = Instant::now();
34+
for i in 0.. {
35+
println!("{}", i);
36+
if should_stop() {
37+
break;
38+
}
39+
if start.elapsed() > Duration::from_secs(60 * 5) {
40+
panic!("timed out");
41+
}
42+
}
43+
}
44+
45+
mod test {
46+
#[test]
47+
fn controlled_loop_terminates() {
48+
super::controlled_loop()
49+
}
50+
}
51+
```

book/src/cargo-args.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,28 @@ For example
1818
cargo mutants -- --cargo-arg=--release
1919
```
2020

21+
or in `.cargo/mutants.toml`:
22+
23+
```toml
24+
additional_cargo_args = ["--all-features"]
25+
```
26+
2127
## Arguments to `cargo test`
2228

2329
Command-line options following a `--` delimiter are passed through to
2430
`cargo test`. For example, this can be used to pass `--all-targets` which (unobviously)
2531
excludes doctests. (If the doctests are numerous and slow, and not relied upon to catch bugs, this can improve performance.)
2632

27-
These options can also be configured statically with the `additional_cargo_test_args` key in `.cargo/mutants.toml`.
28-
2933
```shell
3034
cargo mutants -- --all-targets
3135
```
3236

37+
These options can also be configured statically with the `additional_cargo_test_args` key in `.cargo/mutants.toml`:
38+
39+
```toml
40+
additional_cargo_test_args = ["--jobs=1"]
41+
```
42+
3343
## Arguments to test binaries
3444

3545
You can use a second double-dash to pass options through to the test targets:

book/src/config.md

Lines changed: 0 additions & 25 deletions
This file was deleted.

book/src/controlling.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
# Controlling cargo-mutants
22

3-
`cargo mutants` takes various options to control how it runs. These options are shown in `cargo mutants --help` and are described in detail in this section.
3+
`cargo mutants` takes various options to control how it runs.
4+
5+
These options, can, in general, be passed on the command line, set in a `.cargo/mutants.toml`
6+
file in the source tree, or passed in `CARGO_MUTANTS_` environment variables. Not every
7+
method of setting an option is available for every option, however, as some would not
8+
make sense or be useful.
9+
10+
For options that take a list of values, values from the configuration file are appended
11+
to values from the command line.
12+
13+
For options that take a single value, the value from the command line takes precedence.
14+
15+
`--no-config` can be used to disable reading the configuration file.
16+
17+
## Execution order
418

519
By default, mutants are run in a randomized order, so as to surface results from
620
different parts of the codebase earlier. This can be disabled with
7-
`--no-shuffle`, in which case mutants will run in the same order shown by
8-
`--list`: in order by file name and within each file in the order they appear in
21+
`--no-shuffle`, in which case mutants will run in order by file name and within each file in the order they appear in
922
the source.
1023

1124
## Source directory location
1225

13-
`-d`, `--dir`: Test the Rust tree in the given directory, rather than the default directory.
26+
`-d`, `--dir`: Test the Rust tree in the given directory, rather than the source tree
27+
enclosing the working directory where cargo-mutants is launched.
1428

1529
## Console output
1630

@@ -20,10 +34,6 @@ the source.
2034

2135
`--no-times`: Don't print elapsed times.
2236

23-
## Environment variables
24-
25-
A few options that may be useful to set globally can be configured through environment
26-
variables:
27-
28-
* `CARGO_MUTANTS_JOBS`
29-
* `CARGO_MUTANTS_TRACE_LEVEL`
37+
`-L`, `--level`, and `$CARGO_MUTANTS_TRACE_LEVEL`: set the verbosity of trace
38+
output to stdout. The default is `info`, and it can be increased to `debug` or
39+
`trace`.

book/src/error-values.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Generating error values
2+
3+
cargo-mutants can be configured to generate mutants that return an error value from functions that return a Result.
4+
5+
This will flag cases where no test fails if the function returns an error: that might happen if there are _only_ tests for the error cases and not for the Ok case.
6+
7+
Since crates can choose to use any type for their error values,
8+
cargo-mutants must be told how to construct an appropriate error.
9+
10+
The `--error` command line option and the `error_value` configuration option specify an error value to use.
11+
12+
These options can be repeated or combined, which might be useful
13+
if there are multiple error types in the crate. On any one mutation site, probably only one of the error values will be viable, and cargo-mutants will discover that and use it.
14+
15+
The error value can be any Rust expression that evaluates to a value of the error type. It should not include the `Err` wrapper, because cargo-mutants will add that.
16+
17+
For example, if your crate uses `anyhow::Error` as its error type, you might use `--error '::anyhow::anyhow!("error")'`.
18+
19+
If you have your own error type, you might use `--error 'crate::MyError::Generic'`.
20+
21+
Since the correct error type is a property of the source tree, the configuration should typically go into `.cargo/mutants.toml` rather than being specified on the command line:
22+
23+
```toml
24+
error_values = ["::anyhow::anyhow!(\"mutated\")"]
25+
```
26+
27+
To see only the mutants generated by this configuration, you
28+
can use a command like this:
29+
30+
```sh
31+
cargo r mutants -F anyhow -vV -j4
32+
```

0 commit comments

Comments
 (0)