Files
pezkuwi-subxt/substrate/primitives/api/test/tests/decl_and_impl.rs
T
joe petrowski 757ae372f7 Switch All construct_runtimes to New Syntax (#2979)
Clean up all the old syntax.

---------

Co-authored-by: command-bot <>
Co-authored-by: gupnik <nikhilgupta.iitk@gmail.com>
Co-authored-by: Nikhil Gupta <17176722+gupnik@users.noreply.github.com>
Co-authored-by: Maksym H <1177472+mordamax@users.noreply.github.com>
2024-01-22 07:15:53 +00:00

309 lines
8.2 KiB
Rust

// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use sp_api::{
decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, ApiError, ApiExt, RuntimeApiInfo,
};
use sp_runtime::traits::Block as BlockT;
use substrate_test_runtime_client::runtime::{Block, Hash};
/// The declaration of the `Runtime` type is done by the `construct_runtime!` macro in a real
/// runtime.
pub enum Runtime {}
decl_runtime_apis! {
pub trait Api {
fn test(data: u64);
fn something_with_block(block: Block) -> Block;
fn function_with_two_args(data: u64, block: Block);
fn same_name();
fn wild_card(_: u32);
}
#[api_version(2)]
pub trait ApiWithCustomVersion {
fn same_name();
#[changed_in(2)]
fn same_name() -> String;
}
#[api_version(2)]
pub trait ApiWithMultipleVersions {
fn stable_one(data: u64);
#[api_version(3)]
fn new_one();
#[api_version(4)]
fn glory_one();
}
pub trait ApiWithStagingMethod {
fn stable_one(data: u64);
#[api_version(99)]
fn staging_one();
}
pub trait ApiWithStagingAndVersionedMethods {
fn stable_one(data: u64);
#[api_version(2)]
fn new_one();
#[api_version(99)]
fn staging_one();
}
#[api_version(2)]
pub trait ApiWithStagingAndChangedBase {
fn stable_one(data: u64);
fn new_one();
#[api_version(99)]
fn staging_one();
}
}
impl_runtime_apis! {
impl self::Api<Block> for Runtime {
fn test(_: u64) {
unimplemented!()
}
fn something_with_block(_: Block) -> Block {
unimplemented!()
}
fn function_with_two_args(_: u64, _: Block) {
unimplemented!()
}
fn same_name() {}
fn wild_card(_: u32) {}
}
impl self::ApiWithCustomVersion<Block> for Runtime {
fn same_name() {}
}
#[api_version(3)]
impl self::ApiWithMultipleVersions<Block> for Runtime {
fn stable_one(_: u64) {}
fn new_one() {}
}
#[cfg_attr(feature = "enable-staging-api", api_version(99))]
impl self::ApiWithStagingMethod<Block> for Runtime {
fn stable_one(_: u64) {}
#[cfg(feature = "enable-staging-api")]
fn staging_one() { }
}
#[cfg_attr(feature = "enable-staging-api", api_version(99))]
#[api_version(2)]
impl self::ApiWithStagingAndVersionedMethods<Block> for Runtime {
fn stable_one(_: u64) {}
fn new_one() {}
#[cfg(feature = "enable-staging-api")]
fn staging_one() {}
}
#[cfg_attr(feature = "enable-staging-api", api_version(99))]
impl self::ApiWithStagingAndChangedBase<Block> for Runtime {
fn stable_one(_: u64) {}
fn new_one() {}
#[cfg(feature = "enable-staging-api")]
fn staging_one() {}
}
impl sp_api::Core<Block> for Runtime {
fn version() -> sp_version::RuntimeVersion {
unimplemented!()
}
fn execute_block(_: Block) {
unimplemented!()
}
fn initialize_block(_: &<Block as BlockT>::Header) {
unimplemented!()
}
}
}
struct MockApi {
block: Option<Block>,
}
mock_impl_runtime_apis! {
impl Api<Block> for MockApi {
fn test(_: u64) {
unimplemented!()
}
fn something_with_block(&self, _: Block) -> Block {
self.block.clone().unwrap()
}
fn function_with_two_args(_: u64, _: Block) {
unimplemented!()
}
#[advanced]
fn same_name(_: <Block as BlockT>::Hash) -> Result<(), ApiError> {
Ok(().into())
}
#[advanced]
fn wild_card(at: <Block as BlockT>::Hash, _: u32) -> Result<(), ApiError> {
if Hash::repeat_byte(0x0f) == at {
// yeah
Ok(().into())
} else {
Err((Box::from("Test error") as Box<dyn std::error::Error + Send + Sync>).into())
}
}
}
impl ApiWithCustomVersion<Block> for MockApi {
fn same_name() {}
}
}
type TestClient = substrate_test_runtime_client::client::Client<
substrate_test_runtime_client::Backend,
substrate_test_runtime_client::ExecutorDispatch,
Block,
RuntimeApi,
>;
#[test]
fn test_client_side_function_signature() {
let _test: fn(
&RuntimeApiImpl<Block, TestClient>,
<Block as BlockT>::Hash,
u64,
) -> Result<(), ApiError> = RuntimeApiImpl::<Block, TestClient>::test;
let _something_with_block: fn(
&RuntimeApiImpl<Block, TestClient>,
<Block as BlockT>::Hash,
Block,
) -> Result<Block, ApiError> = RuntimeApiImpl::<Block, TestClient>::something_with_block;
#[allow(deprecated)]
let _same_name_before_version_2: fn(
&RuntimeApiImpl<Block, TestClient>,
<Block as BlockT>::Hash,
) -> Result<String, ApiError> = RuntimeApiImpl::<Block, TestClient>::same_name_before_version_2;
}
#[test]
fn check_runtime_api_info() {
assert_eq!(&<dyn Api::<Block>>::ID, &runtime_decl_for_api::ID);
assert_eq!(<dyn Api::<Block>>::VERSION, runtime_decl_for_api::VERSION);
assert_eq!(<dyn Api::<Block>>::VERSION, 1);
assert_eq!(
<dyn ApiWithCustomVersion::<Block>>::VERSION,
runtime_decl_for_api_with_custom_version::VERSION,
);
assert_eq!(
&<dyn ApiWithCustomVersion::<Block>>::ID,
&runtime_decl_for_api_with_custom_version::ID,
);
assert_eq!(<dyn ApiWithCustomVersion::<Block>>::VERSION, 2);
// The stable version of the API
assert_eq!(<dyn ApiWithMultipleVersions::<Block>>::VERSION, 2);
assert_eq!(<dyn ApiWithStagingMethod::<Block>>::VERSION, 1);
assert_eq!(<dyn ApiWithStagingAndVersionedMethods::<Block>>::VERSION, 1);
assert_eq!(<dyn ApiWithStagingAndChangedBase::<Block>>::VERSION, 2);
}
fn check_runtime_api_versions_contains<T: RuntimeApiInfo + ?Sized>() {
assert!(RUNTIME_API_VERSIONS.iter().any(|v| v == &(T::ID, T::VERSION)));
}
fn check_staging_runtime_api_versions<T: RuntimeApiInfo + ?Sized>(_staging_ver: u32) {
// Staging APIs should contain staging version if the feature is set...
#[cfg(feature = "enable-staging-api")]
assert!(RUNTIME_API_VERSIONS.iter().any(|v| v == &(T::ID, _staging_ver)));
//... otherwise the base version should be set
#[cfg(not(feature = "enable-staging-api"))]
check_runtime_api_versions_contains::<dyn ApiWithStagingMethod<Block>>();
}
#[allow(unused_assignments)]
fn check_staging_multiver_runtime_api_versions<T: RuntimeApiInfo + ?Sized>(
_staging_ver: u32,
_stable_ver: u32,
) {
// Staging APIs should contain staging version if the feature is set...
#[cfg(feature = "enable-staging-api")]
assert!(RUNTIME_API_VERSIONS.iter().any(|v| v == &(T::ID, _staging_ver)));
//... otherwise the base version should be set
#[cfg(not(feature = "enable-staging-api"))]
assert!(RUNTIME_API_VERSIONS.iter().any(|v| v == &(T::ID, _stable_ver)));
}
#[test]
fn check_runtime_api_versions() {
check_runtime_api_versions_contains::<dyn Api<Block>>();
check_runtime_api_versions_contains::<dyn ApiWithCustomVersion<Block>>();
assert!(RUNTIME_API_VERSIONS
.iter()
.any(|v| v == &(<dyn ApiWithMultipleVersions<Block>>::ID, 3)));
check_staging_runtime_api_versions::<dyn ApiWithStagingMethod<Block>>(99);
check_staging_multiver_runtime_api_versions::<dyn ApiWithStagingAndVersionedMethods<Block>>(
99, 2,
);
check_staging_runtime_api_versions::<dyn ApiWithStagingAndChangedBase<Block>>(99);
check_runtime_api_versions_contains::<dyn sp_api::Core<Block>>();
}
#[test]
fn mock_runtime_api_has_api() {
let mock = MockApi { block: None };
assert!(mock.has_api::<dyn ApiWithCustomVersion<Block>>(Hash::default()).unwrap());
assert!(mock.has_api::<dyn Api<Block>>(Hash::default()).unwrap());
}
#[test]
#[should_panic(expected = "Calling deprecated methods is not supported by mocked runtime api.")]
fn mock_runtime_api_panics_on_calling_old_version() {
let mock = MockApi { block: None };
#[allow(deprecated)]
let _ = mock.same_name_before_version_2(Hash::default());
}
#[test]
fn mock_runtime_api_works_with_advanced() {
let mock = MockApi { block: None };
Api::<Block>::same_name(&mock, Hash::default()).unwrap();
mock.wild_card(Hash::repeat_byte(0x0f), 1).unwrap();
assert_eq!(
"Test error".to_string(),
mock.wild_card(Hash::repeat_byte(0x01), 1).unwrap_err().to_string(),
);
}