fvm-mock 1.0.0

tool for user to test contract locally
Documentation
use std::cell::RefCell;
use std::rc::Rc;
use fvm_std::prelude::{Vec, H256, Address};
use fvm_std::types::LogLevel;
use crate::mock_runtime::{RuntimeInner, Runtime, setup_runtime};


pub struct MockRuntime {
    inner: Rc<RefCell<RuntimeInner>>,
}

impl MockRuntime {
    pub fn storage_write<K: AsRef<[u8]>, P: AsRef<[u8]>, V: AsRef<[u8]>>(&self, key: K, prefix: P, val: V) -> &Self {
        let mut p = prefix.as_ref().to_vec();
        let mut k = key.as_ref().to_vec();
        p.append(&mut k);
        self.inner.borrow_mut().storage.insert(p, val.as_ref().to_vec());
        self
    }

    pub fn storage_read(&self, key: &[u8], prefix: &[u8]) -> Option<Vec<u8>> {
        let mut p = prefix.as_ref().to_vec();
        let mut k = key.as_ref().to_vec();
        p.append(&mut k);
        self.inner.borrow().storage.get(&p).map(|val| {
            val.to_vec()
        })
    }

    pub fn storage_delete(&self, key: &[u8], prefix: &[u8]) -> &Self {
        let mut p = prefix.to_vec();
        let mut s = key.to_vec();
        p.append(&mut s);
        self.inner.borrow_mut().storage.remove(&p);
        self
    }

    pub fn block_time(&self, time: u64) -> &Self {
        self.inner.borrow_mut().block_time = time;
        self
    }

    pub fn block_height(&self, height: u64) -> &Self {
        self.inner.borrow_mut().block_height = height;
        self
    }

    pub fn self_address(&self, addr: &Address) -> &Self {
        self.inner.borrow_mut().self_addr = addr.clone();
        self
    }

    pub fn caller_address(&self, caller: &Address) -> &Self {
        self.inner.borrow_mut().caller_addr = caller.clone();
        self
    }

    pub fn origin_address(&self, origin: &Address) -> &Self {
        self.inner.borrow_mut().origin_addr = origin.clone();
        self
    }

    pub fn tx_hash(&self, tx_hash: &H256) -> &Self {
        self.inner.borrow_mut().tx_hash = tx_hash.clone();
        self
    }

    pub fn call_contracts<T: scale::Encode>(&self, call_rets: Vec<T>) -> &Self {
        for c in call_rets {
            self.inner.borrow_mut().call_return.insert(0, T::encode(&c))
        }
        self
    }

    pub fn call_contract<T: scale::Encode>(&self, call_ret: T) -> &Self {
        self.inner.borrow_mut().call_return.insert(0, call_ret.encode());
        self
    }

    pub fn input(&self, _dis: &[u8]) -> &Self {
        self.inner.borrow_mut().input = _dis.to_vec();
        self
    }

    pub fn ret(&self, msg: &[u8]) -> &Self {
        self.inner.borrow_mut().ret = msg.to_vec();
        self
    }

    pub fn get_log(&self, level: LogLevel) -> Vec<Vec<u8>> {
        return self.inner.borrow().debug.get(&level.to_int()).expect("error level").to_vec();
    }

    pub fn get_event(&self) -> Vec<Vec<u8>> {
        self.inner.borrow().log.to_vec()
    }

    pub fn get_ret(&self) -> Vec<u8> {
        self.inner.borrow().ret.to_vec()
    }
}

pub fn build_runtime() -> MockRuntime {
    let inner = Rc::new(RefCell::new(RuntimeInner::default()));

    let rt = Runtime { inner: inner.clone() };
    setup_runtime(rt);

    MockRuntime { inner }
}