Skip to content

Commit b119b65

Browse files
committed
tests: add test that roughly ensures that our lint messages conform with the diagnostics convention of the rustc dev guide
lint message should not start with uppercase letters lint messages should not have punctuation at the end of the last line https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure The test reads through all the .stderr files in the testsuit and checks lint messages that start with "help: ", "error: " etc. There is also an exception list for special messages that are deemed acceptable. changelog: make sure lint messages conform with the rustc dev guide and add test
1 parent abd2c7e commit b119b65

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ tester = "0.9"
4242
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }
4343
serde = { version = "1.0", features = ["derive"] }
4444
derive-new = "0.5"
45+
regex = "1.4"
4546

4647
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
4748
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

tests/lint_message_convention.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use std::path::PathBuf;
2+
3+
use regex::RegexSet;
4+
5+
#[derive(Debug)]
6+
struct Message {
7+
path: PathBuf,
8+
bad_lines: Vec<String>,
9+
}
10+
11+
impl Message {
12+
fn new(path: PathBuf) -> Self {
13+
let content: String = std::fs::read_to_string(&path).unwrap();
14+
// we don't want the first letter after "error: ", "help: " ... to be capitalized
15+
// also no puncutation (except for "?" ?) at the end of a line
16+
let regex_set: RegexSet = RegexSet::new(&[
17+
r"error: [A-Z]",
18+
r"help: [A-Z]",
19+
r"warning: [A-Z]",
20+
r"note: [A-Z]",
21+
r"try this: [A-Z]",
22+
r"error: .*[.!]$",
23+
r"help: .*[.!]$",
24+
r"warning: .*[.!]$",
25+
r"note: .*[.!]$",
26+
r"try this: .*[.!]$",
27+
])
28+
.unwrap();
29+
30+
// sometimes the first character is capitalized and it is legal (like in "Iterator...") or
31+
// we want to ask a question ending in "?"
32+
let exceptions_set: RegexSet = RegexSet::new(&[
33+
r".*error: I see you're using a LinkedList! Perhaps you meant some other data structure?",
34+
r".*C-like enum variant discriminant is not portable to 32-bit targets",
35+
r".*Iterator::step_by(0) will panic at runtime",
36+
r".*did you mean `unix`?",
37+
r".*the arguments may be inverted...",
38+
r".*Intel x86 assembly syntax used",
39+
r".*AT&T x86 assembly syntax used",
40+
r".*remove .* the return type...",
41+
r"note: Clippy version: .*",
42+
])
43+
.unwrap();
44+
45+
let bad_lines = content
46+
.lines()
47+
.filter(|line| regex_set.matches(line).matched_any())
48+
// ignore exceptions
49+
.filter(|line| !exceptions_set.matches(line).matched_any())
50+
.map(|s| s.to_owned())
51+
.collect::<Vec<String>>();
52+
53+
Message { path, bad_lines }
54+
}
55+
}
56+
57+
#[test]
58+
fn lint_message_convention() {
59+
// make sure that lint messages:
60+
// * are not capitalized
61+
// * don't have puncuation at the end of the last sentence
62+
63+
// these directories have interesting tests
64+
let test_dirs = ["ui", "ui-cargo", "ui-internal", "ui-toml"]
65+
.iter()
66+
.map(PathBuf::from)
67+
.map(|p| {
68+
let base = PathBuf::from("tests");
69+
base.join(p)
70+
});
71+
72+
// gather all .stderr files
73+
let tests = test_dirs
74+
.map(|dir| {
75+
std::fs::read_dir(dir)
76+
.expect("failed to read dir")
77+
.map(|direntry| direntry.unwrap().path())
78+
})
79+
.flatten()
80+
.filter(|file| matches!(file.extension().map(|s| s.to_str()), Some(Some("stderr"))));
81+
82+
// get all files that have any "bad lines" in them
83+
let bad_tests: Vec<Message> = tests
84+
.map(|path| Message::new(path))
85+
.filter(|message| !message.bad_lines.is_empty())
86+
.collect();
87+
88+
bad_tests.iter().for_each(|message| {
89+
eprintln!(
90+
"error: the test '{}' contained the following nonconforming lines :",
91+
message.path.display()
92+
);
93+
message.bad_lines.iter().for_each(|line| eprintln!("{}", line));
94+
eprintln!("\n\n");
95+
});
96+
97+
eprintln!("\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed.");
98+
eprintln!("Check out the rustc-dev-guide for more information:");
99+
eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure");
100+
101+
assert!(bad_tests.is_empty());
102+
}

0 commit comments

Comments
 (0)