// This file is part of Substrate. // Copyright (C) 2019-2022 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. #[cfg(test)] // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] mod tests { use frame_support::metadata::*; use sp_io::TestExternalities; frame_support::decl_module! { pub struct Module for enum Call where origin: T::RuntimeOrigin, system=frame_support_test {} } pub trait Config: frame_support_test::Config { type Origin2: codec::Codec + codec::EncodeLike + Default + codec::MaxEncodedLen + scale_info::TypeInfo; } frame_support::decl_storage! { generate_storage_info trait Store for Module as TestStorage { // non-getters: pub / $default /// Hello, this is doc! U32: Option; pub PUBU32: Option; U32MYDEF: Option; pub PUBU32MYDEF: Option; // getters: pub / $default // we need at least one type which uses T, otherwise GenesisConfig will complain. GETU32 get(fn u32_getter): T::Origin2; pub PUBGETU32 get(fn pub_u32_getter): u32; GETU32WITHCONFIG get(fn u32_getter_with_config) config(): u32; pub PUBGETU32WITHCONFIG get(fn pub_u32_getter_with_config) config(): u32; GETU32MYDEF get(fn u32_getter_mydef): Option; pub PUBGETU32MYDEF get(fn pub_u32_getter_mydef) config(): u32 = 3; GETU32WITHCONFIGMYDEF get(fn u32_getter_with_config_mydef) config(): u32 = 2; pub PUBGETU32WITHCONFIGMYDEF get(fn pub_u32_getter_with_config_mydef) config(): u32 = 1; PUBGETU32WITHCONFIGMYDEFOPT get(fn pub_u32_getter_with_config_mydef_opt) config(): Option; GetU32WithBuilder get(fn u32_with_builder) build(|_| 1): u32; GetOptU32WithBuilderSome get(fn opt_u32_with_builder_some) build(|_| Some(1)): Option; GetOptU32WithBuilderNone get(fn opt_u32_with_builder_none) build(|_| None): Option; // map non-getters: pub / $default MAPU32 max_values(3): map hasher(blake2_128_concat) u32 => Option<[u8; 4]>; pub PUBMAPU32: map hasher(blake2_128_concat) u32 => Option<[u8; 4]>; // map getters: pub / $default GETMAPU32 get(fn map_u32_getter): map hasher(blake2_128_concat) u32 => [u8; 4]; pub PUBGETMAPU32 get(fn pub_map_u32_getter): map hasher(blake2_128_concat) u32 => [u8; 4]; GETMAPU32MYDEF get(fn map_u32_getter_mydef): map hasher(blake2_128_concat) u32 => [u8; 4] = *b"mapd"; pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef): map hasher(blake2_128_concat) u32 => [u8; 4] = *b"pubm"; DOUBLEMAP max_values(3): double_map hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Option<[u8; 4]>; DOUBLEMAP2: double_map hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Option<[u8; 4]>; COMPLEXTYPE1: (::std::option::Option,); COMPLEXTYPE2: ([[(u16, Option<()>); 32]; 12], u32); COMPLEXTYPE3: [u32; 25]; NMAP: nmap hasher(blake2_128_concat) u32, hasher(twox_64_concat) u16 => u8; NMAP2: nmap hasher(blake2_128_concat) u32 => u8; } add_extra_genesis { build(|_| {}); } } struct TraitImpl {} impl frame_support_test::Config for TraitImpl { type RuntimeOrigin = u32; type BlockNumber = u32; type PalletInfo = frame_support_test::PanicPalletInfo; type DbWeight = (); } impl Config for TraitImpl { type Origin2 = u32; } fn expected_metadata() -> PalletStorageMetadata { PalletStorageMetadata { prefix: "TestStorage", entries: vec![ StorageEntryMetadata { name: "U32", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![" Hello, this is doc!"], }, StorageEntryMetadata { name: "PUBU32", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "U32MYDEF", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "PUBU32MYDEF", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "GETU32", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "PUBGETU32", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "GETU32WITHCONFIG", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "PUBGETU32WITHCONFIG", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "GETU32MYDEF", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "PUBGETU32MYDEF", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![3, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "GETU32WITHCONFIGMYDEF", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![2, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "PUBGETU32WITHCONFIGMYDEF", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![1, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "PUBGETU32WITHCONFIGMYDEFOPT", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "GetU32WithBuilder", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "GetOptU32WithBuilderSome", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "GetOptU32WithBuilderNone", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Plain(scale_info::meta_type::()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "MAPU32", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Map { hashers: vec![StorageHasher::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "PUBMAPU32", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Map { hashers: vec![StorageHasher::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "GETMAPU32", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Map { hashers: vec![StorageHasher::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "PUBGETMAPU32", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Map { hashers: vec![StorageHasher::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0, 0, 0, 0], docs: vec![], }, StorageEntryMetadata { name: "GETMAPU32MYDEF", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Map { hashers: vec![StorageHasher::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![109, 97, 112, 100], // "map" docs: vec![], }, StorageEntryMetadata { name: "PUBGETMAPU32MYDEF", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Map { hashers: vec![StorageHasher::Blake2_128Concat], key: scale_info::meta_type::(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![112, 117, 98, 109], // "pubmap" docs: vec![], }, StorageEntryMetadata { name: "DOUBLEMAP", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Map { hashers: vec![ StorageHasher::Blake2_128Concat, StorageHasher::Blake2_128Concat, ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "DOUBLEMAP2", modifier: StorageEntryModifier::Optional, ty: StorageEntryType::Map { hashers: vec![ StorageHasher::Blake2_128Concat, StorageHasher::Blake2_128Concat, ], key: scale_info::meta_type::<(u32, u32)>(), value: scale_info::meta_type::<[u8; 4]>(), }, default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "COMPLEXTYPE1", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::<(Option,)>()), default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "COMPLEXTYPE2", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::<( [[(u16, Option<()>); 32]; 12], u32, )>()), default: [0u8; 1156].to_vec(), docs: vec![], }, StorageEntryMetadata { name: "COMPLEXTYPE3", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Plain(scale_info::meta_type::<[u32; 25]>()), default: [0u8; 100].to_vec(), docs: vec![], }, StorageEntryMetadata { name: "NMAP", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Map { key: scale_info::meta_type::<(u32, u16)>(), hashers: vec![StorageHasher::Blake2_128Concat, StorageHasher::Twox64Concat], value: scale_info::meta_type::(), }, default: vec![0], docs: vec![], }, StorageEntryMetadata { name: "NMAP2", modifier: StorageEntryModifier::Default, ty: StorageEntryType::Map { key: scale_info::meta_type::(), hashers: vec![StorageHasher::Blake2_128Concat], value: scale_info::meta_type::(), }, default: vec![0], docs: vec![], }, ], } } #[test] fn storage_info() { use frame_support::{ storage::storage_prefix as prefix, traits::{StorageInfo, StorageInfoTrait}, }; pretty_assertions::assert_eq!( >::storage_info(), vec![ StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"U32".to_vec(), prefix: prefix(b"TestStorage", b"U32").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBU32".to_vec(), prefix: prefix(b"TestStorage", b"PUBU32").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"U32MYDEF".to_vec(), prefix: prefix(b"TestStorage", b"U32MYDEF").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBU32MYDEF".to_vec(), prefix: prefix(b"TestStorage", b"PUBU32MYDEF").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GETU32".to_vec(), prefix: prefix(b"TestStorage", b"GETU32").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETU32".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETU32").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GETU32WITHCONFIG".to_vec(), prefix: prefix(b"TestStorage", b"GETU32WITHCONFIG").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETU32WITHCONFIG".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETU32WITHCONFIG").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GETU32MYDEF".to_vec(), prefix: prefix(b"TestStorage", b"GETU32MYDEF").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETU32MYDEF".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETU32MYDEF").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GETU32WITHCONFIGMYDEF".to_vec(), prefix: prefix(b"TestStorage", b"GETU32WITHCONFIGMYDEF").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETU32WITHCONFIGMYDEF".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETU32WITHCONFIGMYDEF").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETU32WITHCONFIGMYDEFOPT".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETU32WITHCONFIGMYDEFOPT").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GetU32WithBuilder".to_vec(), prefix: prefix(b"TestStorage", b"GetU32WithBuilder").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GetOptU32WithBuilderSome".to_vec(), prefix: prefix(b"TestStorage", b"GetOptU32WithBuilderSome").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GetOptU32WithBuilderNone".to_vec(), prefix: prefix(b"TestStorage", b"GetOptU32WithBuilderNone").to_vec(), max_values: Some(1), max_size: Some(4), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"MAPU32".to_vec(), prefix: prefix(b"TestStorage", b"MAPU32").to_vec(), max_values: Some(3), max_size: Some(8 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBMAPU32".to_vec(), prefix: prefix(b"TestStorage", b"PUBMAPU32").to_vec(), max_values: None, max_size: Some(8 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GETMAPU32".to_vec(), prefix: prefix(b"TestStorage", b"GETMAPU32").to_vec(), max_values: None, max_size: Some(8 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETMAPU32".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETMAPU32").to_vec(), max_values: None, max_size: Some(8 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"GETMAPU32MYDEF".to_vec(), prefix: prefix(b"TestStorage", b"GETMAPU32MYDEF").to_vec(), max_values: None, max_size: Some(8 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PUBGETMAPU32MYDEF".to_vec(), prefix: prefix(b"TestStorage", b"PUBGETMAPU32MYDEF").to_vec(), max_values: None, max_size: Some(8 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"DOUBLEMAP".to_vec(), prefix: prefix(b"TestStorage", b"DOUBLEMAP").to_vec(), max_values: Some(3), max_size: Some(12 + 16 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"DOUBLEMAP2".to_vec(), prefix: prefix(b"TestStorage", b"DOUBLEMAP2").to_vec(), max_values: None, max_size: Some(12 + 16 + 16), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"COMPLEXTYPE1".to_vec(), prefix: prefix(b"TestStorage", b"COMPLEXTYPE1").to_vec(), max_values: Some(1), max_size: Some(5), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"COMPLEXTYPE2".to_vec(), prefix: prefix(b"TestStorage", b"COMPLEXTYPE2").to_vec(), max_values: Some(1), max_size: Some(1156), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"COMPLEXTYPE3".to_vec(), prefix: prefix(b"TestStorage", b"COMPLEXTYPE3").to_vec(), max_values: Some(1), max_size: Some(100), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"NMAP".to_vec(), prefix: prefix(b"TestStorage", b"NMAP").to_vec(), max_values: None, max_size: Some(16 + 4 + 8 + 2 + 1), }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"NMAP2".to_vec(), prefix: prefix(b"TestStorage", b"NMAP2").to_vec(), max_values: None, max_size: Some(16 + 4 + 1), }, ], ); } #[test] fn store_metadata() { let metadata = Module::::storage_metadata(); pretty_assertions::assert_eq!(expected_metadata(), metadata); } #[test] fn check_genesis_config() { let config = GenesisConfig::default(); assert_eq!(config.u32_getter_with_config, 0u32); assert_eq!(config.pub_u32_getter_with_config, 0u32); assert_eq!(config.pub_u32_getter_mydef, 3u32); assert_eq!(config.u32_getter_with_config_mydef, 2u32); assert_eq!(config.pub_u32_getter_with_config_mydef, 1u32); assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 0u32); } #[test] fn check_builder_config() { let config = GenesisConfig::default(); let storage = config.build_storage().unwrap(); TestExternalities::from(storage).execute_with(|| { assert_eq!(Module::::u32_with_builder(), 1); assert_eq!(Module::::opt_u32_with_builder_some(), Some(1)); assert_eq!(Module::::opt_u32_with_builder_none(), None); }) } } #[cfg(test)] #[allow(dead_code)] mod test2 { pub trait Config: frame_support_test::Config {} frame_support::decl_module! { pub struct Module for enum Call where origin: T::RuntimeOrigin, system=frame_support_test {} } type PairOf = (T, T); frame_support::decl_storage! { trait Store for Module as TestStorage { SingleDef : u32; PairDef : PairOf; Single : Option; Pair : (u32, u32); } add_extra_genesis { config(_marker) : ::std::marker::PhantomData; config(extra_field) : u32 = 32; build(|_| {}); } } struct TraitImpl {} impl frame_support_test::Config for TraitImpl { type RuntimeOrigin = u32; type BlockNumber = u32; type PalletInfo = frame_support_test::PanicPalletInfo; type DbWeight = (); } impl Config for TraitImpl {} #[test] fn storage_info() { use frame_support::{ storage::storage_prefix as prefix, traits::{StorageInfo, StorageInfoTrait}, }; pretty_assertions::assert_eq!( >::storage_info(), vec![ StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"SingleDef".to_vec(), prefix: prefix(b"TestStorage", b"SingleDef").to_vec(), max_values: Some(1), max_size: None, }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"PairDef".to_vec(), prefix: prefix(b"TestStorage", b"PairDef").to_vec(), max_values: Some(1), max_size: None, }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"Single".to_vec(), prefix: prefix(b"TestStorage", b"Single").to_vec(), max_values: Some(1), max_size: None, }, StorageInfo { pallet_name: b"TestStorage".to_vec(), storage_name: b"Pair".to_vec(), prefix: prefix(b"TestStorage", b"Pair").to_vec(), max_values: Some(1), max_size: None, }, ], ); } } #[cfg(test)] #[allow(dead_code)] mod test3 { pub trait Config: frame_support_test::Config {} frame_support::decl_module! { pub struct Module for enum Call where origin: T::RuntimeOrigin, system=frame_support_test {} } frame_support::decl_storage! { trait Store for Module as Test { Foo get(fn foo) config(initial_foo): u32; } } type PairOf = (T, T); struct TraitImpl {} impl frame_support_test::Config for TraitImpl { type RuntimeOrigin = u32; type BlockNumber = u32; type PalletInfo = frame_support_test::PanicPalletInfo; type DbWeight = (); } impl Config for TraitImpl {} } #[cfg(test)] #[allow(dead_code)] mod test_append_and_len { use codec::{Decode, Encode}; use sp_io::TestExternalities; pub trait Config: frame_support_test::Config {} frame_support::decl_module! { pub struct Module for enum Call where origin: T::RuntimeOrigin, system=frame_support_test {} } #[derive(PartialEq, Eq, Clone, Encode, Decode, scale_info::TypeInfo)] struct NoDef(u32); frame_support::decl_storage! { trait Store for Module as Test { NoDefault: Option; JustVec: Vec; JustVecWithDefault: Vec = vec![6, 9]; OptionVec: Option>; MapVec: map hasher(blake2_128_concat) u32 => Vec; MapVecWithDefault: map hasher(blake2_128_concat) u32 => Vec = vec![6, 9]; OptionMapVec: map hasher(blake2_128_concat) u32 => Option>; DoubleMapVec: double_map hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Vec; DoubleMapVecWithDefault: double_map hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Vec = vec![6, 9]; OptionDoubleMapVec: double_map hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Option>; } } struct Test {} impl frame_support_test::Config for Test { type RuntimeOrigin = u32; type BlockNumber = u32; type PalletInfo = frame_support_test::PanicPalletInfo; type DbWeight = (); } impl Config for Test {} #[test] fn default_for_option() { TestExternalities::default().execute_with(|| { assert_eq!(OptionVec::get(), None); assert!(JustVec::get().is_empty()); }); } #[test] fn append_works() { TestExternalities::default().execute_with(|| { for val in &[1, 2, 3, 4, 5] { MapVec::append(1, val); } assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); MapVec::remove(1); MapVec::append(1, 1); assert_eq!(MapVec::get(1), vec![1]); for val in &[1, 2, 3, 4, 5] { JustVec::append(val); } assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); JustVec::kill(); JustVec::append(1); assert_eq!(JustVec::get(), vec![1]); }); } #[test] fn append_overwrites_invalid_data() { TestExternalities::default().execute_with(|| { let key = JustVec::hashed_key(); // Set it to some invalid value. frame_support::storage::unhashed::put_raw(&key, b"1"); assert!(JustVec::get().is_empty()); assert_eq!(frame_support::storage::unhashed::get_raw(&key), Some(b"1".to_vec())); JustVec::append(1); JustVec::append(2); assert_eq!(JustVec::get(), vec![1, 2]); }); } #[test] fn append_overwrites_default() { TestExternalities::default().execute_with(|| { assert_eq!(JustVecWithDefault::get(), vec![6, 9]); JustVecWithDefault::append(1); assert_eq!(JustVecWithDefault::get(), vec![1]); assert_eq!(MapVecWithDefault::get(0), vec![6, 9]); MapVecWithDefault::append(0, 1); assert_eq!(MapVecWithDefault::get(0), vec![1]); assert_eq!(OptionVec::get(), None); OptionVec::append(1); assert_eq!(OptionVec::get(), Some(vec![1])); }); } #[test] fn len_works() { TestExternalities::default().execute_with(|| { JustVec::put(&vec![1, 2, 3, 4]); OptionVec::put(&vec![1, 2, 3, 4, 5]); MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]); DoubleMapVec::insert(0, 1, &vec![1, 2]); assert_eq!(JustVec::decode_len().unwrap(), 4); assert_eq!(OptionVec::decode_len().unwrap(), 5); assert_eq!(MapVec::decode_len(1).unwrap(), 6); assert_eq!(DoubleMapVec::decode_len(0, 1).unwrap(), 2); }); } // `decode_len` should always return `None` for default assigments // in `decl_storage!`. #[test] fn len_works_ignores_default_assignment() { TestExternalities::default().execute_with(|| { // vec assert!(JustVec::get().is_empty()); assert_eq!(JustVec::decode_len(), None); assert_eq!(JustVecWithDefault::get(), vec![6, 9]); assert_eq!(JustVecWithDefault::decode_len(), None); assert_eq!(OptionVec::get(), None); assert_eq!(OptionVec::decode_len(), None); // map assert!(MapVec::get(0).is_empty()); assert_eq!(MapVec::decode_len(0), None); assert_eq!(MapVecWithDefault::get(0), vec![6, 9]); assert_eq!(MapVecWithDefault::decode_len(0), None); assert_eq!(OptionMapVec::get(0), None); assert_eq!(OptionMapVec::decode_len(0), None); // Double map assert!(DoubleMapVec::get(0, 0).is_empty()); assert_eq!(DoubleMapVec::decode_len(0, 1), None); assert_eq!(DoubleMapVecWithDefault::get(0, 0), vec![6, 9]); assert_eq!(DoubleMapVecWithDefault::decode_len(0, 1), None); assert_eq!(OptionDoubleMapVec::get(0, 0), None); assert_eq!(OptionDoubleMapVec::decode_len(0, 1), None); }); } }