use cosmrs::Any;
use cosmwasm_std::{Coin, Timestamp};
use prost::Message;
use serde::de::DeserializeOwned;
use test_tube_tx::account::SigningAccount;
use test_tube_tx::runner::result::{RunnerExecuteResult, RunnerResult};
use test_tube_tx::runner::Runner;
use test_tube_tx::BaseApp;
pub const FEE_DENOM: &str = "ucore";
const ADDRESS_PREFIX: &str = "core";
const CHAIN_ID: &str = "coreum-mainnet-1";
const DEFAULT_GAS_ADJUSTMENT: f64 = 1.2;
#[derive(Debug, PartialEq)]
pub struct TXTestApp {
inner: BaseApp,
}
impl Default for TXTestApp {
fn default() -> Self {
TXTestApp::new()
}
}
impl TXTestApp {
pub fn new() -> Self {
Self {
inner: BaseApp::new(FEE_DENOM, CHAIN_ID, ADDRESS_PREFIX, DEFAULT_GAS_ADJUSTMENT),
}
}
pub fn get_block_timestamp(&self) -> Timestamp {
self.inner.get_block_timestamp()
}
pub fn get_block_time_nanos(&self) -> i64 {
self.inner.get_block_time_nanos()
}
pub fn get_block_time_seconds(&self) -> i64 {
self.inner.get_block_time_nanos() / 1_000_000_000i64
}
pub fn get_block_height(&self) -> i64 {
self.inner.get_block_height()
}
pub fn get_first_validator_address(&self) -> RunnerResult<String> {
self.inner.get_first_validator_address()
}
pub fn get_first_validator_signing_account(&self) -> RunnerResult<SigningAccount> {
self.inner.get_first_validator_signing_account()
}
pub fn increase_time(&self, seconds: u64) {
self.inner.increase_time(seconds)
}
pub fn init_account(&self, coins: &[Coin]) -> RunnerResult<SigningAccount> {
self.inner.init_account(coins)
}
pub fn init_accounts(&self, coins: &[Coin], count: u64) -> RunnerResult<Vec<SigningAccount>> {
self.inner.init_accounts(coins, count)
}
pub fn simulate_tx<I>(
&self,
msgs: I,
signer: &SigningAccount,
) -> RunnerResult<cosmrs::proto::cosmos::base::abci::v1beta1::GasInfo>
where
I: IntoIterator<Item = cosmrs::Any>,
{
self.inner.simulate_tx(msgs, signer)
}
pub fn set_param_set(&self, subspace: &str, pset: impl Into<Any>) -> RunnerResult<()> {
self.inner.set_param_set(subspace, pset)
}
pub fn get_param_set<P: Message + Default>(
&self,
subspace: &str,
type_url: &str,
) -> RunnerResult<P> {
self.inner.get_param_set(subspace, type_url)
}
}
impl<'a> Runner<'a> for TXTestApp {
fn execute_multiple<M, R>(
&self,
msgs: &[(M, &str)],
signer: &SigningAccount,
) -> RunnerExecuteResult<R>
where
M: ::prost::Message,
R: ::prost::Message + Default,
{
self.inner.execute_multiple(msgs, signer)
}
fn query<Q, R>(&self, path: &str, q: &Q) -> RunnerResult<R>
where
Q: ::prost::Message,
R: ::prost::Message + DeserializeOwned + Default,
{
self.inner.query(path, q)
}
fn execute_multiple_raw<R>(
&self,
msgs: Vec<cosmrs::Any>,
signer: &SigningAccount,
) -> RunnerExecuteResult<R>
where
R: prost::Message + Default,
{
self.inner.execute_multiple_raw(msgs, signer)
}
}
#[cfg(test)]
mod tests {
use cosmwasm_std::coins;
use crate::runner::app::{TXTestApp, FEE_DENOM};
#[test]
fn test_init_accounts() {
let app = TXTestApp::default();
let accounts = app
.init_accounts(&coins(100_000_000_000, FEE_DENOM), 3)
.unwrap();
assert!(accounts.get(0).is_some());
assert!(accounts.get(1).is_some());
assert!(accounts.get(2).is_some());
assert!(accounts.get(3).is_none());
}
#[test]
fn test_get_and_set_block_timestamp() {
let app = TXTestApp::default();
let block_time_nanos = app.get_block_time_nanos();
let block_time_seconds = app.get_block_time_seconds();
app.increase_time(10u64);
assert_eq!(
app.get_block_time_nanos(),
block_time_nanos + 10_000_000_000
);
assert_eq!(app.get_block_time_seconds(), block_time_seconds + 10);
}
#[test]
fn test_get_block_height() {
let app = TXTestApp::default();
assert_eq!(app.get_block_height(), 1i64);
app.increase_time(10u64);
assert_eq!(app.get_block_height(), 2i64);
}
}