use super::*;
use frame_support::{
parameter_types,
traits::{
fungible,
fungible::ItemOf,
fungibles,
tokens::{
fungibles::{
Balanced as FungiblesBalanced, Create as FungiblesCreate,
Inspect as FungiblesInspect, Mutate as FungiblesMutate,
},
Fortitude, Precision, Preservation,
},
},
};
use sp_runtime::{traits::ConvertToValue, Either};
const FIRST_ASSET: u32 = 0;
const UNKNOWN_ASSET: u32 = 10;
parameter_types! {
pub const LeftAsset: Either<(), u32> = Either::Left(());
pub const RightAsset: Either<u32, ()> = Either::Right(());
pub const RightUnitAsset: Either<(), ()> = Either::Right(());
}
type FirstFungible<T> = ItemOf<T, frame_support::traits::ConstU32<{ FIRST_ASSET }>, u64>;
type UnknownFungible<T> = ItemOf<T, frame_support::traits::ConstU32<{ UNKNOWN_ASSET }>, u64>;
type LeftFungible<T> = fungible::UnionOf<FirstFungible<T>, T, ConvertToValue<LeftAsset>, (), u64>;
type RightFungible<T> =
fungible::UnionOf<UnknownFungible<T>, LeftFungible<T>, ConvertToValue<RightUnitAsset>, (), u64>;
type LeftFungibles<T> = fungibles::UnionOf<RightFungible<T>, T, ConvertToValue<LeftAsset>, (), u64>;
type First<T> = fungibles::UnionOf<T, LeftFungibles<T>, ConvertToValue<RightAsset>, (), u64>;
#[test]
fn deposit_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1 = 0;
let account1 = 1;
let account2 = 2;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, 1));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let imb = First::<Assets>::deposit((), &account2, 50, Precision::Exact).unwrap();
assert_eq!(First::<Assets>::balance((), &account2), 50);
assert_eq!(First::<Assets>::total_issuance(()), 100);
System::assert_has_event(RuntimeEvent::Assets(crate::Event::Deposited {
asset_id: asset1,
who: account2,
amount: 50,
}));
assert_eq!(imb.peek(), 50);
let (imb1, imb2) = imb.split(30);
assert_eq!(imb1.peek(), 30);
assert_eq!(imb2.peek(), 20);
drop(imb2);
assert_eq!(First::<Assets>::total_issuance(()), 120);
assert!(First::<Assets>::settle(&account1, imb1, Preservation::Preserve).is_ok());
assert_eq!(First::<Assets>::balance((), &account1), 70);
assert_eq!(First::<Assets>::balance((), &account2), 50);
assert_eq!(First::<Assets>::total_issuance(()), 120);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}
#[test]
fn issue_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1: u32 = 0;
let account1: u64 = 1;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, 1));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_eq!(First::<Assets>::balance((), &account1), 100);
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let imb = First::<Assets>::issue((), 100);
assert_eq!(First::<Assets>::total_issuance(()), 200);
assert_eq!(imb.peek(), 100);
let (imb1, imb2) = imb.split(30);
assert_eq!(imb1.peek(), 30);
assert_eq!(imb2.peek(), 70);
drop(imb2);
assert_eq!(First::<Assets>::total_issuance(()), 130);
assert!(First::<Assets>::resolve(&account1, imb1).is_ok());
assert_eq!(First::<Assets>::balance((), &account1), 130);
assert_eq!(First::<Assets>::total_issuance(()), 130);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}
#[test]
fn pair_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1: u32 = 0;
let account1: u64 = 1;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, 1));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_eq!(First::<Assets>::balance((), &account1), 100);
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let (debt, credit) = First::<Assets>::pair((), 100).unwrap();
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(debt.peek(), 100);
assert_eq!(credit.peek(), 100);
let (debt1, debt2) = debt.split(30);
assert_eq!(debt1.peek(), 30);
assert_eq!(debt2.peek(), 70);
drop(debt2);
assert_eq!(First::<Assets>::total_issuance(()), 170);
assert!(First::<Assets>::settle(&account1, debt1, Preservation::Preserve).is_ok());
assert_eq!(First::<Assets>::balance((), &account1), 70);
assert_eq!(First::<Assets>::total_issuance(()), 170);
let (credit1, credit2) = credit.split(40);
assert_eq!(credit1.peek(), 40);
assert_eq!(credit2.peek(), 60);
drop(credit2);
assert_eq!(First::<Assets>::total_issuance(()), 110);
assert!(First::<Assets>::resolve(&account1, credit1).is_ok());
assert_eq!(First::<Assets>::balance((), &account1), 110);
assert_eq!(First::<Assets>::total_issuance(()), 110);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}
#[test]
fn rescind_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1: u32 = 0;
let account1: u64 = 1;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, 1));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let imb = First::<Assets>::rescind((), 20);
assert_eq!(First::<Assets>::total_issuance(()), 80);
assert_eq!(imb.peek(), 20);
let (imb1, imb2) = imb.split(15);
assert_eq!(imb1.peek(), 15);
assert_eq!(imb2.peek(), 5);
drop(imb2);
assert_eq!(First::<Assets>::total_issuance(()), 85);
assert!(First::<Assets>::settle(&account1, imb1, Preservation::Preserve).is_ok());
assert_eq!(First::<Assets>::balance((), &account1), 85);
assert_eq!(First::<Assets>::total_issuance(()), 85);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}
#[test]
fn resolve_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1: u32 = 0;
let account1: u64 = 1;
let account2: u64 = 2;
let ed = 11;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, ed));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_eq!(First::<Assets>::balance((), &account1), 100);
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let imb = First::<Assets>::issue((), 100);
assert_eq!(First::<Assets>::total_issuance(()), 200);
assert_eq!(imb.peek(), 100);
let (imb1, imb2) = imb.split(10);
assert_eq!(imb1.peek(), 10);
assert_eq!(imb2.peek(), 90);
assert_eq!(First::<Assets>::total_issuance(()), 200);
let imb1 = First::<Assets>::resolve(&account2, imb1).unwrap_err();
assert_eq!(imb1.peek(), 10);
drop(imb1);
assert_eq!(First::<Assets>::total_issuance(()), 190);
assert_eq!(First::<Assets>::balance((), &account2), 0);
assert_ok!(First::<Assets>::resolve(&account2, imb2));
assert_eq!(First::<Assets>::total_issuance(()), 190);
assert_eq!(First::<Assets>::balance((), &account2), 90);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}
#[test]
fn settle_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1: u32 = 0;
let account1: u64 = 1;
let account2: u64 = 2;
let ed = 11;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, ed));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_ok!(Assets::mint_into(asset1, &account2, 100));
assert_eq!(First::<Assets>::balance((), &account2), 100);
assert_eq!(First::<Assets>::total_issuance(()), 200);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let imb = First::<Assets>::rescind((), 100);
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(imb.peek(), 100);
let (imb1, imb2) = imb.split(10);
assert_eq!(imb1.peek(), 10);
assert_eq!(imb2.peek(), 90);
assert_eq!(First::<Assets>::total_issuance(()), 100);
let imb2 = First::<Assets>::settle(&account2, imb2, Preservation::Preserve).unwrap_err();
assert_eq!(imb2.peek(), 90);
drop(imb2);
assert_eq!(First::<Assets>::total_issuance(()), 190);
assert_eq!(First::<Assets>::balance((), &account2), 100);
assert_ok!(First::<Assets>::settle(&account2, imb1, Preservation::Preserve));
assert_eq!(First::<Assets>::total_issuance(()), 190);
assert_eq!(First::<Assets>::balance((), &account2), 90);
let imb = First::<Assets>::rescind((), 85);
assert_eq!(First::<Assets>::total_issuance(()), 105);
assert_eq!(imb.peek(), 85);
let imb = First::<Assets>::settle(&account2, imb, Preservation::Expendable).unwrap();
assert_eq!(imb.peek(), 5);
assert_eq!(First::<Assets>::total_issuance(()), 105);
assert_eq!(First::<Assets>::balance((), &account2), 0);
drop(imb);
assert_eq!(First::<Assets>::total_issuance(()), 100);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}
#[test]
fn withdraw_from_set_types_works() {
new_test_ext().execute_with(|| {
let asset1 = 0;
let account1 = 1;
let account2 = 2;
assert_ok!(<Assets as FungiblesCreate<u64>>::create(asset1, account1, true, 1));
assert_ok!(Assets::mint_into(asset1, &account1, 100));
assert_ok!(Assets::mint_into(asset1, &account2, 100));
assert_eq!(First::<Assets>::total_issuance(()), 200);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
let imb = First::<Assets>::withdraw(
(),
&account2,
50,
Precision::Exact,
Preservation::Preserve,
Fortitude::Polite,
)
.unwrap();
assert_eq!(First::<Assets>::balance((), &account2), 50);
assert_eq!(First::<Assets>::total_issuance(()), 200);
System::assert_has_event(RuntimeEvent::Assets(crate::Event::Withdrawn {
asset_id: asset1,
who: account2,
amount: 50,
}));
assert_eq!(imb.peek(), 50);
drop(imb);
assert_eq!(First::<Assets>::total_issuance(()), 150);
assert_eq!(First::<Assets>::balance((), &account2), 50);
assert_eq!(First::<Assets>::total_issuance(()), Assets::total_issuance(asset1));
});
}