Skip to content
Snippets Groups Projects
mock.rs 7.81 KiB
Newer Older
//! Mocks for the tokens module.

#![cfg(test)]

use super::*;
zjb0807's avatar
zjb0807 committed
use frame_support::{
	impl_outer_event, impl_outer_origin, parameter_types,
	traits::{ChangeMembers, Contains, ContainsLengthBound, GenesisBuild, SaturatingCurrencyToVote},
zjb0807's avatar
zjb0807 committed
};
use orml_traits::{parameter_type_with_key, LockIdentifier};
Shaopeng Wang's avatar
Shaopeng Wang committed
use sp_core::H256;
wangjj9219's avatar
wangjj9219 committed
use sp_runtime::{
	testing::Header,
	traits::{AccountIdConversion, IdentityLookup},
	AccountId32, ModuleId, Permill,
wangjj9219's avatar
wangjj9219 committed
};
Xiliang Chen's avatar
Xiliang Chen committed
use sp_std::cell::RefCell;
wangjj9219's avatar
wangjj9219 committed
pub type AccountId = AccountId32;
pub type CurrencyId = u32;
pub type Balance = u64;

pub const DOT: CurrencyId = 1;
pub const BTC: CurrencyId = 2;
pub const ETH: CurrencyId = 3;
pub const ALICE: AccountId = AccountId32::new([0u8; 32]);
pub const BOB: AccountId = AccountId32::new([1u8; 32]);
pub const TREASURY_ACCOUNT: AccountId = AccountId32::new([2u8; 32]);
pub const ID_1: LockIdentifier = *b"1       ";
pub const ID_2: LockIdentifier = *b"2       ";

impl_outer_origin! {
	pub enum Origin for Runtime {}
}

mod tokens {
	pub use crate::Event;
}

impl_outer_event! {
	pub enum TestEvent for Runtime {
Xiliang Chen's avatar
Xiliang Chen committed
		frame_system<T>,
		tokens<T>,
zjb0807's avatar
zjb0807 committed
		pallet_treasury<T>,
		pallet_elections_phragmen<T>,
	}
}

// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Runtime;
parameter_types! {
	pub const BlockHashCount: u64 = 250;
}

Shaopeng Wang's avatar
Shaopeng Wang committed
impl frame_system::Config for Runtime {
	type Origin = Origin;
	type Index = u64;
	type BlockNumber = u64;
	type Hash = H256;
Xiliang Chen's avatar
Xiliang Chen committed
	type Hashing = ::sp_runtime::traits::BlakeTwo256;
	type AccountId = AccountId;
	type Lookup = IdentityLookup<Self::AccountId>;
	type Header = Header;
	type Event = TestEvent;
	type BlockHashCount = BlockHashCount;
Shaopeng Wang's avatar
Shaopeng Wang committed
	type BlockWeights = ();
	type BlockLength = ();
	type Version = ();
	type PalletInfo = ();
Xiliang Chen's avatar
Xiliang Chen committed
	type AccountData = ();
	type OnNewAccount = ();
Xiliang Chen's avatar
Xiliang Chen committed
	type OnKilledAccount = ();
	type DbWeight = ();
	type BaseCallFilter = ();
Xiliang Chen's avatar
Xiliang Chen committed
	type SystemWeightInfo = ();
Shaopeng Wang's avatar
Shaopeng Wang committed
	type SS58Prefix = ();
pub type System = frame_system::Module<Runtime>;
thread_local! {
wangjj9219's avatar
wangjj9219 committed
	static TEN_TO_FOURTEEN: RefCell<Vec<AccountId>> = RefCell::new(vec![
		AccountId32::new([10u8; 32]),
		AccountId32::new([11u8; 32]),
		AccountId32::new([12u8; 32]),
		AccountId32::new([13u8; 32]),
		AccountId32::new([14u8; 32]),
	]);
zjb0807's avatar
zjb0807 committed
pub struct TenToFourteen;
wangjj9219's avatar
wangjj9219 committed
impl Contains<AccountId> for TenToFourteen {
	fn sorted_members() -> Vec<AccountId> {
zjb0807's avatar
zjb0807 committed
		TEN_TO_FOURTEEN.with(|v| v.borrow().clone())
	}
	#[cfg(feature = "runtime-benchmarks")]
wangjj9219's avatar
wangjj9219 committed
	fn add(new: &AccountId) {
zjb0807's avatar
zjb0807 committed
		TEN_TO_FOURTEEN.with(|v| {
			let mut members = v.borrow_mut();
			members.push(*new);
			members.sort();
		})
	}
}
zjb0807's avatar
zjb0807 committed
impl ContainsLengthBound for TenToFourteen {
	fn max_len() -> usize {
		TEN_TO_FOURTEEN.with(|v| v.borrow().len())
	}
	fn min_len() -> usize {
		0
	}
}

parameter_types! {
	pub const ProposalBond: Permill = Permill::from_percent(5);
	pub const ProposalBondMinimum: u64 = 1;
	pub const SpendPeriod: u64 = 2;
	pub const Burn: Permill = Permill::from_percent(50);
	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");
wangjj9219's avatar
wangjj9219 committed
	pub const GetTokenId: CurrencyId = DOT;
Shaopeng Wang's avatar
Shaopeng Wang committed
impl pallet_treasury::Config for Runtime {
zjb0807's avatar
zjb0807 committed
	type ModuleId = TreasuryModuleId;
	type Currency = CurrencyAdapter<Runtime, GetTokenId>;
wangjj9219's avatar
wangjj9219 committed
	type ApproveOrigin = frame_system::EnsureRoot<AccountId>;
	type RejectOrigin = frame_system::EnsureRoot<AccountId>;
zjb0807's avatar
zjb0807 committed
	type Event = TestEvent;
	type OnSlash = ();
zjb0807's avatar
zjb0807 committed
	type ProposalBond = ProposalBond;
	type ProposalBondMinimum = ProposalBondMinimum;
	type SpendPeriod = SpendPeriod;
	type Burn = Burn;
	type BurnDestination = ();
	type SpendFunds = ();
	type WeightInfo = ();
}

wangjj9219's avatar
wangjj9219 committed
pub type Treasury = pallet_treasury::Module<Runtime>;
zjb0807's avatar
zjb0807 committed

thread_local! {
wangjj9219's avatar
wangjj9219 committed
	pub static MEMBERS: RefCell<Vec<AccountId>> = RefCell::new(vec![]);
	pub static PRIME: RefCell<Option<AccountId>> = RefCell::new(None);
zjb0807's avatar
zjb0807 committed
}

pub struct TestChangeMembers;
wangjj9219's avatar
wangjj9219 committed
impl ChangeMembers<AccountId> for TestChangeMembers {
	fn change_members_sorted(incoming: &[AccountId], outgoing: &[AccountId], new: &[AccountId]) {
zjb0807's avatar
zjb0807 committed
		// new, incoming, outgoing must be sorted.
		let mut new_sorted = new.to_vec();
		new_sorted.sort();
		assert_eq!(new, &new_sorted[..]);

		let mut incoming_sorted = incoming.to_vec();
		incoming_sorted.sort();
		assert_eq!(incoming, &incoming_sorted[..]);

		let mut outgoing_sorted = outgoing.to_vec();
		outgoing_sorted.sort();
		assert_eq!(outgoing, &outgoing_sorted[..]);

		// incoming and outgoing must be disjoint
		for x in incoming.iter() {
			assert!(outgoing.binary_search(x).is_err());
		}

		let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec());
		old_plus_incoming.extend_from_slice(incoming);
		old_plus_incoming.sort();

		let mut new_plus_outgoing = new.to_vec();
		new_plus_outgoing.extend_from_slice(outgoing);
		new_plus_outgoing.sort();

		assert_eq!(
			old_plus_incoming, new_plus_outgoing,
			"change members call is incorrect!"
		);

		MEMBERS.with(|m| *m.borrow_mut() = new.to_vec());
		PRIME.with(|p| *p.borrow_mut() = None);
	}

wangjj9219's avatar
wangjj9219 committed
	fn set_prime(who: Option<AccountId>) {
zjb0807's avatar
zjb0807 committed
		PRIME.with(|p| *p.borrow_mut() = who);
	}
}

parameter_types! {
	pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect";
	pub const CandidacyBond: u64 = 3;
	pub const VotingBond: u64 = 2;
	pub const DesiredMembers: u32 = 2;
	pub const DesiredRunnersUp: u32 = 2;
	pub const TermDuration: u64 = 5;
wangjj9219's avatar
wangjj9219 committed
	pub const VotingBondBase: u64 = 2;
	pub const VotingBondFactor: u64 = 0;
Shaopeng Wang's avatar
Shaopeng Wang committed
impl pallet_elections_phragmen::Config for Runtime {
zjb0807's avatar
zjb0807 committed
	type ModuleId = ElectionsPhragmenModuleId;
	type Event = TestEvent;
	type Currency = CurrencyAdapter<Runtime, GetTokenId>;
zjb0807's avatar
zjb0807 committed
	type CurrencyToVote = SaturatingCurrencyToVote;
zjb0807's avatar
zjb0807 committed
	type ChangeMembers = TestChangeMembers;
	type InitializeMembers = ();
	type CandidacyBond = CandidacyBond;
wangjj9219's avatar
wangjj9219 committed
	type VotingBondBase = VotingBondBase;
	type VotingBondFactor = VotingBondFactor;
zjb0807's avatar
zjb0807 committed
	type TermDuration = TermDuration;
	type DesiredMembers = DesiredMembers;
	type DesiredRunnersUp = DesiredRunnersUp;
	type LoserCandidate = ();
	type KickedMember = ();
	type WeightInfo = ();
}

wangjj9219's avatar
wangjj9219 committed
parameter_type_with_key! {
	pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {
wangjj9219's avatar
wangjj9219 committed
		match currency_id {
			&BTC => 1,
			&DOT => 2,
			_ => 0,
		}
	};
}

parameter_types! {
	pub DustAccount: AccountId = ModuleId(*b"orml/dst").into_account();
Shaopeng Wang's avatar
Shaopeng Wang committed
impl Config for Runtime {
	type Event = TestEvent;
	type Balance = Balance;
	type CurrencyId = CurrencyId;
	type WeightInfo = ();
	type ExistentialDeposits = ExistentialDeposits;
	type OnDust = TransferDust<Runtime, DustAccount>;
}
pub type Tokens = Module<Runtime>;
Shaopeng Wang's avatar
Shaopeng Wang committed
pub type TreasuryCurrencyAdapter = <Runtime as pallet_treasury::Config>::Currency;

pub struct ExtBuilder {
	endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>,
zjb0807's avatar
zjb0807 committed
	treasury_genesis: bool,
}

impl Default for ExtBuilder {
	fn default() -> Self {
		Self {
zjb0807's avatar
zjb0807 committed
			treasury_genesis: false,
	pub fn balances(mut self, endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>) -> Self {
		self.endowed_accounts = endowed_accounts;
		self
	}

	pub fn one_hundred_for_alice_n_bob(self) -> Self {
wangjj9219's avatar
wangjj9219 committed
		self.balances(vec![(ALICE, DOT, 100), (BOB, DOT, 100)])
zjb0807's avatar
zjb0807 committed
	pub fn one_hundred_for_treasury_account(mut self) -> Self {
		self.treasury_genesis = true;
wangjj9219's avatar
wangjj9219 committed
		self.balances(vec![(TREASURY_ACCOUNT, DOT, 100)])
Shaopeng Wang's avatar
Shaopeng Wang committed
	pub fn build(self) -> sp_io::TestExternalities {
Xiliang Chen's avatar
Xiliang Chen committed
		let mut t = frame_system::GenesisConfig::default()
			.build_storage::<Runtime>()
			.unwrap();

		GenesisConfig::<Runtime> {
			endowed_accounts: self.endowed_accounts,
		}
		.assimilate_storage(&mut t)
		.unwrap();

zjb0807's avatar
zjb0807 committed
		if self.treasury_genesis {
			pallet_treasury::GenesisConfig::default()
				.assimilate_storage::<Runtime, _>(&mut t)
zjb0807's avatar
zjb0807 committed
				.unwrap();

			pallet_elections_phragmen::GenesisConfig::<Runtime> {
				members: vec![(TREASURY_ACCOUNT, 10)],
			}
			.assimilate_storage(&mut t)
			.unwrap();
		}

		let mut ext = sp_io::TestExternalities::new(t);
		ext.execute_with(|| System::set_block_number(1));
		ext