Skip to content

Commit 0491fda

Browse files
authored
Rollup merge of #99474 - aDotInTheVoid:rustdoc-json-noinline-test-cleanup, r=CraftSpider
Rustdoc json tests: New @hasexact test command Alot of the time, we wanted to assert that a module had an exact set of items. Most of the time this was done by asserting that the ```@count``` of the module was `n`, and then doing `n` ```@has``` checks on the module. This was tedious, so often shortcuts were done. This PR adds a new command to jsondocck to allow consistently expressing this behavior, and then uses it to clean up the tests. ``@rustbot`` modify labels: +A-rustdoc-json +A-testsuite
2 parents 86c6ebe + 760b972 commit 0491fda

13 files changed

+111
-39
lines changed

src/test/rustdoc-json/nested.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,28 @@
44
// @is nested.json "$.crate_version" \"1.0.0\"
55
// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
66
// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
7-
// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1
7+
8+
// @set l1_id = - "$.index[*][?(@.name=='l1')].id"
9+
// @ismany - "$.index[*][?(@.name=='nested')].inner.items[*]" $l1_id
810

911
// @is nested.json "$.index[*][?(@.name=='l1')].kind" \"module\"
1012
// @is - "$.index[*][?(@.name=='l1')].inner.is_crate" false
11-
// @count - "$.index[*][?(@.name=='l1')].inner.items[*]" 2
1213
pub mod l1 {
13-
1414
// @is nested.json "$.index[*][?(@.name=='l3')].kind" \"module\"
1515
// @is - "$.index[*][?(@.name=='l3')].inner.is_crate" false
16-
// @count - "$.index[*][?(@.name=='l3')].inner.items[*]" 1
1716
// @set l3_id = - "$.index[*][?(@.name=='l3')].id"
18-
// @has - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id
1917
pub mod l3 {
2018

2119
// @is nested.json "$.index[*][?(@.name=='L4')].kind" \"struct\"
2220
// @is - "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
2321
// @set l4_id = - "$.index[*][?(@.name=='L4')].id"
24-
// @has - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
22+
// @ismany - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
2523
pub struct L4;
2624
}
2725
// @is nested.json "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
2826
// @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
27+
// @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.id" $l4_id
28+
// @set l4_use_id = - "$.index[*][?(@.inner.source=='l3::L4')].id"
2929
pub use l3::L4;
3030
}
31+
// @ismany - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id $l4_use_id

src/test/rustdoc-json/reexport/glob_extern.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@
44
#![feature(no_core)]
55

66
// @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
7-
// @is glob_extern.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
7+
// @is - "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
88
mod mod1 {
99
extern "C" {
10-
// @has - "$.index[*][?(@.name=='public_fn')].id"
10+
// @set public_fn_id = - "$.index[*][?(@.name=='public_fn')].id"
1111
pub fn public_fn();
1212
// @!has - "$.index[*][?(@.name=='private_fn')]"
1313
fn private_fn();
1414
}
15+
// @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $public_fn_id
16+
// @set mod1_id = - "$.index[*][?(@.name=='mod1')].id"
1517
}
1618

1719
// @is - "$.index[*][?(@.kind=='import')].inner.glob" true
20+
// @is - "$.index[*][?(@.kind=='import')].inner.id" $mod1_id
21+
// @set use_id = - "$.index[*][?(@.kind=='import')].id"
22+
// @ismany - "$.index[*][?(@.name=='glob_extern')].inner.items[*]" $use_id
1823
pub use mod1::*;

src/test/rustdoc-json/reexport/glob_private.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ mod mod1 {
1616
struct Mod2Private;
1717
}
1818

19-
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')]"
19+
// @set mod2_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')].id"
2020
pub use self::mod2::*;
2121

2222
// @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
@@ -25,8 +25,9 @@ mod mod1 {
2525
struct Mod1Private;
2626
}
2727

28-
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')]"
28+
// @set mod1_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')].id"
2929
pub use mod1::*;
3030

31-
// @has - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
32-
// @has - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id
31+
// @ismany - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
32+
// @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id $mod2_use_id
33+
// @ismany - "$.index[*][?(@.name=='glob_private')].inner.items[*]" $mod1_use_id

src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
pub mod foo {
55
// @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
6-
// @has - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
6+
// @ismany - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
77
pub struct Bar;
88
}
99

@@ -15,6 +15,6 @@ pub use foo::Bar;
1515
pub mod baz {
1616
// @set baz_import_id = - "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
1717
// @is - "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
18-
// @has - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
18+
// @ismany - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
1919
pub use crate::foo::Bar;
2020
}

src/test/rustdoc-json/reexport/macro.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
#![no_core]
44
#![feature(no_core)]
55

6-
// @count macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" 2
7-
86
// @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
9-
// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id
107
#[macro_export]
118
macro_rules! repro {
129
() => {};
1310
}
1411

1512
// @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
16-
// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro2_id
1713
pub use crate::repro as repro2;
14+
15+
// @ismany macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id $repro2_id
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
// aux-build:pub-struct.rs
2+
// ignore-tidy-linelength
23

3-
// Test for the ICE in rust/83057
4-
// Am external type re-exported with different attributes shouldn't cause an error
4+
// Test for the ICE in https://github.com/rust-lang/rust/issues/83057
5+
// An external type re-exported with different attributes shouldn't cause an error
56

67
#![no_core]
78
#![feature(no_core)]
89

910
extern crate pub_struct as foo;
10-
1111
#[doc(inline)]
12+
13+
// @set crate_use_id = private_twice_one_inline.json "$.index[*][?(@.docs=='Hack A')].id"
14+
// @set foo_id = - "$.index[*][?(@.docs=='Hack A')].inner.id"
15+
/// Hack A
1216
pub use foo::Foo;
1317

18+
// @set bar_id = - "$.index[*][?(@.name=='bar')].id"
1419
pub mod bar {
20+
// @is - "$.index[*][?(@.docs=='Hack B')].inner.id" $foo_id
21+
// @set bar_use_id = - "$.index[*][?(@.docs=='Hack B')].id"
22+
// @ismany - "$.index[*][?(@.name=='bar')].inner.items[*]" $bar_use_id
23+
/// Hack B
1524
pub use foo::Foo;
1625
}
1726

18-
// @count private_twice_one_inline.json "$.index[*][?(@.kind=='import')]" 2
27+
// @ismany - "$.index[*][?(@.kind=='import')].id" $crate_use_id $bar_use_id
28+
// @ismany - "$.index[*][?(@.name=='private_twice_one_inline')].inner.items[*]" $bar_id $crate_use_id
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// Test for the ICE in rust/83720
1+
// ignore-tidy-linelength
2+
3+
// Test for the ICE in https://github.com/rust-lang/rust/issues/83720
24
// A pub-in-private type re-exported under two different names shouldn't cause an error
35

46
#![no_core]
@@ -7,11 +9,15 @@
79
// @is private_two_names.json "$.index[*][?(@.name=='style')].kind" \"module\"
810
// @is private_two_names.json "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
911
mod style {
10-
// @has - "$.index[*](?(@.name=='Color'))"
12+
// @set color_struct_id = - "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
1113
pub struct Color;
1214
}
1315

14-
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')]"
16+
// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].inner.id" $color_struct_id
17+
// @set color_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].id"
1518
pub use style::Color;
16-
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')]"
19+
// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].inner.id" $color_struct_id
20+
// @set colour_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].id"
1721
pub use style::Color as Colour;
22+
23+
// @ismany - "$.index[*][?(@.name=='private_two_names')].inner.items[*]" $color_export_id $colour_export_id

src/test/rustdoc-json/reexport/rename_public.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
#![feature(no_core)]
55

66
// @set inner_id = rename_public.json "$.index[*][?(@.name=='inner')].id"
7-
// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id
87
pub mod inner {
98
// @set public_id = - "$.index[*][?(@.name=='Public')].id"
10-
// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
9+
// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
1110
pub struct Public;
1211
}
1312
// @set import_id = - "$.index[*][?(@.inner.name=='NewName')].id"
1413
// @!has - "$.index[*][?(@.inner.name=='Public')]"
15-
// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $import_id
1614
// @is - "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
1715
pub use inner::Public as NewName;
16+
17+
// @ismany - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id $import_id
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1+
// ignore-tidy-linelength
2+
13
// Regression test for <https://github.com/rust-lang/rust/issues/97432>.
24

35
#![feature(no_core)]
46
#![no_std]
57
#![no_core]
68

79
// @has same_type_reexported_more_than_once.json
8-
// @has - "$.index[*][?(@.name=='Trait')]"
9-
pub use inner::Trait;
10-
// @has - "$.index[*].inner[?(@.name=='Reexport')].id"
11-
pub use inner::Trait as Reexport;
1210

1311
mod inner {
12+
// @set trait_id = - "$.index[*][?(@.name=='Trait')].id"
1413
pub trait Trait {}
1514
}
15+
16+
// @set export_id = - "$.index[*][?(@.inner.name=='Trait')].id"
17+
// @is - "$.index[*][?(@.inner.name=='Trait')].inner.id" $trait_id
18+
pub use inner::Trait;
19+
// @set reexport_id = - "$.index[*][?(@.inner.name=='Reexport')].id"
20+
// @is - "$.index[*][?(@.inner.name=='Reexport')].inner.id" $trait_id
21+
pub use inner::Trait as Reexport;
22+
23+
// @ismany - "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.items[*]" $reexport_id $export_id

src/test/rustdoc-json/reexport/simple_private.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ mod inner {
1010
}
1111

1212
// @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
13+
// @set use_id = - "$.index[*][?(@.kind=='import')].id"
1314
pub use inner::Public;
1415

15-
// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
16+
// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
17+
// @ismany - "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id

src/test/rustdoc-json/reexport/simple_public.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
#![feature(no_core)]
55

66
// @set inner_id = simple_public.json "$.index[*][?(@.name=='inner')].id"
7-
// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $inner_id
87
pub mod inner {
98

109
// @set public_id = - "$.index[*][?(@.name=='Public')].id"
11-
// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
10+
// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
1211
pub struct Public;
1312
}
1413

1514
// @set import_id = - "$.index[*][?(@.inner.name=='Public')].id"
16-
// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id
1715
// @is - "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
1816
pub use inner::Public;
17+
18+
// @ismany - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id $inner_id

src/test/rustdoc-json/type/fn_lifetime.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
// @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
44

5-
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*]" 1
6-
// @is - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
5+
// @ismany - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
76
// @has - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
87
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
98
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0

src/tools/jsondocck/src/main.rs

+42
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@ pub enum CommandKind {
5050
Has,
5151
Count,
5252
Is,
53+
IsMany,
5354
Set,
5455
}
5556

5657
impl CommandKind {
5758
fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool {
5859
let count = match self {
5960
CommandKind::Has => (1..=3).contains(&args.len()),
61+
CommandKind::IsMany => args.len() >= 3,
6062
CommandKind::Count | CommandKind::Is => 3 == args.len(),
6163
CommandKind::Set => 4 == args.len(),
6264
};
@@ -89,6 +91,7 @@ impl fmt::Display for CommandKind {
8991
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9092
let text = match self {
9193
CommandKind::Has => "has",
94+
CommandKind::IsMany => "ismany",
9295
CommandKind::Count => "count",
9396
CommandKind::Is => "is",
9497
CommandKind::Set => "set",
@@ -137,6 +140,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
137140
"has" => CommandKind::Has,
138141
"count" => CommandKind::Count,
139142
"is" => CommandKind::Is,
143+
"ismany" => CommandKind::IsMany,
140144
"set" => CommandKind::Set,
141145
_ => {
142146
print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
@@ -227,6 +231,44 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
227231
_ => unreachable!(),
228232
}
229233
}
234+
CommandKind::IsMany => {
235+
// @ismany <path> <jsonpath> <value>...
236+
let (path, query, values) = if let [path, query, values @ ..] = &command.args[..] {
237+
(path, query, values)
238+
} else {
239+
unreachable!("Checked in CommandKind::validate")
240+
};
241+
let val = cache.get_value(path)?;
242+
let got_values = select(&val, &query).unwrap();
243+
assert!(!command.negated, "`@!ismany` is not supported");
244+
245+
// Serde json doesn't implement Ord or Hash for Value, so we must
246+
// use a Vec here. While in theory that makes setwize equality
247+
// O(n^2), in practice n will never be large enought to matter.
248+
let expected_values =
249+
values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>();
250+
if expected_values.len() != got_values.len() {
251+
return Err(CkError::FailedCheck(
252+
format!(
253+
"Expected {} values, but `{}` matched to {} values ({:?})",
254+
expected_values.len(),
255+
query,
256+
got_values.len(),
257+
got_values
258+
),
259+
command,
260+
));
261+
};
262+
for got_value in got_values {
263+
if !expected_values.iter().any(|exp| &**exp == got_value) {
264+
return Err(CkError::FailedCheck(
265+
format!("`{}` has match {:?}, which was not expected", query, got_value),
266+
command,
267+
));
268+
}
269+
}
270+
true
271+
}
230272
CommandKind::Count => {
231273
// @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
232274
assert_eq!(command.args.len(), 3);

0 commit comments

Comments
 (0)