@@ -5,7 +5,7 @@ our first task before implementing any logic for a new lint is to write some tes
5
5
6
6
## Develop Lints with Tests
7
7
8
- When we develop Clippy, we enter a complex and chaotic realm full of
8
+ When we develop Clippy, we enter a complex and chaotic realm full of
9
9
programmatic issues, stylistic errors, illogical code and non-adherence to convention.
10
10
Tests are the first layer of order we can leverage to define when and where
11
11
we want a new lint to trigger or not.
@@ -18,23 +18,25 @@ This approach empowers us to iteratively enhance each lint.
18
18
19
19
## Clippy UI Tests
20
20
21
- We use ** UI tests** for testing in Clippy.
22
- These UI tests check that the output of Clippy is exactly as we expect it to be.
23
- Each test is just a plain Rust file that contains the code we want to check.
21
+ We use ** UI tests** for testing in Clippy. These UI tests check that the output
22
+ of Clippy is exactly as we expect it to be. Each test is just a plain Rust file
23
+ that contains the code we want to check.
24
24
25
- The output of Clippy is compared against a ` .stderr ` file.
26
- Note that you don't have to create this file yourself.
27
- We'll get to generating the ` .stderr ` files with the command [ ` cargo dev bless ` ] ( #cargo-dev-bless ) (seen later on).
25
+ The output of Clippy is compared against a ` .stderr ` file. Note that you don't
26
+ have to create this file yourself. We'll get to generating the ` .stderr ` files
27
+ with the command [ ` cargo dev bless ` ] ( #cargo-dev-bless ) (seen later on).
28
28
29
29
### Write Test Cases
30
30
31
- Let us now think about some tests for our imaginary ` foo_functions ` lint,
32
- We start by opening the test file ` tests/ui/foo_functions.rs ` that was created by ` cargo dev new_lint ` .
31
+ Let us now think about some tests for our imaginary ` foo_functions ` lint. We
32
+ start by opening the test file ` tests/ui/foo_functions.rs ` that was created by
33
+ ` cargo dev new_lint ` .
33
34
34
35
Update the file with some examples to get started:
35
36
36
37
``` rust
37
- #![warn(clippy:: foo_functions)]
38
+ #![warn(clippy:: foo_functions)] // < Add this, so the lint is guaranteed to be enabled in this file
39
+
38
40
// Impl methods
39
41
struct A ;
40
42
impl A {
@@ -64,8 +66,8 @@ fn main() {
64
66
```
65
67
66
68
Without actual lint logic to emit the lint when we see a ` foo ` function name,
67
- these tests are still quite meaningless.
68
- However, we can now run the test with the following command:
69
+ this test will just pass, because no lint will be emitted. However, we can now
70
+ run the test with the following command:
69
71
70
72
``` sh
71
73
$ TESTNAME=foo_functions cargo uitest
@@ -118,10 +120,12 @@ LL | fn foo() {}
118
120
error: aborting due to 3 previous errors
119
121
```
120
122
121
- Note the * failures* label at the top of the fragment, we'll get rid of it (saving this output) in the next section.
123
+ Note the * failures* label at the top of the fragment, we'll get rid of it
124
+ (saving this output) in the next section.
122
125
123
126
> _ Note:_ You can run multiple test files by specifying a comma separated list:
124
127
> ` TESTNAME=foo_functions,bar_methods,baz_structs ` .
128
+
125
129
### ` cargo dev bless `
126
130
127
131
Once we are satisfied with the output, we need to run this command to
@@ -136,23 +140,39 @@ $ cargo dev bless
136
140
This write the emitted lint suggestions and fixes to the ` .stderr ` file,
137
141
with the reason for the lint, suggested fixes, and line numbers, etc.
138
142
139
- > _ Note:_ we need to run ` TESTNAME=foo_functions cargo uitest ` every time before we run
140
- > ` cargo dev bless ` .
143
+ > _ Note:_ we need to run ` TESTNAME=foo_functions cargo uitest ` every time before
144
+ > we run ` cargo dev bless ` .
141
145
142
- Running ` TESTNAME=foo_functions cargo uitest ` should pass then. When we
143
- commit our lint, we need to commit the generated ` .stderr ` files, too.
146
+ Running ` TESTNAME=foo_functions cargo uitest ` should pass then. When we commit
147
+ our lint, we need to commit the generated ` .stderr ` files, too.
144
148
145
149
In general, you should only commit files changed by ` cargo dev bless ` for the
146
150
specific lint you are creating/editing.
147
151
148
152
> _ Note:_ If the generated ` .stderr ` , and ` .fixed ` files are empty,
149
153
> they should be removed.
150
154
155
+ ## ` toml ` Tests
156
+
157
+ Some lints can be configured through a ` clippy.toml ` file. Those configuration
158
+ values are tested in ` tests/ui-toml ` .
159
+
160
+ To add a new test there, create a new directory and add the files:
161
+
162
+ - ` clippy.toml ` : Put here the configuration value you want to test.
163
+ - ` lint_name.rs ` : A test file where you put the testing code, that should see a
164
+ different lint behavior according to the configuration set in the
165
+ ` clippy.toml ` file.
166
+
167
+ The potential ` .stderr ` and ` .fixed ` files can again be generated with `cargo
168
+ dev bless`.
169
+
151
170
## Cargo Lints
152
171
153
172
The process of testing is different for Cargo lints in that now we are
154
- interested in the ` Cargo.toml ` manifest file.
155
- In this case, we also need a minimal crate associated with that manifest.
173
+ interested in the ` Cargo.toml ` manifest file. In this case, we also need a
174
+ minimal crate associated with that manifest. Those tests are generated in
175
+ ` tests/ui-cargo ` .
156
176
157
177
Imagine we have a new example lint that is named ` foo_categories ` , we can run:
158
178
@@ -168,46 +188,33 @@ each with its manifest file:
168
188
* ` tests/ui-cargo/foo_categories/pass/Cargo.toml ` : this file should not trigger
169
189
the lint.
170
190
171
- If you need more cases, you can copy one of those crates (under ` foo_categories ` ) and rename it.
191
+ If you need more cases, you can copy one of those crates (under
192
+ ` foo_categories ` ) and rename it.
172
193
173
- The process of generating the ` .stderr ` file is the same as for other lints
194
+ The process of generating the ` .stderr ` file is the same as for other lints
174
195
and prepending the ` TESTNAME ` variable to ` cargo uitest ` works for Cargo lints too.
175
196
176
- Overall, you should see the following changes when you generate a new Cargo lint:
177
-
178
- ``` sh
179
- $ git status
180
- On branch foo_categories
181
- Changes not staged for commit:
182
- (use " git add <file>..." to update what will be committed)
183
- (use " git restore <file>..." to discard changes in working directory)
184
- modified: CHANGELOG.md
185
- modified: clippy_lints/src/cargo/mod.rs
186
- modified: clippy_lints/src/lib.rs
187
- Untracked files:
188
- (use " git add <file>..." to include in what will be committed)
189
- clippy_lints/src/cargo/foo_categories.rs
190
- tests/ui-cargo/foo_categories/
191
- ```
192
-
193
197
## Rustfix Tests
194
198
195
199
If the lint you are working on is making use of structured suggestions, the test
196
200
file should include a ` // run-rustfix ` comment at the top.
197
201
198
- Structured suggestions tell a user how to fix or re-write certain code that has been linted, they are usually linted
199
- with [ ` span_lint_and_sugg ` ] ( https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html ) .
202
+ Structured suggestions tell a user how to fix or re-write certain code that has
203
+ been linted with [ ` span_lint_and_sugg ` ] .
200
204
201
205
The ` // run-rustfix ` comment will additionally run [ rustfix] for our test.
202
206
Rustfix will apply the suggestions from the lint to the test file code and
203
207
compare that to the contents of a ` .fixed ` file.
204
208
205
209
We'll talk about suggestions more in depth in a later chapter.
206
- <!-- FIXME: (blyyas ) Link to "Emitting lints" when that gets merged -->
210
+ <!-- FIXME: (blyxyas ) Link to "Emitting lints" when that gets merged -->
207
211
208
- Use ` cargo dev bless ` to automatically generate the ` .fixed ` file after running the tests.
212
+ Use ` cargo dev bless ` to automatically generate the ` .fixed ` file after running
213
+ the tests.
209
214
210
215
[ rustfix ] : https://github.com/rust-lang/rustfix
216
+ [ `span_lint_and_sugg` ] : https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html
217
+
211
218
## Testing Manually
212
219
213
220
Manually testing against an example file can be useful if you have added some
0 commit comments