Skip to content

Commit

Permalink
Test for handling custom execution messages
Browse files Browse the repository at this point in the history
  • Loading branch information
hashedone committed Sep 1, 2021
1 parent f4ef0b1 commit f96a7ba
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 23 deletions.
72 changes: 65 additions & 7 deletions packages/multi-test/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ where
self
}

/// Overwrites default custom messages handler
#[track_caller]
pub fn with_custom(mut self, custom: impl CustomHandler<ExecC, QueryC> + 'static) -> Self {
assert!(self.custom.is_none(), "Custom handler already overwritten");
self.custom = Some(Box::new(custom));
self
}

/// Overwrites default initial block
#[track_caller]
pub fn with_block(mut self, block: BlockInfo) -> Self {
Expand Down Expand Up @@ -1077,7 +1085,7 @@ mod test {
.execute_contract(
owner,
contract,
&echo::Message {
&echo::Message::<Empty> {
data: Some("Data".to_owned()),
..echo::Message::default()
},
Expand Down Expand Up @@ -1225,7 +1233,7 @@ mod test {
// reflect will call echo
// echo will set the data
// top-level app will not display the data
let echo_msg = echo::Message {
let echo_msg = echo::Message::<Empty> {
data: Some("my echo".into()),
events: vec![Event::new("echo").add_attribute("called", "true")],
..echo::Message::default()
Expand Down Expand Up @@ -1408,7 +1416,7 @@ mod test {
.execute_contract(
owner,
contract,
&echo::Message {
&echo::Message::<Empty> {
data: None,
attributes: vec![
Attribute::new(" ", "value"),
Expand Down Expand Up @@ -1438,7 +1446,7 @@ mod test {
.execute_contract(
owner,
contract,
&echo::Message {
&echo::Message::<Empty> {
data: None,
attributes: vec![
Attribute::new("key", " "),
Expand Down Expand Up @@ -1468,7 +1476,7 @@ mod test {
.execute_contract(
owner,
contract,
&echo::Message {
&echo::Message::<Empty> {
data: None,
events: vec![Event::new("event")
.add_attribute(" ", "value")
Expand Down Expand Up @@ -1497,7 +1505,7 @@ mod test {
.execute_contract(
owner,
contract,
&echo::Message {
&echo::Message::<Empty> {
data: None,
events: vec![Event::new("event")
.add_attribute("key", " ")
Expand Down Expand Up @@ -1526,7 +1534,7 @@ mod test {
.execute_contract(
owner,
contract,
&echo::Message {
&echo::Message::<Empty> {
data: None,
events: vec![Event::new(" e "), Event::new("event")],
..echo::Message::default()
Expand All @@ -1538,4 +1546,54 @@ mod test {
assert_eq!(Error::event_type_too_short("e"), err.downcast().unwrap());
}
}

mod custom_messages {
use super::*;
use mockall as ma;

#[test]
fn triggering_custom_msg() {
let api = MockApi::default();
let sender = api.addr_validate("sender").unwrap();
let owner = api.addr_validate("owner").unwrap();

let mut custom_handler = MockSimpleCustomHandler::<CustomMsg, Empty>::new();
custom_handler
.expect_execute()
.with(
ma::predicate::always(),
ma::predicate::always(),
ma::predicate::eq(CustomMsg::SetAge { age: 20 }),
)
.returning(|_, _, _| {
Ok(AppResponse {
data: None,
events: vec![],
})
});

let mut app = AppBuilder::new()
.with_api(api)
.with_custom(custom_handler)
.build();

let contract_id = app.store_code(echo::custom_contract());
let contract = app
.instantiate_contract(contract_id, owner.clone(), &EmptyMsg {}, &[], "Echo", None)
.unwrap();

app.execute_contract(
sender,
contract,
&echo::Message {
sub_msg: vec![SubMsg::new(CosmosMsg::Custom(CustomMsg::SetAge {
age: 20,
}))],
..Default::default()
},
&[],
)
.unwrap();
}
}
}
47 changes: 31 additions & 16 deletions packages/multi-test/src/test_helpers/contracts/echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,49 @@ use cosmwasm_std::{
to_binary, Attribute, Binary, ContractResult, Deps, DepsMut, Empty, Env, Event, MessageInfo,
Reply, Response, StdError, SubMsg, SubMsgExecutionResponse,
};
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};

use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper};
use schemars::JsonSchema;
use std::fmt;
use std::fmt::Debug;

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Message {
use derivative::Derivative;

#[derive(Debug, Clone, Serialize, Deserialize, Derivative)]
#[derivative(Default(bound = "", new = "true"))]
pub struct Message<ExecC>
where
ExecC: Debug + PartialEq + Clone + JsonSchema + 'static,
{
pub data: Option<String>,
pub sub_msg: Vec<SubMsg>,
pub sub_msg: Vec<SubMsg<ExecC>>,
pub attributes: Vec<Attribute>,
pub events: Vec<Event>,
}

#[allow(clippy::unnecessary_wraps)]
fn instantiate(
fn instantiate<ExecC>(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
_msg: EmptyMsg,
) -> Result<Response, StdError> {
) -> Result<Response<ExecC>, StdError>
where
ExecC: Debug + PartialEq + Clone + JsonSchema + 'static,
{
Ok(Response::default())
}

#[allow(clippy::unnecessary_wraps)]
fn execute(
fn execute<ExecC>(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
msg: Message,
) -> Result<Response, StdError> {
msg: Message<ExecC>,
) -> Result<Response<ExecC>, StdError>
where
ExecC: Debug + PartialEq + Clone + JsonSchema + 'static,
{
let mut resp = Response::new();

if let Some(data) = msg.data {
Expand All @@ -55,7 +67,10 @@ fn query(_deps: Deps, _env: Env, msg: EmptyMsg) -> Result<Binary, StdError> {
}

#[allow(clippy::unnecessary_wraps)]
fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, StdError> {
fn reply<ExecC>(_deps: DepsMut, _env: Env, msg: Reply) -> Result<Response<ExecC>, StdError>
where
ExecC: Debug + PartialEq + Clone + JsonSchema + 'static,
{
if let Reply {
result:
ContractResult::Ok(SubMsgExecutionResponse {
Expand All @@ -71,16 +86,16 @@ fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, StdError> {
}

pub fn contract() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(execute, instantiate, query).with_reply(reply);
let contract = ContractWrapper::new(execute::<Empty>, instantiate::<Empty>, query)
.with_reply(reply::<Empty>);
Box::new(contract)
}

#[allow(dead_code)]
pub fn custom_contract<C>() -> Box<dyn Contract<C>>
where
C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static,
C: Clone + Debug + PartialEq + JsonSchema + DeserializeOwned + 'static,
{
let contract = ContractWrapper::new_with_empty(execute, instantiate, query);
let contract = contract.with_reply_empty(reply);
let contract =
ContractWrapper::new(execute::<C>, instantiate::<C>, query).with_reply(reply::<C>);
Box::new(contract)
}

0 comments on commit f96a7ba

Please sign in to comment.