apollo_cw_multi_test/
executor.rs1use std::fmt;
2
3use cosmwasm_std::{
4 to_binary, Addr, Attribute, BankMsg, Binary, Coin, CosmosMsg, Event, SubMsgResponse, WasmMsg,
5};
6use cw_utils::{parse_execute_response_data, parse_instantiate_response_data};
7use schemars::JsonSchema;
8use serde::Serialize;
9
10use anyhow::Result as AnyResult;
11
12#[derive(Default, Clone, Debug)]
13pub struct AppResponse {
14 pub events: Vec<Event>,
15 pub data: Option<Binary>,
16}
17
18impl AppResponse {
19 #[track_caller]
22 pub fn custom_attrs(&self, idx: usize) -> &[Attribute] {
23 assert_eq!(self.events[idx].ty.as_str(), "wasm");
24 &self.events[idx].attributes[1..]
25 }
26
27 pub fn has_event(&self, expected: &Event) -> bool {
31 self.events.iter().any(|ev| {
32 expected.ty == ev.ty
33 && expected
34 .attributes
35 .iter()
36 .all(|at| ev.attributes.contains(at))
37 })
38 }
39
40 #[track_caller]
42 pub fn assert_event(&self, expected: &Event) {
43 assert!(
44 self.has_event(expected),
45 "Expected to find an event {:?}, but received: {:?}",
46 expected,
47 self.events
48 );
49 }
50}
51
52impl From<SubMsgResponse> for AppResponse {
55 fn from(reply: SubMsgResponse) -> Self {
56 AppResponse {
57 data: reply.data,
58 events: reply.events,
59 }
60 }
61}
62
63pub trait Executor<C>
64where
65 C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static,
66{
67 fn execute(&self, sender: Addr, msg: CosmosMsg<C>) -> AnyResult<AppResponse>;
71
72 fn instantiate_contract<T: Serialize, U: Into<String>>(
75 &self,
76 code_id: u64,
77 sender: Addr,
78 init_msg: &T,
79 send_funds: &[Coin],
80 label: U,
81 admin: Option<String>,
82 ) -> AnyResult<Addr> {
83 let init_msg = to_binary(init_msg)?;
85 let msg = WasmMsg::Instantiate {
86 admin,
87 code_id,
88 msg: init_msg,
89 funds: send_funds.to_vec(),
90 label: label.into(),
91 };
92 let res = self.execute(sender, msg.into())?;
93 let data = parse_instantiate_response_data(res.data.unwrap_or_default().as_slice())?;
94 Ok(Addr::unchecked(data.contract_address))
95 }
96
97 fn execute_contract<T: Serialize + std::fmt::Debug>(
101 &self,
102 sender: Addr,
103 contract_addr: Addr,
104 msg: &T,
105 send_funds: &[Coin],
106 ) -> AnyResult<AppResponse> {
107 let binary_msg = to_binary(msg)?;
108 let wrapped_msg = WasmMsg::Execute {
109 contract_addr: contract_addr.into_string(),
110 msg: binary_msg,
111 funds: send_funds.to_vec(),
112 };
113 let mut res = self.execute(sender, wrapped_msg.into())?;
114 res.data = res
115 .data
116 .and_then(|d| parse_execute_response_data(d.as_slice()).unwrap().data);
117 Ok(res)
118 }
119
120 fn migrate_contract<T: Serialize>(
123 &mut self,
124 sender: Addr,
125 contract_addr: Addr,
126 msg: &T,
127 new_code_id: u64,
128 ) -> AnyResult<AppResponse> {
129 let msg = to_binary(msg)?;
130 let msg = WasmMsg::Migrate {
131 contract_addr: contract_addr.into(),
132 msg,
133 new_code_id,
134 };
135 self.execute(sender, msg.into())
136 }
137
138 fn send_tokens(
139 &mut self,
140 sender: Addr,
141 recipient: Addr,
142 amount: &[Coin],
143 ) -> AnyResult<AppResponse> {
144 let msg = BankMsg::Send {
145 to_address: recipient.to_string(),
146 amount: amount.to_vec(),
147 };
148 self.execute(sender, msg.into())
149 }
150}