mirror of
https://github.com/pezkuwichain/pezkuwi-runtime-templates.git
synced 2026-06-12 17:01:02 +00:00
base for testing new pallets
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
//! Benchmarking setup for pallet-parachain-template
|
||||
|
||||
use super::*;
|
||||
|
||||
#[allow(unused)]
|
||||
use crate::Pallet as Template;
|
||||
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller};
|
||||
use frame_system::RawOrigin;
|
||||
|
||||
benchmarks! {
|
||||
do_something {
|
||||
let s in 0 .. 100;
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
}: _(RawOrigin::Signed(caller), s)
|
||||
verify {
|
||||
assert_eq!(Something::<T>::get(), Some(s));
|
||||
}
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test,);
|
||||
@@ -0,0 +1,106 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
/// Edit this file to define custom logic or remove it if it is not needed.
|
||||
/// Learn more about FRAME and the core library of Substrate FRAME pallets:
|
||||
/// <https://docs.substrate.io/v3/runtime/frame>
|
||||
pub use pallet::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarking;
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*};
|
||||
use frame_system::pallet_prelude::*;
|
||||
|
||||
/// Configure the pallet by specifying the parameters and types on which it depends.
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
/// Because this pallet emits events, it depends on the runtime's definition of an event.
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
// The pallet's runtime storage items.
|
||||
// https://docs.substrate.io/v3/runtime/storage
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn something)]
|
||||
// Learn more about declaring storage items:
|
||||
// https://docs.substrate.io/v3/runtime/storage#declaring-storage-items
|
||||
pub type Something<T> = StorageValue<_, u32>;
|
||||
|
||||
// Pallets use events to inform users when important changes are made.
|
||||
// https://docs.substrate.io/v3/runtime/events-and-errors
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
/// Event documentation should end with an array that provides descriptive names for event
|
||||
/// parameters. [something, who]
|
||||
SomethingStored(u32, T::AccountId),
|
||||
}
|
||||
|
||||
// Errors inform users that something went wrong.
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// Error names should be descriptive.
|
||||
NoneValue,
|
||||
/// Errors should have helpful documentation associated with them.
|
||||
StorageOverflow,
|
||||
}
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
|
||||
// Dispatchable functions allows users to interact with the pallet and invoke state changes.
|
||||
// These functions materialize as "extrinsics", which are often compared to transactions.
|
||||
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// An example dispatchable that takes a singles value as a parameter, writes the value to
|
||||
/// storage and emits an event. This function must be dispatched by a signed extrinsic.
|
||||
#[pallet::call_index(0)]
|
||||
#[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))]
|
||||
pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResultWithPostInfo {
|
||||
// Check that the extrinsic was signed and get the signer.
|
||||
// This function will return an error if the extrinsic is not signed.
|
||||
// https://docs.substrate.io/v3/runtime/origins
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
// Update storage.
|
||||
<Something<T>>::put(something);
|
||||
|
||||
// Emit an event.
|
||||
Self::deposit_event(Event::SomethingStored(something, who));
|
||||
// Return a successful DispatchResultWithPostInfo
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
/// An example dispatchable that may throw a custom error.
|
||||
#[pallet::call_index(1)]
|
||||
#[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().reads_writes(1,1))]
|
||||
pub fn cause_error(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
|
||||
let _who = ensure_signed(origin)?;
|
||||
|
||||
// Read a value from storage.
|
||||
match <Something<T>>::get() {
|
||||
// Return an error if the value has not been set.
|
||||
None => Err(Error::<T>::NoneValue)?,
|
||||
Some(old) => {
|
||||
// Increment the value read from storage; will error in the event of overflow.
|
||||
let new = old.checked_add(1).ok_or(Error::<T>::StorageOverflow)?;
|
||||
// Update the value in storage with the incremented result.
|
||||
<Something<T>>::put(new);
|
||||
Ok(().into())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
use frame_support::{parameter_types, traits::Everything};
|
||||
use frame_system as system;
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
BuildStorage,
|
||||
};
|
||||
|
||||
type Block = frame_system::mocking::MockBlock<Test>;
|
||||
|
||||
// Configure a mock runtime to test the pallet.
|
||||
frame_support::construct_runtime!(
|
||||
pub enum Test
|
||||
{
|
||||
System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>},
|
||||
TemplateModule: crate::{Pallet, Call, Storage, Event<T>},
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub const SS58Prefix: u8 = 42;
|
||||
}
|
||||
|
||||
impl system::Config for Test {
|
||||
type BaseCallFilter = Everything;
|
||||
type BlockWeights = ();
|
||||
type BlockLength = ();
|
||||
type DbWeight = ();
|
||||
type RuntimeOrigin = RuntimeOrigin;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
type Nonce = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Block = Block;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = ();
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = ();
|
||||
type MaxConsumers = frame_support::traits::ConstU32<16>;
|
||||
}
|
||||
|
||||
impl crate::Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
}
|
||||
|
||||
// Build genesis storage according to the mock runtime.
|
||||
pub fn new_test_ext() -> sp_io::TestExternalities {
|
||||
system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
use crate::{mock::*, Error};
|
||||
use frame_support::{assert_noop, assert_ok};
|
||||
|
||||
#[test]
|
||||
fn it_works_for_default_value() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Dispatch a signed extrinsic.
|
||||
assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42));
|
||||
// Read pallet storage and assert an expected result.
|
||||
assert_eq!(TemplateModule::something(), Some(42));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn correct_error_for_none_value() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Ensure the expected error is thrown when no value is present.
|
||||
assert_noop!(
|
||||
TemplateModule::cause_error(RuntimeOrigin::signed(1)),
|
||||
Error::<Test>::NoneValue
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user