1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
//! `cargo-darwin` is a plugin over `cargo` tool.
//!
//! Darwin mutates your code, if your code still passes check tests, then your code isn't enough tested.
//!
//! ## Usage
//! ```bash
//! cargo darwin /path/to/project/to/test
//! ```
//! Will display something like
//! ```bash
//! [Missing] : Tests pass, the mutation hasn't been caught, suspicion of missing test
//! [OK] : Tests failed, the mutation has been caught
//! [Timeout] : Mutation introduces infinite loop, inconclusive
//! [Killed] : Mutation introduces non buildable modification
//! ---
//! [OK] : Mutation #0 replace - by + in function "sub" of file src\a\toto.rs at line 11:6
//! [OK] : Mutation #1 replace - by * in function "sub" of file src\a\toto.rs at line 11:6
//! [Killed] : Mutation #2 replace - by && in function "sub" of file src\a\toto.rs at line 11:6
//! [Missing] : Mutation #3 replace + by - in function "add" of file src\lib.rs at line 5:6
//! [Missing] : Mutation #4 replace + by * in function "add" of file src\lib.rs at line 5:6
//! [Missing] : Mutation #5 replace + by - in function "add" of file src\lib.rs at line 5:10
//! [Missing] : Mutation #6 replace + by * in function "add" of file src\lib.rs at line 5:10
//! ```
//!
//! ## Details
//!
//! *Darwin* walks the provided path (if none provided get the current dir).
//!
//! For each file ending by **.rs** extension, **Darwin** analyze the file and try to found mutable
//! function.
//!
//! A function is mutable if there is no `#[test]` or `#[tokio::test]` attribute over it.
//!
//! ```ignore
//! fn mutable() {}
//!
//! #[test]
//! fn non_mutable() {}
//!
//! #[tokio::test]
//! async fn non_mutable_async() {}
//! ```
//!
//! The project is in its really early stage, so the mutation are quite limited, actually just binary expressions like `a + b` or `a - b`.
//!
//! For example this mutable function
//!
//! ```
//! fn add(x: u8, y:u8) -> u8 {
//! x + y
//! }
//! ```
//! will become
//! ```
//! fn add(x: u8, y:u8) -> u8 {
//! x - y
//! }
//! ```
//! Then Darwin create a copy of the actual project and apply the modification on the copied file
//!
//! Once the project mutated, Darwin runs a `cargo build`, if the project compile, then the mutation is sustainable
//!
//! If so, Darwin runs the `cargo test`, There are 3 possibilities:
//! - project tests pass : the project is inefficiently tested as the mutation isn't catch
//! - tests fail : the project has at least one test which catches the mutation
//! - timeout : the mutation even if compiles, introduce a loop or something that makes the test run
//! forever
//!
//! ### Reports
//!
//! All reports can be found in the *mutation path* in a **reports** folder which.
//!
//! For example if you have run *darwin* with
//!
//! ```bash
//! cargo darwin --mutation-path /tmp/darwin /path/to/project/to/test
//! ```
//! You will get this tree
//!
//! ```bash
//! tmp/
//! ├─ darwin/
//! │ ├─ reports/
//! │ │ ├─ mutation_0.log
//! │ │ ├─ mutation_1.log
//! │ │ ├─ summary
//! │ ├─ 0/
//! │ ├─ 1/
//! ```
//!
//! #### Mutated projects
//!
//! If the `--keep` flag is defined, after tests, you can walk to generated projects
//!
//! Each one has a mutation ID and the associated mutation ID can be found in summary file
//!
//! #### Summary
//!
//! Summarize the mutation applied and the result of each.
//!
//! ```bash
//! [OK] : Mutation #0 replace - by + in function "sub" of file src\a\toto.rs at line 11:6
//! [OK] : Mutation #1 replace - by * in function "sub" of file src\a\toto.rs at line 11:6
//! [Killed] : Mutation #2 replace - by && in function "sub" of file src\a\toto.rs at line 11:6
//! [Missing] : Mutation #3 replace + by - in function "add" of file src\lib.rs at line 5:6
//! [Missing] : Mutation #4 replace + by * in function "add" of file src\lib.rs at line 5:6
//! [Missing] : Mutation #5 replace + by - in function "add" of file src\lib.rs at line 5:10
//! [Missing] : Mutation #6 replace + by * in function "add" of file src\lib.rs at line 5:10
//! ```
//!
//! For more information about the mutation, check the associated mutation_ID.log file
//!
//! #### Mutation report
//! `reports/mutation_X.log` files are the detailed view of the mutation.
//!
//! There are build with the following nomenclature
//! - Mutated file
//! - Mutation
//! - Mutation status
//! - Diff of the mutation
//! - Test or build output
//!
//! Below an example of output
//!
//! ```log
//! Mutation of file F:\Projets\Lab\Rust\darwin\playground\src\a\toto.rs
//! Mutation reason: replace - by *
//! Status : OK => Mutation Caught
//! Mutation diff:
//! @@ -8,7 +8,7 @@
//! //
//! fn sub(x: i8, y: i8) -> i8 {
//! let u = 8;
//! - x - y
//! + x * y
//! }
//!
//! Output:
//!
//! #[test]
//! stderr:
//! Compiling playground v0.1.0 (F:\Projets\Lab\Rust\darwin\tmp\1)
//! Finished test [unoptimized + debuginfo] target(s) in 0.18s
//! Running unittests src\lib.rs (target\debug\deps\playground-29148ab9d23d3c5d.exe)
//! error: test failed, to rerun pass `--lib`
//!
//! stdout:
//!
//! running 2 tests
//! test a::toto::test_sub ... FAILED
//! test a::toto::async_test_sub ... FAILED
//!
//! failures:
//!
//! ---- a::toto::test_sub stdout ----
//! thread 'a::toto::test_sub' panicked at src\a\toto.rs:16:5:
//! assertion `left == right` failed
//! left: 10
//! right: 3
//! note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
//!
//! ---- a::toto::async_test_sub stdout ----
//! thread 'a::toto::async_test_sub' panicked at src\a\toto.rs:21:5:
//! assertion `left == right` failed
//! left: 10
//! right: 3
//!
//!
//! failures:
//! a::toto::async_test_sub
//! a::toto::test_sub
//!
//! test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
//! ```
//!
//! As a test has failed, the mutation has been caught, so the code is enough tested for this particular mutation
//!
use fs;
use Parser;
use ;
use ;
use Mutation;
/// Display mutation but don't run tests
/// Main darwin function