Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement struct_now_doc_hidden lint #587

Merged
merged 15 commits into from
Nov 28, 2023
Merged
50 changes: 50 additions & 0 deletions src/lints/struct_now_doc_hidden.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
SemverQuery(
id: "struct_now_doc_hidden",
human_readable_name: "pub struct is now #[doc(hidden)]",
description: "A pub struct is now hidden from documentation effectively removing it from the crate's public api.",
u9g marked this conversation as resolved.
Show resolved Hide resolved
required_update: Major,
reference_link: Some("https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html#hidden"),
query: r#"
{
CrateDiff {
baseline {
item {
... on Struct {
visibility_limit @filter(op: "=", value: ["$public"])
struct_type @output @tag

importable_path {
path @output @tag
public_api @filter(op: "=", value: ["$true"])
}
}
}
}
current {
item {
... on Struct {
visibility_limit @filter(op: "=", value: ["$public"])
struct_name: name @output
struct_type @filter(op: "=", value: ["%struct_type"])
u9g marked this conversation as resolved.
Show resolved Hide resolved

importable_path {
path @filter(op: "=", value: ["%path"])
public_api @filter(op: "!=", value: ["$true"])
}

span_: span @optional {
filename @output
begin_line @output
}
}
}
}
}
}"#,
arguments: {
"public": "public",
"true": true,
},
error_message: "A publicly visible struct is now hidden via #[doc(hidden)].",
u9g marked this conversation as resolved.
Show resolved Hide resolved
per_result_error_template: Some("Struct {{struct_name}} in file {{span_filename}}:{{span_begin_line}}"),
u9g marked this conversation as resolved.
Show resolved Hide resolved
)
1 change: 1 addition & 0 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ add_lints!(
struct_marked_non_exhaustive,
struct_missing,
struct_must_use_added,
struct_now_doc_hidden,
struct_pub_field_missing,
struct_repr_c_removed,
struct_repr_transparent_removed,
Expand Down
7 changes: 7 additions & 0 deletions test_crates/struct_now_doc_hidden/new/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "struct_now_doc_hidden"
version = "0.1.0"
edition = "2021"

[dependencies]
4 changes: 4 additions & 0 deletions test_crates/struct_now_doc_hidden/new/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct StayingKnown;

#[doc(hidden)]
pub struct Example;
7 changes: 7 additions & 0 deletions test_crates/struct_now_doc_hidden/old/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
publish = false
name = "struct_now_doc_hidden"
version = "0.1.0"
edition = "2021"

[dependencies]
3 changes: 3 additions & 0 deletions test_crates/struct_now_doc_hidden/old/src/lib.rs
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test cases are fine, but please do try to think of some more edge cases to test for. Simple lints like this are great for practicing those skills!

One trick to help you think of test cases that is called "mutation testing." Take the correct lint you've implemented, and intentionally introduce a bug into it: for example, delete a filter clause, change a filter operator, or add an unnecessary filter or edge traversal somewhere. Then run the tests and see if they catch the bug.

You know you have good test coverage when no matter what bug you introduce, the tests always catch it.

After some practice, you'll be able to run this process "in your head" without actually modifying the lint, and you'll be able to directly write sufficient test cases to catch most reasonable bugs. At the moment, I think there are several plausible ways to accidentally mis-implement this lint that I don't think our test suite as a whole will catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good point, I went ahead and tried to get rid of some lines in the lint which actually ended up being optional entirely :)

In terms of tests, I added a bunch more tests that should make it a lot harder to mis-implement this rule.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
struct StayingKnown;
u9g marked this conversation as resolved.
Show resolved Hide resolved

pub struct Example;
46 changes: 46 additions & 0 deletions test_outputs/struct_now_doc_hidden.output.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"./test_crates/struct_now_doc_hidden/": [
{
"path": List([
String("struct_now_doc_hidden"),
String("Example"),
]),
"span_begin_line": Uint64(4),
"span_filename": String("src/lib.rs"),
"struct_name": String("Example"),
"struct_type": String("unit"),
},
],
"./test_crates/type_hidden_from_public_api/": [
{
"path": List([
String("type_hidden_from_public_api"),
String("ExamplePlainStruct"),
]),
"span_begin_line": Uint64(2),
"span_filename": String("src/lib.rs"),
"struct_name": String("ExamplePlainStruct"),
"struct_type": String("plain"),
},
{
"path": List([
String("type_hidden_from_public_api"),
String("ExampleTupleStruct"),
]),
"span_begin_line": Uint64(7),
"span_filename": String("src/lib.rs"),
"struct_name": String("ExampleTupleStruct"),
"struct_type": String("tuple"),
},
{
"path": List([
String("type_hidden_from_public_api"),
String("ExampleUnitStruct"),
]),
"span_begin_line": Uint64(10),
"span_filename": String("src/lib.rs"),
"struct_name": String("ExampleUnitStruct"),
"struct_type": String("unit"),
},
],
}
u9g marked this conversation as resolved.
Show resolved Hide resolved
Loading