diff --git a/README.md b/README.md index b63286be..6b56264f 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,14 @@ Four main API methods are offered: * `process_instruction`: Process an instruction and return the result. * `process_and_validate_instruction`: Process an instruction and perform a - series of checks on the result, panicking if any checks fail. + series of checks on the result. By default, failing checks cause a panic, + but this behavior is configurable through `Mollusk::config`. * `process_instruction_chain`: Process a chain of instructions and return the result. * `process_and_validate_instruction_chain`: Process a chain of instructions - and perform a series of checks on each result, panicking if any checks - fail. + and perform a series of checks on each result. By default, failing checks + cause a panic, but this behavior is configurable through + `Mollusk::config`. ## Single Instructions diff --git a/harness/src/lib.rs b/harness/src/lib.rs index ebb7d38c..32850b96 100644 --- a/harness/src/lib.rs +++ b/harness/src/lib.rs @@ -27,12 +27,14 @@ //! //! * `process_instruction`: Process an instruction and return the result. //! * `process_and_validate_instruction`: Process an instruction and perform a -//! series of checks on the result, panicking if any checks fail. +//! series of checks on the result. By default, failing checks cause a panic, +//! but this behavior is configurable through `Mollusk::config`. //! * `process_instruction_chain`: Process a chain of instructions and return //! the result. //! * `process_and_validate_instruction_chain`: Process a chain of instructions -//! and perform a series of checks on each result, panicking if any checks -//! fail. +//! and perform a series of checks on each result. By default, failing checks +//! cause a panic, but this behavior is configurable through +//! `Mollusk::config`. //! //! ## Single Instructions //! diff --git a/result/src/check.rs b/result/src/check.rs index 43fab210..7db96ff8 100644 --- a/result/src/check.rs +++ b/result/src/check.rs @@ -5,12 +5,14 @@ use { config::{compare, throw, CheckContext, Config}, types::{InstructionResult, ProgramResult}, }, - solana_account::ReadableAccount, + solana_account::{Account, ReadableAccount}, solana_instruction::error::InstructionError, solana_program_error::ProgramError, solana_pubkey::Pubkey, }; +type AccountCheckFn = dyn Fn(&[(Pubkey, Account)]) -> bool; + enum CheckType<'a> { /// Check the number of compute units consumed by the instruction. ComputeUnitsConsumed(u64), @@ -22,8 +24,10 @@ enum CheckType<'a> { ReturnData(&'a [u8]), /// Check a resulting account after executing the instruction. ResultingAccount(AccountCheck<'a>), - /// Check that all accounts are rent exempt + /// Check that all accounts are rent exempt. AllRentExempt, + /// Custom check for accounts. + Custom((Box, &'static str)), } pub struct Check<'a> { @@ -75,10 +79,18 @@ impl<'a> Check<'a> { AccountCheckBuilder::new(pubkey) } - /// Check that all resulting accounts are rent exempt + /// Check that all resulting accounts are rent exempt. pub fn all_rent_exempt() -> Self { Check::new(CheckType::AllRentExempt) } + + /// Custom check for accounts. + pub fn custom(function: F, function_name: &'static str) -> Self + where + F: Fn(&[(Pubkey, Account)]) -> bool + 'static, + { + Check::new(CheckType::Custom((Box::new(function), function_name))) + } } enum AccountStateCheck { @@ -298,6 +310,10 @@ impl InstructionResult { } } } + CheckType::Custom((function, function_name)) => { + println!("Calling {}", *function_name); + pass &= function(&self.resulting_accounts); + } } } pass