casperlabs-test-env 0.1.2

this package have basic utilities for CasperLabs Test Environment
Documentation
use std::path::PathBuf;

use casper_engine_test_support::{
    DeployItemBuilder, ExecuteRequestBuilder, InMemoryWasmTestBuilder, ARG_AMOUNT,
    DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT,
};
use casper_execution_engine::core::engine_state::ExecuteRequest;
use casper_types::{
    account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash,
    ContractPackageHash, Key, RuntimeArgs, StoredValue, U512,
};
use rand::Rng;

pub fn query<T: FromBytes + CLTyped>(
    builder: &InMemoryWasmTestBuilder,
    base: Key,
    path: &[String],
) -> T {
    builder
        .query(None, base, path)
        .expect("should be stored value.")
        .as_cl_value()
        .expect("should be cl value.")
        .clone()
        .into_t()
        .expect("Wrong type in query result.")
}

pub fn fund_account(account: &AccountHash) -> ExecuteRequest {
    let mut rng = rand::thread_rng();
    let deploy_item = DeployItemBuilder::new()
        .with_address(*DEFAULT_ACCOUNT_ADDR)
        .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
        .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
        .with_transfer_args(runtime_args! {
            mint::ARG_AMOUNT => U512::from(99_999_999_000_000_00u64),
            mint::ARG_TARGET => *account,
            mint::ARG_ID => <Option::<u64>>::None
        })
        .with_deploy_hash(rng.gen())
        .build();

    ExecuteRequestBuilder::from_deploy_item(deploy_item).build()
}

pub enum DeploySource {
    Code(PathBuf),
    ByContractHash {
        hash: ContractHash,
        method: String,
    },
    ByPackageHash {
        package_hash: ContractPackageHash,
        method: String,
    },
}

pub fn deploy(
    builder: &mut InMemoryWasmTestBuilder,
    deployer: &AccountHash,
    source: &DeploySource,
    args: RuntimeArgs,
    success: bool,
    block_time: Option<u64>,
) {
    let mut rng = rand::thread_rng();
    // let deploy_hash = rng.gen();
    let mut deploy_builder = DeployItemBuilder::new()
        .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
        .with_address(*deployer)
        .with_authorization_keys(&[*deployer])
        .with_deploy_hash(rng.gen());
    deploy_builder = match source {
        DeploySource::Code(path) => deploy_builder.with_session_code(path, args),
        DeploySource::ByContractHash { hash, method } => {
            deploy_builder.with_stored_session_hash(*hash, method, args)
        }
        DeploySource::ByPackageHash {
            package_hash,
            method,
        } => deploy_builder.with_stored_versioned_contract_by_hash(
            package_hash.value(),
            None,
            method,
            args,
        ),
    };

    let mut execute_request_builder =
        ExecuteRequestBuilder::from_deploy_item(deploy_builder.build());
    if let Some(ustamp) = block_time {
        execute_request_builder = execute_request_builder.with_block_time(ustamp)
    }
    let exec = builder.exec(execute_request_builder.build());
    if success {
        exec.expect_success()
    } else {
        exec.expect_failure()
    }
    .commit();
}

pub fn query_dictionary_item(
    builder: &InMemoryWasmTestBuilder,
    key: Key,
    dictionary_name: Option<String>,
    dictionary_item_key: String,
) -> Result<StoredValue, String> {
    let empty_path = vec![];
    let dictionary_key_bytes = dictionary_item_key.as_bytes();
    let address = match key {
        Key::Account(_) | Key::Hash(_) => {
            if let Some(name) = dictionary_name {
                let stored_value = builder.query(None, key, &[])?;

                let named_keys = match &stored_value {
                    StoredValue::Account(account) => account.named_keys(),
                    StoredValue::Contract(contract) => contract.named_keys(),
                    _ => {
                        return Err(
                            "Provided base key is nether an account or a contract".to_string()
                        )
                    }
                };

                let dictionary_uref = named_keys
                    .get(&name)
                    .and_then(Key::as_uref)
                    .ok_or_else(|| "No dictionary uref was found in named keys".to_string())?;

                Key::dictionary(*dictionary_uref, dictionary_key_bytes)
            } else {
                return Err("No dictionary name was provided".to_string());
            }
        }
        Key::URef(uref) => Key::dictionary(uref, dictionary_key_bytes),
        Key::Dictionary(address) => Key::Dictionary(address),
        _ => return Err("Unsupported key type for a query to a dictionary item".to_string()),
    };
    builder.query(None, address, &empty_path)
}