casperlabs-test-env 0.1.2

this package have basic utilities for CasperLabs Test Environment
Documentation
use std::sync::{Arc, Mutex};

use casper_engine_test_support::{InMemoryWasmTestBuilder, DEFAULT_RUN_GENESIS_REQUEST};
use casper_types::{
    account::AccountHash, bytesrepr::FromBytes, CLTyped, Key, PublicKey, RuntimeArgs, SecretKey,
};

use crate::utils::{deploy, fund_account, query, query_dictionary_item, DeploySource};

#[derive(Clone)]
pub struct TestEnv {
    state: Arc<Mutex<TestEnvState>>,
}

impl TestEnv {
    pub fn new() -> TestEnv {
        TestEnv {
            state: Arc::new(Mutex::new(TestEnvState::new())),
        }
    }

    pub fn run(
        &self,
        sender: AccountHash,
        session_code: DeploySource,
        session_args: RuntimeArgs,
        time: u64,
    ) {
        deploy(
            &mut self.state.lock().unwrap().builder,
            &sender,
            &session_code,
            session_args,
            true,
            Some(time),
        )
    }

    pub fn next_user(&self) -> AccountHash {
        self.state.lock().unwrap().next_user()
    }

    pub fn query_dictionary<T: CLTyped + FromBytes>(
        &self,
        contract_hash: [u8; 32],
        dict_name: &str,
        key: String,
    ) -> Option<T> {
        self.state
            .lock()
            .unwrap()
            .query_dictionary(contract_hash, dict_name.to_string(), key)
    }

    pub fn query_account_named_key<T: CLTyped + FromBytes>(
        &self,
        account: AccountHash,
        path: &[String],
    ) -> T {
        self.state
            .lock()
            .unwrap()
            .query_account_named_key(account, path)
    }
}

impl Default for TestEnv {
    fn default() -> Self {
        TestEnv::new()
    }
}

struct TestEnvState {
    builder: InMemoryWasmTestBuilder,
    accounts: Vec<AccountHash>,
}

impl TestEnvState {
    pub fn new() -> TestEnvState {
        let mut builder = InMemoryWasmTestBuilder::default();
        builder.run_genesis(&DEFAULT_RUN_GENESIS_REQUEST).commit();
        let mut accounts = Vec::new();
        for i in 0..10u8 {
            let secret_key: SecretKey = SecretKey::ed25519_from_bytes([i; 32]).unwrap();
            let public_key: PublicKey = (&secret_key).into();
            let account_hash = AccountHash::from(&public_key);
            accounts.push(account_hash);
            builder
                .exec(fund_account(&account_hash))
                .expect_success()
                .commit();
        }

        TestEnvState { builder, accounts }
    }

    pub fn _new_with_users(user_secrets: &[[u8; 32]]) -> TestEnvState {
        let mut builder = InMemoryWasmTestBuilder::default();
        builder.run_genesis(&DEFAULT_RUN_GENESIS_REQUEST).commit();

        let mut accounts = Vec::new();
        for user_secret in user_secrets {
            let secret_key: SecretKey = SecretKey::ed25519_from_bytes(user_secret).unwrap();
            let public_key: PublicKey = (&secret_key).into();
            let account_hash = AccountHash::from(&public_key);
            accounts.push(account_hash);
            builder
                .exec(fund_account(&account_hash))
                .expect_success()
                .commit();
        }

        TestEnvState { builder, accounts }
    }

    pub fn next_user(&mut self) -> AccountHash {
        self.accounts.pop().unwrap()
    }

    pub fn _run(
        &mut self,
        sender: AccountHash,
        session_code: DeploySource,
        session_args: RuntimeArgs,
    ) {
        deploy(
            &mut self.builder,
            &sender,
            &session_code,
            session_args,
            true,
            None,
        )
    }

    pub fn query_dictionary<T: CLTyped + FromBytes>(
        &self,
        contract_hash: [u8; 32],
        dict_name: String,
        dictionary_item_key: String,
    ) -> Option<T> {
        match query_dictionary_item(
            &self.builder,
            Key::Hash(contract_hash),
            Some(dict_name),
            dictionary_item_key,
        ) {
            Ok(value) => value
                .as_cl_value()
                .expect("should be cl value.")
                .clone()
                .into_t()
                .expect("Wrong type in query result."),
            Err(e) => {
                println!("{}", e);
                None
            }
        }
    }

    pub fn query_account_named_key<T: CLTyped + FromBytes>(
        &self,
        account: AccountHash,
        path: &[String],
    ) -> T {
        query(&self.builder, Key::Account(account), path)
    }
}