Improve mock_impl_runtime_apis! (#7370)

* Improve `mock_impl_runtime_apis!`

This adds a new attribute for functions being implemented in the
`mock_impl_runtime_apis!` macro, the `advanced` attribute. When this
attribute is given the user gets access to the `at` parameter and is
able to return a `Result`, instead of letting the macro generate this
stuff.

* Use the `at_param_name` directly

* Prevent clashing of `params`
This commit is contained in:
Bastian Köcher
2020-10-22 21:09:13 +02:00
committed by GitHub
parent d847c9b019
commit 79be077774
9 changed files with 287 additions and 46 deletions
@@ -19,9 +19,8 @@ use sp_api::{
RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis,
ApiExt,
};
use sp_runtime::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId};
use sp_core::NativeOrEncoded;
use substrate_test_runtime_client::runtime::Block;
use sp_blockchain::Result;
@@ -103,9 +102,20 @@ mock_impl_runtime_apis! {
unimplemented!()
}
fn same_name() {}
#[advanced]
fn same_name(_: &BlockId<Block>) -> std::result::Result<NativeOrEncoded<()>, String> {
Ok(().into())
}
fn wild_card(_: u32) {}
#[advanced]
fn wild_card(at: &BlockId<Block>, _: u32) -> std::result::Result<NativeOrEncoded<()>, String> {
if let BlockId::Number(1337) = at {
// yeah
Ok(().into())
} else {
Err("Ohh noooo".into())
}
}
}
impl ApiWithCustomVersion<Block> for MockApi {
@@ -180,3 +190,12 @@ fn mock_runtime_api_panics_on_calling_old_version() {
#[allow(deprecated)]
let _ = mock.same_name_before_version_2(&BlockId::Number(0));
}
#[test]
fn mock_runtime_api_works_with_advanced() {
let mock = MockApi { block: None };
Api::<Block>::same_name(&mock, &BlockId::Number(0)).unwrap();
mock.wild_card(&BlockId::Number(1337), 1).unwrap();
assert_eq!(String::from("Ohh noooo"), mock.wild_card(&BlockId::Number(1336), 1).unwrap_err());
}
@@ -0,0 +1,20 @@
use substrate_test_runtime_client::runtime::Block;
sp_api::decl_runtime_apis! {
pub trait Api {
fn test();
}
}
struct MockApi;
sp_api::mock_impl_runtime_apis! {
impl Api<Block> for MockApi {
#[advanced]
fn test(&self, _: BlockId<Block>) -> Result<sp_core::NativeOrEncoded<()>, String> {
Ok(().into())
}
}
}
fn main() {}
@@ -0,0 +1,13 @@
error: `BlockId` needs to be taken by reference and not by value!
--> $DIR/mock_advanced_block_id_by_value.rs:11:1
|
11 | / sp_api::mock_impl_runtime_apis! {
12 | | impl Api<Block> for MockApi {
13 | | #[advanced]
14 | | fn test(&self, _: BlockId<Block>) -> Result<sp_core::NativeOrEncoded<()>, String> {
... |
17 | | }
18 | | }
| |_^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,20 @@
use substrate_test_runtime_client::runtime::Block;
sp_api::decl_runtime_apis! {
pub trait Api {
fn test();
}
}
struct MockApi;
sp_api::mock_impl_runtime_apis! {
impl Api<Block> for MockApi {
#[advanced]
fn test(&self) -> Result<sp_core::NativeOrEncoded<()>, String> {
Ok(().into())
}
}
}
fn main() {}
@@ -0,0 +1,5 @@
error: If using the `advanced` attribute, it is required that the function takes at least one argument, the `BlockId`.
--> $DIR/mock_advanced_missing_blockid.rs:14:3
|
14 | fn test(&self) -> Result<sp_core::NativeOrEncoded<()>, String> {
| ^^
@@ -4,22 +4,22 @@ error: Error type can not change between runtime apis
23 | type Error = u64;
| ^^^^
error: First error type was declared here.
--> $DIR/mock_only_one_error_type.rs:17:16
|
17 | type Error = u32;
| ^^^
error[E0277]: the trait bound `u32: std::convert::From<std::string::String>` is not satisfied
--> $DIR/mock_only_one_error_type.rs:15:1
--> $DIR/mock_only_one_error_type.rs:17:16
|
15 | / sp_api::mock_impl_runtime_apis! {
16 | | impl Api<Block> for MockApi {
17 | | type Error = u32;
18 | |
... |
26 | | }
27 | | }
| |_^ the trait `std::convert::From<std::string::String>` is not implemented for `u32`
|
::: $WORKSPACE/primitives/api/src/lib.rs:350:35
17 | type Error = u32;
| ^^^ the trait `std::convert::From<std::string::String>` is not implemented for `u32`
|
350 | type Error: std::fmt::Debug + From<String>;
| ------------ required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt`
::: $WORKSPACE/primitives/api/src/lib.rs
|
| type Error: std::fmt::Debug + From<String>;
| ------------ required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt`
|
= help: the following implementations were found:
<u32 as std::convert::From<bool>>
@@ -27,4 +27,3 @@ error[E0277]: the trait bound `u32: std::convert::From<std::string::String>` is
<u32 as std::convert::From<h2::frame::reason::Reason>>
<u32 as std::convert::From<h2::frame::reason::Reason>>
and 18 others
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)