mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
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
This commit is contained in:
commit
0491fdad6f
@ -4,27 +4,28 @@
|
|||||||
// @is nested.json "$.crate_version" \"1.0.0\"
|
// @is nested.json "$.crate_version" \"1.0.0\"
|
||||||
// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
|
// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
|
||||||
// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
|
// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
|
||||||
// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1
|
|
||||||
|
// @set l1_id = - "$.index[*][?(@.name=='l1')].id"
|
||||||
|
// @ismany - "$.index[*][?(@.name=='nested')].inner.items[*]" $l1_id
|
||||||
|
|
||||||
// @is nested.json "$.index[*][?(@.name=='l1')].kind" \"module\"
|
// @is nested.json "$.index[*][?(@.name=='l1')].kind" \"module\"
|
||||||
// @is - "$.index[*][?(@.name=='l1')].inner.is_crate" false
|
// @is - "$.index[*][?(@.name=='l1')].inner.is_crate" false
|
||||||
// @count - "$.index[*][?(@.name=='l1')].inner.items[*]" 2
|
|
||||||
pub mod l1 {
|
pub mod l1 {
|
||||||
|
|
||||||
// @is nested.json "$.index[*][?(@.name=='l3')].kind" \"module\"
|
// @is nested.json "$.index[*][?(@.name=='l3')].kind" \"module\"
|
||||||
// @is - "$.index[*][?(@.name=='l3')].inner.is_crate" false
|
// @is - "$.index[*][?(@.name=='l3')].inner.is_crate" false
|
||||||
// @count - "$.index[*][?(@.name=='l3')].inner.items[*]" 1
|
|
||||||
// @set l3_id = - "$.index[*][?(@.name=='l3')].id"
|
// @set l3_id = - "$.index[*][?(@.name=='l3')].id"
|
||||||
// @has - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id
|
|
||||||
pub mod l3 {
|
pub mod l3 {
|
||||||
|
|
||||||
// @is nested.json "$.index[*][?(@.name=='L4')].kind" \"struct\"
|
// @is nested.json "$.index[*][?(@.name=='L4')].kind" \"struct\"
|
||||||
// @is - "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
|
// @is - "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
|
||||||
// @set l4_id = - "$.index[*][?(@.name=='L4')].id"
|
// @set l4_id = - "$.index[*][?(@.name=='L4')].id"
|
||||||
// @has - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
|
// @ismany - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
|
||||||
pub struct L4;
|
pub struct L4;
|
||||||
}
|
}
|
||||||
// @is nested.json "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
|
// @is nested.json "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
|
||||||
// @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
|
// @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
|
||||||
|
// @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.id" $l4_id
|
||||||
|
// @set l4_use_id = - "$.index[*][?(@.inner.source=='l3::L4')].id"
|
||||||
pub use l3::L4;
|
pub use l3::L4;
|
||||||
}
|
}
|
||||||
|
// @ismany - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id $l4_use_id
|
||||||
|
@ -4,15 +4,20 @@
|
|||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
// @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
|
// @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
|
||||||
// @is glob_extern.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
|
// @is - "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
|
||||||
mod mod1 {
|
mod mod1 {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// @has - "$.index[*][?(@.name=='public_fn')].id"
|
// @set public_fn_id = - "$.index[*][?(@.name=='public_fn')].id"
|
||||||
pub fn public_fn();
|
pub fn public_fn();
|
||||||
// @!has - "$.index[*][?(@.name=='private_fn')]"
|
// @!has - "$.index[*][?(@.name=='private_fn')]"
|
||||||
fn private_fn();
|
fn private_fn();
|
||||||
}
|
}
|
||||||
|
// @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $public_fn_id
|
||||||
|
// @set mod1_id = - "$.index[*][?(@.name=='mod1')].id"
|
||||||
}
|
}
|
||||||
|
|
||||||
// @is - "$.index[*][?(@.kind=='import')].inner.glob" true
|
// @is - "$.index[*][?(@.kind=='import')].inner.glob" true
|
||||||
|
// @is - "$.index[*][?(@.kind=='import')].inner.id" $mod1_id
|
||||||
|
// @set use_id = - "$.index[*][?(@.kind=='import')].id"
|
||||||
|
// @ismany - "$.index[*][?(@.name=='glob_extern')].inner.items[*]" $use_id
|
||||||
pub use mod1::*;
|
pub use mod1::*;
|
||||||
|
@ -16,7 +16,7 @@ mod mod1 {
|
|||||||
struct Mod2Private;
|
struct Mod2Private;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')]"
|
// @set mod2_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')].id"
|
||||||
pub use self::mod2::*;
|
pub use self::mod2::*;
|
||||||
|
|
||||||
// @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
|
// @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
|
||||||
@ -25,8 +25,9 @@ mod mod1 {
|
|||||||
struct Mod1Private;
|
struct Mod1Private;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')]"
|
// @set mod1_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')].id"
|
||||||
pub use mod1::*;
|
pub use mod1::*;
|
||||||
|
|
||||||
// @has - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
|
// @ismany - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
|
||||||
// @has - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id
|
// @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id $mod2_use_id
|
||||||
|
// @ismany - "$.index[*][?(@.name=='glob_private')].inner.items[*]" $mod1_use_id
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
pub mod foo {
|
pub mod foo {
|
||||||
// @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
|
// @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
|
||||||
// @has - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
|
// @ismany - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
|
||||||
pub struct Bar;
|
pub struct Bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,6 +15,6 @@ pub use foo::Bar;
|
|||||||
pub mod baz {
|
pub mod baz {
|
||||||
// @set baz_import_id = - "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
|
// @set baz_import_id = - "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
|
||||||
// @is - "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
|
// @is - "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
|
||||||
// @has - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
|
// @ismany - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
|
||||||
pub use crate::foo::Bar;
|
pub use crate::foo::Bar;
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,13 @@
|
|||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
// @count macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" 2
|
|
||||||
|
|
||||||
// @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
|
// @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
|
||||||
// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! repro {
|
macro_rules! repro {
|
||||||
() => {};
|
() => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
|
// @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
|
||||||
// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro2_id
|
|
||||||
pub use crate::repro as repro2;
|
pub use crate::repro as repro2;
|
||||||
|
|
||||||
|
// @ismany macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id $repro2_id
|
||||||
|
@ -1,18 +1,28 @@
|
|||||||
// aux-build:pub-struct.rs
|
// aux-build:pub-struct.rs
|
||||||
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
// Test for the ICE in rust/83057
|
// Test for the ICE in https://github.com/rust-lang/rust/issues/83057
|
||||||
// Am external type re-exported with different attributes shouldn't cause an error
|
// An external type re-exported with different attributes shouldn't cause an error
|
||||||
|
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
extern crate pub_struct as foo;
|
extern crate pub_struct as foo;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[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;
|
pub use foo::Foo;
|
||||||
|
|
||||||
|
// @set bar_id = - "$.index[*][?(@.name=='bar')].id"
|
||||||
pub mod bar {
|
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;
|
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
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
// Test for the ICE in rust/83720
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
|
// Test for the ICE in https://github.com/rust-lang/rust/issues/83720
|
||||||
// A pub-in-private type re-exported under two different names shouldn't cause an error
|
// A pub-in-private type re-exported under two different names shouldn't cause an error
|
||||||
|
|
||||||
#![no_core]
|
#![no_core]
|
||||||
@ -7,11 +9,15 @@
|
|||||||
// @is private_two_names.json "$.index[*][?(@.name=='style')].kind" \"module\"
|
// @is private_two_names.json "$.index[*][?(@.name=='style')].kind" \"module\"
|
||||||
// @is private_two_names.json "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
|
// @is private_two_names.json "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
|
||||||
mod style {
|
mod style {
|
||||||
// @has - "$.index[*](?(@.name=='Color'))"
|
// @set color_struct_id = - "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
|
||||||
pub struct Color;
|
pub struct Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')]"
|
// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].inner.id" $color_struct_id
|
||||||
|
// @set color_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].id"
|
||||||
pub use style::Color;
|
pub use style::Color;
|
||||||
// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')]"
|
// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].inner.id" $color_struct_id
|
||||||
|
// @set colour_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].id"
|
||||||
pub use style::Color as Colour;
|
pub use style::Color as Colour;
|
||||||
|
|
||||||
|
// @ismany - "$.index[*][?(@.name=='private_two_names')].inner.items[*]" $color_export_id $colour_export_id
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
// @set inner_id = rename_public.json "$.index[*][?(@.name=='inner')].id"
|
// @set inner_id = rename_public.json "$.index[*][?(@.name=='inner')].id"
|
||||||
// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id
|
|
||||||
pub mod inner {
|
pub mod inner {
|
||||||
// @set public_id = - "$.index[*][?(@.name=='Public')].id"
|
// @set public_id = - "$.index[*][?(@.name=='Public')].id"
|
||||||
// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
|
// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
|
||||||
pub struct Public;
|
pub struct Public;
|
||||||
}
|
}
|
||||||
// @set import_id = - "$.index[*][?(@.inner.name=='NewName')].id"
|
// @set import_id = - "$.index[*][?(@.inner.name=='NewName')].id"
|
||||||
// @!has - "$.index[*][?(@.inner.name=='Public')]"
|
// @!has - "$.index[*][?(@.inner.name=='Public')]"
|
||||||
// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $import_id
|
|
||||||
// @is - "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
|
// @is - "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
|
||||||
pub use inner::Public as NewName;
|
pub use inner::Public as NewName;
|
||||||
|
|
||||||
|
// @ismany - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id $import_id
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
// Regression test for <https://github.com/rust-lang/rust/issues/97432>.
|
// Regression test for <https://github.com/rust-lang/rust/issues/97432>.
|
||||||
|
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
@ -5,11 +7,17 @@
|
|||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
// @has same_type_reexported_more_than_once.json
|
// @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 {
|
mod inner {
|
||||||
|
// @set trait_id = - "$.index[*][?(@.name=='Trait')].id"
|
||||||
pub trait Trait {}
|
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
|
||||||
|
@ -10,6 +10,8 @@ mod inner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
|
// @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
|
||||||
|
// @set use_id = - "$.index[*][?(@.kind=='import')].id"
|
||||||
pub use inner::Public;
|
pub use inner::Public;
|
||||||
|
|
||||||
// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
|
// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
|
||||||
|
// @ismany - "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
|
|
||||||
// @set inner_id = simple_public.json "$.index[*][?(@.name=='inner')].id"
|
// @set inner_id = simple_public.json "$.index[*][?(@.name=='inner')].id"
|
||||||
// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $inner_id
|
|
||||||
pub mod inner {
|
pub mod inner {
|
||||||
|
|
||||||
// @set public_id = - "$.index[*][?(@.name=='Public')].id"
|
// @set public_id = - "$.index[*][?(@.name=='Public')].id"
|
||||||
// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
|
// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
|
||||||
pub struct Public;
|
pub struct Public;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @set import_id = - "$.index[*][?(@.inner.name=='Public')].id"
|
// @set import_id = - "$.index[*][?(@.inner.name=='Public')].id"
|
||||||
// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id
|
|
||||||
// @is - "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
|
// @is - "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
|
||||||
pub use inner::Public;
|
pub use inner::Public;
|
||||||
|
|
||||||
|
// @ismany - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id $inner_id
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
// @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
|
// @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
|
||||||
|
|
||||||
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*]" 1
|
// @ismany - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
|
||||||
// @is - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
|
|
||||||
// @has - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
|
// @has - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
|
||||||
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
|
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
|
||||||
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
|
// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
|
||||||
|
@ -50,6 +50,7 @@ pub enum CommandKind {
|
|||||||
Has,
|
Has,
|
||||||
Count,
|
Count,
|
||||||
Is,
|
Is,
|
||||||
|
IsMany,
|
||||||
Set,
|
Set,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ impl CommandKind {
|
|||||||
fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool {
|
fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool {
|
||||||
let count = match self {
|
let count = match self {
|
||||||
CommandKind::Has => (1..=3).contains(&args.len()),
|
CommandKind::Has => (1..=3).contains(&args.len()),
|
||||||
|
CommandKind::IsMany => args.len() >= 3,
|
||||||
CommandKind::Count | CommandKind::Is => 3 == args.len(),
|
CommandKind::Count | CommandKind::Is => 3 == args.len(),
|
||||||
CommandKind::Set => 4 == 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 {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let text = match self {
|
let text = match self {
|
||||||
CommandKind::Has => "has",
|
CommandKind::Has => "has",
|
||||||
|
CommandKind::IsMany => "ismany",
|
||||||
CommandKind::Count => "count",
|
CommandKind::Count => "count",
|
||||||
CommandKind::Is => "is",
|
CommandKind::Is => "is",
|
||||||
CommandKind::Set => "set",
|
CommandKind::Set => "set",
|
||||||
@ -137,6 +140,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
|
|||||||
"has" => CommandKind::Has,
|
"has" => CommandKind::Has,
|
||||||
"count" => CommandKind::Count,
|
"count" => CommandKind::Count,
|
||||||
"is" => CommandKind::Is,
|
"is" => CommandKind::Is,
|
||||||
|
"ismany" => CommandKind::IsMany,
|
||||||
"set" => CommandKind::Set,
|
"set" => CommandKind::Set,
|
||||||
_ => {
|
_ => {
|
||||||
print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
|
print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
|
||||||
@ -227,6 +231,44 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
|
|||||||
_ => unreachable!(),
|
_ => 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.
|
||||||
|
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 => {
|
CommandKind::Count => {
|
||||||
// @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
|
// @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
|
||||||
assert_eq!(command.args.len(), 3);
|
assert_eq!(command.args.len(), 3);
|
||||||
|
Loading…
Reference in New Issue
Block a user