-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Rustdoc json tests: New @ismany test command #99474
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,28 @@ | ||
// aux-build:pub-struct.rs | ||
// ignore-tidy-linelength | ||
|
||
// Test for the ICE in rust/83057 | ||
// Am external type re-exported with different attributes shouldn't cause an error | ||
// Test for the ICE in https://github.com/rust-lang/rust/issues/83057 | ||
// An external type re-exported with different attributes shouldn't cause an error | ||
|
||
#![no_core] | ||
#![feature(no_core)] | ||
|
||
extern crate pub_struct as foo; | ||
|
||
#[doc(inline)] | ||
|
||
// @set crate_use_id = private_twice_one_inline.json "$.index[*][?(@.docs=='Hack A')].id" | ||
// @set foo_id = - "$.index[*][?(@.docs=='Hack A')].inner.id" | ||
/// Hack A | ||
pub use foo::Foo; | ||
|
||
// @set bar_id = - "$.index[*][?(@.name=='bar')].id" | ||
pub mod bar { | ||
// @is - "$.index[*][?(@.docs=='Hack B')].inner.id" $foo_id | ||
// @set bar_use_id = - "$.index[*][?(@.docs=='Hack B')].id" | ||
// @ismany - "$.index[*][?(@.name=='bar')].inner.items[*]" $bar_use_id | ||
/// Hack B | ||
pub use foo::Foo; | ||
} | ||
|
||
// @count private_twice_one_inline.json "$.index[*][?(@.kind=='import')]" 2 | ||
// @ismany - "$.index[*][?(@.kind=='import')].id" $crate_use_id $bar_use_id | ||
// @ismany - "$.index[*][?(@.name=='private_twice_one_inline')].inner.items[*]" $bar_id $crate_use_id |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,23 @@ | ||
// ignore-tidy-linelength | ||
|
||
// Regression test for <https://github.com/rust-lang/rust/issues/97432>. | ||
|
||
#![feature(no_core)] | ||
#![no_std] | ||
#![no_core] | ||
|
||
// @has same_type_reexported_more_than_once.json | ||
// @has - "$.index[*][?(@.name=='Trait')]" | ||
pub use inner::Trait; | ||
// @has - "$.index[*].inner[?(@.name=='Reexport')].id" | ||
pub use inner::Trait as Reexport; | ||
|
||
mod inner { | ||
// @set trait_id = - "$.index[*][?(@.name=='Trait')].id" | ||
pub trait Trait {} | ||
} | ||
|
||
// @set export_id = - "$.index[*][?(@.inner.name=='Trait')].id" | ||
// @is - "$.index[*][?(@.inner.name=='Trait')].inner.id" $trait_id | ||
pub use inner::Trait; | ||
// @set reexport_id = - "$.index[*][?(@.inner.name=='Reexport')].id" | ||
// @is - "$.index[*][?(@.inner.name=='Reexport')].inner.id" $trait_id | ||
pub use inner::Trait as Reexport; | ||
|
||
// @ismany - "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.items[*]" $reexport_id $export_id |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,13 +50,15 @@ pub enum CommandKind { | |
Has, | ||
Count, | ||
Is, | ||
IsMany, | ||
Set, | ||
} | ||
|
||
impl CommandKind { | ||
fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool { | ||
let count = match self { | ||
CommandKind::Has => (1..=3).contains(&args.len()), | ||
CommandKind::IsMany => args.len() >= 3, | ||
CommandKind::Count | CommandKind::Is => 3 == args.len(), | ||
CommandKind::Set => 4 == args.len(), | ||
}; | ||
|
@@ -89,6 +91,7 @@ impl fmt::Display for CommandKind { | |
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
let text = match self { | ||
CommandKind::Has => "has", | ||
CommandKind::IsMany => "ismany", | ||
CommandKind::Count => "count", | ||
CommandKind::Is => "is", | ||
CommandKind::Set => "set", | ||
|
@@ -137,6 +140,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> { | |
"has" => CommandKind::Has, | ||
"count" => CommandKind::Count, | ||
"is" => CommandKind::Is, | ||
"ismany" => CommandKind::IsMany, | ||
"set" => CommandKind::Set, | ||
_ => { | ||
print_err(&format!("Unrecognized command name `@{}`", cmd), lineno); | ||
|
@@ -227,6 +231,44 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> { | |
_ => unreachable!(), | ||
} | ||
} | ||
CommandKind::IsMany => { | ||
// @ismany <path> <jsonpath> <value>... | ||
let (path, query, values) = if let [path, query, values @ ..] = &command.args[..] { | ||
(path, query, values) | ||
} else { | ||
unreachable!("Checked in CommandKind::validate") | ||
}; | ||
let val = cache.get_value(path)?; | ||
let got_values = select(&val, &query).unwrap(); | ||
assert!(!command.negated, "`@!ismany` is not supported"); | ||
|
||
// Serde json doesn't implement Ord or Hash for Value, so we must | ||
// use a Vec here. While in theory that makes setwize equality | ||
// O(n^2), in practice n will never be large enought to matter. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like a 'hasexact' would make me expect that it would check the order too, not just presence -- and that would avoid any question of n^2 comparison time. I agree that n^2 comparison time isn't itself an issue, though, so maybe this is fine as-is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It needs to not check order, as that's not a property that's stable, so the intension is to a setwise comparison.
|
||
let expected_values = | ||
values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>(); | ||
if expected_values.len() != got_values.len() { | ||
return Err(CkError::FailedCheck( | ||
format!( | ||
"Expected {} values, but `{}` matched to {} values ({:?})", | ||
expected_values.len(), | ||
query, | ||
got_values.len(), | ||
got_values | ||
), | ||
command, | ||
)); | ||
}; | ||
for got_value in got_values { | ||
if !expected_values.iter().any(|exp| &**exp == got_value) { | ||
return Err(CkError::FailedCheck( | ||
format!("`{}` has match {:?}, which was not expected", query, got_value), | ||
command, | ||
)); | ||
} | ||
} | ||
true | ||
} | ||
CommandKind::Count => { | ||
// @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times | ||
assert_eq!(command.args.len(), 3); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to nit-pick, but I wonder: Is it worth to use
-
instead of the whole filename? That messes up the alignment and makes the code harder to read, IMHO.Edit: Well, if all other lines use
-
then the alignment becomes good for them at least...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, most of the tests use
-
for all but the first item. (Side note, I should add a feature to set the-
to the obvious value initialy, because I don't think this is ever used, but just a hold over from the HTML side)