From c0e75222232bbfb6f30efefb07828c3702ff6c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 1 Sep 2021 13:42:39 +0200 Subject: [PATCH 1/5] Better multitest::App creation interface --- Cargo.lock | 238 ++++++++++++++---- contracts/cw20-escrow/src/integration_test.rs | 9 +- .../src/integration_tests.rs | 9 +- contracts/cw3-flex-multisig/src/contract.rs | 9 +- packages/multi-test/Cargo.toml | 2 + packages/multi-test/src/app.rs | 119 ++++++--- packages/multi-test/src/lib.rs | 2 +- packages/multi-test/src/wasm.rs | 5 +- 8 files changed, 286 insertions(+), 107 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ff235761..681d5fcb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.43" @@ -103,15 +112,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" [[package]] name = "cfg-if" @@ -127,9 +136,9 @@ checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" [[package]] name = "cosmwasm-crypto" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa1715a9b71c7c31385a3f021dee2fd0a17b82043ab937467e103aa25043d2e" +checksum = "a965098e28b1338513185746efe1f57c974aebb9e3869ded3361dc3bffbc780d" dependencies = [ "digest 0.9.0", "ed25519-zebra", @@ -140,18 +149,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6e6dff07965015c4fcdf477c4becde738a2bfb40cf6239bdcea9335016c5a2" +checksum = "be68adf023b7d37de680cb901d2a1179473fee3aa25435ad0b3c7267ae965cdb" dependencies = [ "syn", ] [[package]] name = "cosmwasm-schema" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9ba1eea088e7f1ec4a7679c43adcb51e80cbc2af6a6d83d1bb652b7adaf6dc" +checksum = "534e3160bea28e7a0e1b63532c1b5ce558c5a400030777b73d21316a1309a6f7" dependencies = [ "schemars", "serde_json", @@ -159,9 +168,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92bdeee0ebba164ebbef9380522cc50f889db38acc1f1210f6b55ee2244b8c59" +checksum = "a14b383575cc9a579d1bb5b7d5eaee74fda8449c25f9d6c736fee282dc025013" dependencies = [ "base64", "cosmwasm-crypto", @@ -175,9 +184,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e26053f14f971b05abca3be34f80c631d70c5b5b9df175e7a1d8b4aad83e40cc" +checksum = "46e70e058e316453284cf5561fbebc4fde68f5dfd99a57dc7146e1892465f1c6" dependencies = [ "cosmwasm-std", "serde", @@ -185,9 +194,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] @@ -200,9 +209,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09910f0830248af4499907177608b81d640c8c404526f8770b87b765fbd8c9a5" +checksum = "cc209804a22c34a98fe26a32d997ac64d4284816f65cf1a529c4e31a256218a0" dependencies = [ "generic-array 0.14.4", "rand_core 0.6.3", @@ -254,7 +263,9 @@ dependencies = [ "cosmwasm-storage", "cw-storage-plus", "cw0", + "derivative", "itertools", + "mockall", "prost", "schemars", "serde", @@ -466,7 +477,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sha2 0.9.5", + "sha2 0.9.6", "thiserror", ] @@ -612,6 +623,23 @@ dependencies = [ "const-oid", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + [[package]] name = "digest" version = "0.8.1" @@ -630,6 +658,12 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "downcast" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" + [[package]] name = "dyn-clone" version = "1.0.4" @@ -658,7 +692,7 @@ dependencies = [ "hex 0.4.3", "rand_core 0.5.1", "serde", - "sha2 0.9.5", + "sha2 0.9.6", "thiserror", ] @@ -670,9 +704,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069397e10739989e400628cbc0556a817a8a64119d7a2315767f4456e1332c23" +checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" dependencies = [ "crypto-bigint", "ff", @@ -700,6 +734,21 @@ dependencies = [ "subtle", ] +[[package]] +name = "float-cmp" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fragile" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2" + [[package]] name = "generic-array" version = "0.12.4" @@ -809,9 +858,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "k256" @@ -822,20 +871,26 @@ dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.9.5", + "sha2 0.9.6", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" -version = "0.2.99" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "miniz_oxide" @@ -847,6 +902,39 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mockall" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab571328afa78ae322493cacca3efac6a0f2e0a67305b4df31fd439ef129ac0" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e25b214433f669161f414959594216d8e6ba83b6679d3db96899c0b4639033" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "num-traits" version = "0.2.14" @@ -858,9 +946,9 @@ dependencies = [ [[package]] name = "object" -version = "0.26.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" dependencies = [ "memchr", ] @@ -887,11 +975,40 @@ dependencies = [ "spki", ] +[[package]] +name = "predicates" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" +dependencies = [ + "difference", + "float-cmp", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" + +[[package]] +name = "predicates-tree" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d" +dependencies = [ + "predicates-core", + "treeline", +] + [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] @@ -946,6 +1063,23 @@ dependencies = [ "getrandom 0.2.3", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "rust_decimal" version = "1.15.0" @@ -959,9 +1093,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "ryu" @@ -995,9 +1129,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] @@ -1013,9 +1147,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -1035,9 +1169,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" dependencies = [ "itoa", "ryu", @@ -1058,9 +1192,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ "block-buffer 0.9.0", "cfg-if", @@ -1102,9 +1236,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" dependencies = [ "proc-macro2", "quote", @@ -1113,24 +1247,30 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "treeline" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" + [[package]] name = "typenum" version = "1.13.0" diff --git a/contracts/cw20-escrow/src/integration_test.rs b/contracts/cw20-escrow/src/integration_test.rs index 4733adf77..c19cd2254 100644 --- a/contracts/cw20-escrow/src/integration_test.rs +++ b/contracts/cw20-escrow/src/integration_test.rs @@ -1,18 +1,13 @@ #![cfg(test)] -use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{coins, to_binary, Addr, Empty, Uint128}; use cw20::{Cw20Coin, Cw20Contract, Cw20ExecuteMsg}; -use cw_multi_test::{App, BankKeeper, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper, Executor}; use crate::msg::{CreateMsg, DetailsResponse, ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg}; fn mock_app() -> App { - let env = mock_env(); - let api = MockApi::default(); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, MockStorage::new()) + AppBuilder::new().build() } pub fn contract_escrow() -> Box> { diff --git a/contracts/cw3-fixed-multisig/src/integration_tests.rs b/contracts/cw3-fixed-multisig/src/integration_tests.rs index e0d7dee8b..17c866423 100644 --- a/contracts/cw3-fixed-multisig/src/integration_tests.rs +++ b/contracts/cw3-fixed-multisig/src/integration_tests.rs @@ -2,20 +2,15 @@ use crate::contract::{execute, instantiate, query}; use crate::msg::{ExecuteMsg, InstantiateMsg, Voter}; -use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{to_binary, Addr, Empty, Uint128, WasmMsg}; use cw0::Duration; use cw20::{BalanceResponse, MinterResponse}; use cw20_base::msg::QueryMsg; use cw3::Vote; -use cw_multi_test::{App, BankKeeper, Contract, ContractWrapper, Executor}; +use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper, Executor}; fn mock_app() -> App { - let env = mock_env(); - let api = MockApi::default(); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, MockStorage::new()) + AppBuilder::new().build() } pub fn contract_cw3_fixed_multisig() -> Box> { diff --git a/contracts/cw3-flex-multisig/src/contract.rs b/contracts/cw3-flex-multisig/src/contract.rs index 59049d41f..a5021d0b2 100644 --- a/contracts/cw3-flex-multisig/src/contract.rs +++ b/contracts/cw3-flex-multisig/src/contract.rs @@ -424,14 +424,13 @@ fn list_voters( #[cfg(test)] mod tests { - use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp}; use cw0::Duration; use cw2::{query_contract_info, ContractVersion}; use cw4::{Cw4ExecuteMsg, Member}; use cw4_group::helpers::Cw4GroupContract; - use cw_multi_test::{next_block, App, BankKeeper, Contract, ContractWrapper, Executor}; + use cw_multi_test::{next_block, App, AppBuilder, Contract, ContractWrapper, Executor}; use super::*; use crate::msg::Threshold; @@ -470,11 +469,7 @@ mod tests { } fn mock_app() -> App { - let env = mock_env(); - let api = MockApi::default(); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, MockStorage::new()) + AppBuilder::new().build() } // uploads code and returns address of group contract diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index 6244b371d..b8cd3e607 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -27,3 +27,5 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } prost = "0.8.0" anyhow = "1" thiserror = "1" +mockall = "0.10" +derivative = "2" diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 611d231eb..3bd9aabca 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -1,7 +1,6 @@ -use std::fmt; +use std::fmt::{self, Debug}; -#[cfg(test)] -use cosmwasm_std::testing::{mock_env, MockApi}; +use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{ from_slice, to_vec, Addr, Api, Binary, BlockInfo, Coin, ContractResult, CosmosMsg, Empty, Querier, QuerierResult, QuerierWrapper, QueryRequest, Storage, SystemError, SystemResult, @@ -14,8 +13,10 @@ use crate::contracts::Contract; use crate::executor::{AppResponse, Executor}; use crate::transactions::transactional; use crate::wasm::{ContractData, Wasm, WasmKeeper}; +use crate::BankKeeper; use anyhow::Result as AnyResult; +use derivative::Derivative; pub fn next_block(block: &mut BlockInfo) { block.time = block.time.plus_seconds(5); @@ -60,24 +61,89 @@ where } } -impl App +/// Utility to build App in stages. If particular items wont be set, defaults would be used +#[derive(Derivative)] +#[derivative(Default(bound = "", new = "true"))] +pub struct AppBuilder { + wasm: Option>>, + bank: Option>, + api: Option>, + storage: Option>, + block: Option, +} + +impl AppBuilder where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + C: Debug + PartialEq + Clone + JsonSchema + 'static, { - pub fn new( - api: impl Api + 'static, - block: BlockInfo, - bank: impl Bank + 'static, - storage: impl Storage + 'static, - ) -> Self { + /// Overwrites default wasm executor. Panic if already set. + #[track_caller] + pub fn with_wasm(mut self, wasm: impl Wasm + 'static) -> Self { + assert!(self.wasm.is_none(), "Wasm executor already overwritten"); + self.wasm = Some(Box::new(wasm)); + self + } + + /// Overwrites default bank interface + #[track_caller] + pub fn with_bank(mut self, bank: impl Bank + 'static) -> Self { + assert!(self.bank.is_none(), "Bank interface already overwritten"); + self.bank = Some(Box::new(bank)); + self + } + + /// Overwrites default api interface + #[track_caller] + pub fn with_api(mut self, api: impl Api + 'static) -> Self { + assert!(self.api.is_none(), "API interface already overwritten"); + self.api = Some(Box::new(api)); + self + } + + /// Overwrites default storage interface + #[track_caller] + pub fn with_storage(mut self, storage: impl Storage + 'static) -> Self { + assert!( + self.storage.is_none(), + "Storage interface already overwritten" + ); + self.storage = Some(Box::new(storage)); + self + } + + /// Overwrites default initial block + #[track_caller] + pub fn with_block(mut self, block: BlockInfo) -> Self { + assert!( + self.block.is_none(), + "Initial block info already overwritten" + ); + self.block = Some(block); + self + } + + pub fn build(self) -> App { + let wasm = self.wasm.unwrap_or_else(|| Box::new(WasmKeeper::new())); + let bank = self.bank.unwrap_or_else(|| Box::new(BankKeeper::new())); + let api = self.api.unwrap_or_else(|| Box::new(MockApi::default())); + let storage = self.storage.unwrap_or_else(|| Box::new(MockStorage::new())); + let block = self.block.unwrap_or_else(|| mock_env().block); + + let router = Router { wasm, bank }; + App { - router: Router::new(bank), - api: Box::new(api), - storage: Box::new(storage), + router, + api, + storage, block, } } +} +impl App +where + C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, +{ pub fn set_block(&mut self, block: BlockInfo) { self.block = block; } @@ -163,21 +229,14 @@ where } pub struct Router { - pub wasm: Box>, - pub bank: Box, + pub(crate) wasm: Box>, + pub(crate) bank: Box, } impl Router where C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, { - pub(super) fn new(bank: impl Bank + 'static) -> Self { - Router { - wasm: Box::new(WasmKeeper::new()), - bank: Box::new(bank), - } - } - pub fn querier<'a>( &'a self, api: &'a dyn Api, @@ -281,7 +340,6 @@ where #[cfg(test)] mod test { - use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{ coin, coins, to_binary, AllBalanceResponse, Attribute, BankMsg, BankQuery, Event, Reply, StdResult, SubMsg, WasmMsg, @@ -291,25 +349,16 @@ mod test { use crate::test_helpers::contracts::{echo, hackatom, payout, reflect}; use crate::test_helpers::{CustomMsg, EmptyMsg}; use crate::transactions::StorageTransaction; - use crate::BankKeeper; use cosmwasm_std::{OverflowError, OverflowOperation, StdError}; use super::*; fn mock_app() -> App { - let env = mock_env(); - let api = MockApi::default(); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, MockStorage::new()) + AppBuilder::new().build() } fn custom_app() -> App { - let env = mock_env(); - let api = MockApi::default(); - let bank = BankKeeper::new(); - - App::new(api, env.block, bank, MockStorage::new()) + AppBuilder::new().build() } fn get_balance(app: &App, addr: &Addr) -> Vec diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index ff30be1e3..23f6e30f9 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -15,7 +15,7 @@ mod test_helpers; mod transactions; mod wasm; -pub use crate::app::{next_block, App, Router}; +pub use crate::app::{next_block, App, AppBuilder, Router}; pub use crate::bank::{Bank, BankKeeper}; pub use crate::contracts::{Contract, ContractWrapper}; pub use crate::executor::{AppResponse, Executor}; diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index b8181e67c..9390e902f 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -862,7 +862,10 @@ mod test { } fn mock_router() -> Router { - Router::new(BankKeeper {}) + Router { + wasm: Box::new(WasmKeeper::new()), + bank: Box::new(BankKeeper::new()), + } } #[test] From f4ef0b1ab80a4d8fa0c22a43cdb7f81251f49a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 1 Sep 2021 15:43:16 +0200 Subject: [PATCH 2/5] Mocking custom messages handler in multitestg --- packages/multi-test/src/app.rs | 108 +++++++++++++--------- packages/multi-test/src/custom_handler.rs | 60 ++++++++++++ packages/multi-test/src/lib.rs | 2 + packages/multi-test/src/wasm.rs | 92 +++++++++--------- 4 files changed, 176 insertions(+), 86 deletions(-) create mode 100644 packages/multi-test/src/custom_handler.rs diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 3bd9aabca..ca039b316 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -2,18 +2,21 @@ use std::fmt::{self, Debug}; use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; use cosmwasm_std::{ - from_slice, to_vec, Addr, Api, Binary, BlockInfo, Coin, ContractResult, CosmosMsg, Empty, - Querier, QuerierResult, QuerierWrapper, QueryRequest, Storage, SystemError, SystemResult, + from_slice, to_vec, Addr, Api, Binary, BlockInfo, Coin, ContractResult, CosmosMsg, CustomQuery, + Empty, Querier, QuerierResult, QuerierWrapper, QueryRequest, Storage, SystemError, + SystemResult, }; use schemars::JsonSchema; +use serde::de::DeserializeOwned; use serde::Serialize; use crate::bank::Bank; use crate::contracts::Contract; +use crate::custom_handler::CustomHandler; use crate::executor::{AppResponse, Executor}; use crate::transactions::transactional; use crate::wasm::{ContractData, Wasm, WasmKeeper}; -use crate::BankKeeper; +use crate::{BankKeeper, MockSimpleCustomHandler}; use anyhow::Result as AnyResult; use derivative::Derivative; @@ -27,21 +30,26 @@ pub fn next_block(block: &mut BlockInfo) { /// Execution generally happens on the RouterCache, which then can be atomically committed or rolled back. /// We offer .execute() as a wrapper around cache, execute, commit/rollback process. /// -/// C is the custom message returned init, handle, sudo (Response). -/// All contracts must return Response or Response -pub struct App +/// ExecC is the custom message returned init, handle, sudo (Response). +/// All contracts must return Response or Response. +/// +/// Also `ExecC` is the custom message which is handled by custom message handler. +/// +/// `QueryC` is custom query message handled by custom message handler. +pub struct App where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, { - router: Router, + router: Router, api: Box, storage: Box, block: BlockInfo, } -impl Querier for App +impl Querier for App where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { self.router @@ -50,11 +58,12 @@ where } } -impl Executor for App +impl Executor for App where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { - fn execute(&mut self, sender: Addr, msg: CosmosMsg) -> AnyResult { + fn execute(&mut self, sender: Addr, msg: CosmosMsg) -> AnyResult { let mut all = self.execute_multi(sender, vec![msg])?; let res = all.pop().unwrap(); Ok(res) @@ -64,21 +73,23 @@ where /// Utility to build App in stages. If particular items wont be set, defaults would be used #[derive(Derivative)] #[derivative(Default(bound = "", new = "true"))] -pub struct AppBuilder { - wasm: Option>>, +pub struct AppBuilder { + wasm: Option>>, bank: Option>, api: Option>, storage: Option>, + custom: Option>>, block: Option, } -impl AppBuilder +impl AppBuilder where - C: Debug + PartialEq + Clone + JsonSchema + 'static, + ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned + 'static, { /// Overwrites default wasm executor. Panic if already set. #[track_caller] - pub fn with_wasm(mut self, wasm: impl Wasm + 'static) -> Self { + pub fn with_wasm(mut self, wasm: impl Wasm + 'static) -> Self { assert!(self.wasm.is_none(), "Wasm executor already overwritten"); self.wasm = Some(Box::new(wasm)); self @@ -122,14 +133,17 @@ where self } - pub fn build(self) -> App { + pub fn build(self) -> App { let wasm = self.wasm.unwrap_or_else(|| Box::new(WasmKeeper::new())); let bank = self.bank.unwrap_or_else(|| Box::new(BankKeeper::new())); let api = self.api.unwrap_or_else(|| Box::new(MockApi::default())); let storage = self.storage.unwrap_or_else(|| Box::new(MockStorage::new())); let block = self.block.unwrap_or_else(|| mock_env().block); + let custom = self + .custom + .unwrap_or_else(|| Box::new(MockSimpleCustomHandler::new())); - let router = Router { wasm, bank }; + let router = Router { wasm, bank, custom }; App { router, @@ -140,9 +154,10 @@ where } } -impl App +impl App where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { pub fn set_block(&mut self, block: BlockInfo) { self.block = block; @@ -170,7 +185,7 @@ where pub fn execute_multi( &mut self, sender: Addr, - msgs: Vec>, + msgs: Vec>, ) -> AnyResult> { // we need to do some caching of storage here, once in the entry point: // meaning, wrap current state, all writes go to a cache, only when execute @@ -199,7 +214,7 @@ where /// This registers contract code (like uploading wasm bytecode on a chain), /// so it can later be used to instantiate a contract. - pub fn store_code(&mut self, code: Box>) -> u64 { + pub fn store_code(&mut self, code: Box>) -> u64 { self.router.wasm.store_code(code) as u64 } @@ -228,21 +243,23 @@ where } } -pub struct Router { - pub(crate) wasm: Box>, +pub struct Router { + pub(crate) wasm: Box>, pub(crate) bank: Box, + pub(crate) custom: Box>, } -impl Router +impl Router where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { pub fn querier<'a>( &'a self, api: &'a dyn Api, storage: &'a dyn Storage, block_info: &'a BlockInfo, - ) -> RouterQuerier<'a, C> { + ) -> RouterQuerier<'a, ExecC, QueryC> { RouterQuerier { router: self, api, @@ -259,7 +276,7 @@ where api: &dyn Api, storage: &dyn Storage, block: &BlockInfo, - request: QueryRequest, + request: QueryRequest, ) -> AnyResult { match request { QueryRequest::Wasm(req) => { @@ -267,6 +284,7 @@ where .query(api, storage, &self.querier(api, storage, block), block, req) } QueryRequest::Bank(req) => self.bank.query(api, storage, req), + QueryRequest::Custom(req) => self.custom.query(api, storage, block, req), _ => unimplemented!(), } } @@ -277,31 +295,33 @@ where storage: &mut dyn Storage, block: &BlockInfo, sender: Addr, - msg: CosmosMsg, + msg: CosmosMsg, ) -> AnyResult { match msg { CosmosMsg::Wasm(msg) => self.wasm.execute(api, storage, &self, block, sender, msg), CosmosMsg::Bank(msg) => self.bank.execute(storage, sender, msg), + CosmosMsg::Custom(msg) => self.custom.execute(api, storage, block, sender, msg), _ => unimplemented!(), } } } -pub struct RouterQuerier<'a, C> +pub struct RouterQuerier<'a, ExecC, QueryC> where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, { - router: &'a Router, + router: &'a Router, api: &'a dyn Api, storage: &'a dyn Storage, block_info: &'a BlockInfo, } -impl<'a, C> RouterQuerier<'a, C> + +impl<'a, ExecC, QueryC> RouterQuerier<'a, ExecC, QueryC> where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, { pub fn new( - router: &'a Router, + router: &'a Router, api: &'a dyn Api, storage: &'a dyn Storage, block_info: &'a BlockInfo, @@ -315,13 +335,13 @@ where } } -impl<'a, C> Querier for RouterQuerier<'a, C> +impl<'a, ExecC, QueryC> Querier for RouterQuerier<'a, ExecC, QueryC> where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - // TODO: we need to make a new custom type for queries - let request: QueryRequest = match from_slice(bin_request) { + let request: QueryRequest = match from_slice(bin_request) { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { @@ -807,14 +827,14 @@ mod test { // TODO: check error? } - fn query_router( - router: &Router, + fn query_router( + router: &Router, api: &dyn Api, storage: &dyn Storage, rcpt: &Addr, ) -> Vec where - C: Clone + fmt::Debug + PartialEq + JsonSchema, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema, { let query = BankQuery::AllBalances { address: rcpt.into(), diff --git a/packages/multi-test/src/custom_handler.rs b/packages/multi-test/src/custom_handler.rs new file mode 100644 index 000000000..69d06d5c1 --- /dev/null +++ b/packages/multi-test/src/custom_handler.rs @@ -0,0 +1,60 @@ +use cosmwasm_std::{Addr, Api, Binary, BlockInfo, Empty, Storage}; +use mockall::automock; + +use anyhow::Result as AnyResult; + +use crate::AppResponse; + +/// Custom message handler trait. Implementator of this trait is mocking environment behaviour on +/// given custom message. +pub trait CustomHandler { + fn execute( + &self, + api: &dyn Api, + storage: &mut dyn Storage, + block: &BlockInfo, + sender: Addr, + msg: ExecC, + ) -> AnyResult; + + fn query( + &self, + api: &dyn Api, + storage: &dyn Storage, + block: &BlockInfo, + msg: QueryC, + ) -> AnyResult; +} + +/// Simplified version of `CustomHandler` having only arguments which are not app internals - they +/// are just discarded. Usefull for simpler mocking. +#[automock(type QueryResult = Binary;)] +pub trait SimpleCustomHandler { + type QueryResult; + + fn execute(&self, block: &BlockInfo, sender: Addr, msg: ExecC) -> AnyResult; + fn query(&self, block: &BlockInfo, msg: QueryC) -> AnyResult; +} + +impl> CustomHandler for T { + fn execute( + &self, + _: &dyn Api, + _: &mut dyn Storage, + block: &BlockInfo, + sender: Addr, + msg: ExecC, + ) -> AnyResult { + self.execute(block, sender, msg) + } + + fn query( + &self, + _: &dyn Api, + _: &dyn Storage, + block: &BlockInfo, + msg: QueryC, + ) -> AnyResult { + self.query(block, msg) + } +} diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 23f6e30f9..0742ac149 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -9,6 +9,7 @@ mod app; mod bank; mod contracts; +mod custom_handler; pub mod error; mod executor; mod test_helpers; @@ -18,5 +19,6 @@ mod wasm; pub use crate::app::{next_block, App, AppBuilder, Router}; pub use crate::bank::{Bank, BankKeeper}; pub use crate::contracts::{Contract, ContractWrapper}; +pub use crate::custom_handler::{CustomHandler, MockSimpleCustomHandler, SimpleCustomHandler}; pub use crate::executor::{AppResponse, Executor}; pub use crate::wasm::{parse_contract_addr, Wasm, WasmKeeper}; diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 9390e902f..c2b391803 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -3,13 +3,14 @@ use std::fmt; use std::ops::Deref; use cosmwasm_std::{ - Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, ContractResult, Deps, - DepsMut, Env, Event, MessageInfo, Order, Querier, QuerierWrapper, Reply, ReplyOn, Response, - Storage, SubMsg, SubMsgExecutionResponse, WasmMsg, WasmQuery, + Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin, ContractInfo, ContractResult, + CustomQuery, Deps, DepsMut, Empty, Env, Event, MessageInfo, Order, Querier, QuerierWrapper, + Reply, ReplyOn, Response, Storage, SubMsg, SubMsgExecutionResponse, WasmMsg, WasmQuery, }; use cosmwasm_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; use prost::Message; use schemars::JsonSchema; +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use cw_storage_plus::Map; @@ -45,9 +46,9 @@ pub struct ContractData { pub created: u64, } -pub trait Wasm +pub trait Wasm where - C: Clone + fmt::Debug + PartialEq + JsonSchema, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema, { /// Handles all WasmQuery requests fn query( @@ -64,14 +65,14 @@ where &self, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, sender: Addr, msg: WasmMsg, ) -> AnyResult; // Add a new contract. Must be done on the base object, when no contracts running - fn store_code(&mut self, code: Box>) -> usize; + fn store_code(&mut self, code: Box>) -> usize; // Helper for querying for specific contract data fn contract_data(&self, storage: &dyn Storage, address: &Addr) -> AnyResult; @@ -82,29 +83,33 @@ where api: &dyn Api, contract_addr: Addr, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, msg: Vec, ) -> AnyResult; } -pub struct WasmKeeper { +pub struct WasmKeeper { /// code is in-memory lookup that stands in for wasm code /// this can only be edited on the WasmRouter, and just read in caches - codes: HashMap>>, + codes: HashMap>>, + /// Just marker to make type elision fork when using it as `Wasm` trait + _q: std::marker::PhantomData, } -impl Default for WasmKeeper { +impl Default for WasmKeeper { fn default() -> Self { Self { codes: HashMap::default(), + _q: std::marker::PhantomData, } } } -impl Wasm for WasmKeeper +impl Wasm for WasmKeeper where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { fn query( &self, @@ -131,7 +136,7 @@ where &self, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, sender: Addr, msg: WasmMsg, @@ -143,7 +148,7 @@ where self.process_response(api, router, storage, block, resender, res, msgs) } - fn store_code(&mut self, code: Box>) -> usize { + fn store_code(&mut self, code: Box>) -> usize { let idx = self.codes.len() + 1; self.codes.insert(idx, code); idx @@ -158,7 +163,7 @@ where api: &dyn Api, contract: Addr, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, msg: Vec, ) -> AnyResult { @@ -170,9 +175,10 @@ where } } -impl WasmKeeper +impl WasmKeeper where - C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + 'static, + QueryC: CustomQuery + DeserializeOwned, { pub fn new() -> Self { Self::default() @@ -207,7 +213,7 @@ where &self, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, sender: T, recipient: String, @@ -230,11 +236,11 @@ where &self, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, sender: Addr, wasm_msg: WasmMsg, - ) -> AnyResult<(Addr, Response, Event)> { + ) -> AnyResult<(Addr, Response, Event)> { match wasm_msg { WasmMsg::Execute { contract_addr, @@ -368,11 +374,11 @@ where fn execute_submsg( &self, api: &dyn Api, - router: &Router, + router: &Router, storage: &mut dyn Storage, block: &BlockInfo, contract: Addr, - msg: SubMsg, + msg: SubMsg, ) -> AnyResult { let SubMsg { msg, id, reply_on, .. @@ -423,7 +429,7 @@ where fn _reply( &self, api: &dyn Api, - router: &Router, + router: &Router, storage: &mut dyn Storage, block: &BlockInfo, contract: Addr, @@ -449,8 +455,8 @@ where &self, contract: &Addr, custom_event: Event, // entry-point specific custom event added by x/wasm - response: Response, - ) -> (AppResponse, Vec>) { + response: Response, + ) -> (AppResponse, Vec>) { let Response { messages, attributes, @@ -492,12 +498,12 @@ where fn process_response( &self, api: &dyn Api, - router: &Router, + router: &Router, storage: &mut dyn Storage, block: &BlockInfo, contract: Addr, response: AppResponse, - messages: Vec>, + messages: Vec>, ) -> AnyResult { let AppResponse { mut events, data } = response; @@ -546,11 +552,11 @@ where api: &dyn Api, storage: &mut dyn Storage, address: Addr, - router: &Router, + router: &Router, block: &BlockInfo, info: MessageInfo, msg: Vec, - ) -> AnyResult> { + ) -> AnyResult> { Self::verify_response(self.with_storage( api, storage, @@ -566,11 +572,11 @@ where address: Addr, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, info: MessageInfo, msg: Vec, - ) -> AnyResult> { + ) -> AnyResult> { Self::verify_response(self.with_storage( api, storage, @@ -586,10 +592,10 @@ where address: Addr, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, reply: Reply, - ) -> AnyResult> { + ) -> AnyResult> { Self::verify_response(self.with_storage( api, storage, @@ -605,10 +611,10 @@ where address: Addr, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, msg: Vec, - ) -> AnyResult> { + ) -> AnyResult> { Self::verify_response(self.with_storage( api, storage, @@ -624,10 +630,10 @@ where address: Addr, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, msg: Vec, - ) -> AnyResult> { + ) -> AnyResult> { Self::verify_response(self.with_storage( api, storage, @@ -657,7 +663,7 @@ where action: F, ) -> AnyResult where - F: FnOnce(&Box>, Deps, Env) -> AnyResult, + F: FnOnce(&Box>, Deps, Env) -> AnyResult, { let contract = self.load_contract(storage, &address)?; let handler = self @@ -679,13 +685,13 @@ where &self, api: &dyn Api, storage: &mut dyn Storage, - router: &Router, + router: &Router, block: &BlockInfo, address: Addr, action: F, ) -> AnyResult where - F: FnOnce(&Box>, DepsMut, Env) -> AnyResult, + F: FnOnce(&Box>, DepsMut, Env) -> AnyResult, { let contract = self.load_contract(storage, &address)?; let handler = self @@ -848,6 +854,7 @@ pub fn parse_contract_addr(data: &Option) -> AnyResult { #[cfg(test)] mod test { + use crate::MockSimpleCustomHandler; use cosmwasm_std::testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}; use cosmwasm_std::{coin, from_slice, to_vec, BankMsg, Coin, CosmosMsg, Empty, StdError}; @@ -861,10 +868,11 @@ mod test { WasmKeeper::new() } - fn mock_router() -> Router { + fn mock_router() -> Router { Router { wasm: Box::new(WasmKeeper::new()), bank: Box::new(BankKeeper::new()), + custom: Box::new(MockSimpleCustomHandler::new()), } } From c1ee67b4aeb1aaa986618af53ad40509a0e0e6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Wed, 1 Sep 2021 18:12:57 +0200 Subject: [PATCH 3/5] Test for handling custom execution messages --- packages/multi-test/src/app.rs | 72 +++++++++++++++++-- .../src/test_helpers/contracts/echo.rs | 47 +++++++----- 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index ca039b316..1c2f964e2 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -122,6 +122,14 @@ where self } + /// Overwrites default custom messages handler + #[track_caller] + pub fn with_custom(mut self, custom: impl CustomHandler + '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 { @@ -1077,7 +1085,7 @@ mod test { .execute_contract( owner, contract, - &echo::Message { + &echo::Message:: { data: Some("Data".to_owned()), ..echo::Message::default() }, @@ -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:: { data: Some("my echo".into()), events: vec![Event::new("echo").add_attribute("called", "true")], ..echo::Message::default() @@ -1408,7 +1416,7 @@ mod test { .execute_contract( owner, contract, - &echo::Message { + &echo::Message:: { data: None, attributes: vec![ Attribute::new(" ", "value"), @@ -1438,7 +1446,7 @@ mod test { .execute_contract( owner, contract, - &echo::Message { + &echo::Message:: { data: None, attributes: vec![ Attribute::new("key", " "), @@ -1468,7 +1476,7 @@ mod test { .execute_contract( owner, contract, - &echo::Message { + &echo::Message:: { data: None, events: vec![Event::new("event") .add_attribute(" ", "value") @@ -1497,7 +1505,7 @@ mod test { .execute_contract( owner, contract, - &echo::Message { + &echo::Message:: { data: None, events: vec![Event::new("event") .add_attribute("key", " ") @@ -1526,7 +1534,7 @@ mod test { .execute_contract( owner, contract, - &echo::Message { + &echo::Message:: { data: None, events: vec![Event::new(" e "), Event::new("event")], ..echo::Message::default() @@ -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::::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, &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(); + } + } } diff --git a/packages/multi-test/src/test_helpers/contracts/echo.rs b/packages/multi-test/src/test_helpers/contracts/echo.rs index 8f2a33bca..21e08fc96 100644 --- a/packages/multi-test/src/test_helpers/contracts/echo.rs +++ b/packages/multi-test/src/test_helpers/contracts/echo.rs @@ -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 +where + ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, +{ pub data: Option, - pub sub_msg: Vec, + pub sub_msg: Vec>, pub attributes: Vec, pub events: Vec, } #[allow(clippy::unnecessary_wraps)] -fn instantiate( +fn instantiate( _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: EmptyMsg, -) -> Result { +) -> Result, StdError> +where + ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, +{ Ok(Response::default()) } #[allow(clippy::unnecessary_wraps)] -fn execute( +fn execute( _deps: DepsMut, _env: Env, _info: MessageInfo, - msg: Message, -) -> Result { + msg: Message, +) -> Result, StdError> +where + ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, +{ let mut resp = Response::new(); if let Some(data) = msg.data { @@ -55,7 +67,10 @@ fn query(_deps: Deps, _env: Env, msg: EmptyMsg) -> Result { } #[allow(clippy::unnecessary_wraps)] -fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { +fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result, StdError> +where + ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, +{ if let Reply { result: ContractResult::Ok(SubMsgExecutionResponse { @@ -71,16 +86,16 @@ fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { } pub fn contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query).with_reply(reply); + let contract = ContractWrapper::new(execute::, instantiate::, query) + .with_reply(reply::); Box::new(contract) } -#[allow(dead_code)] pub fn custom_contract() -> Box> 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::, instantiate::, query).with_reply(reply::); Box::new(contract) } From 1f82b41af802bfe95cd688610afd2dbab2524d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Tue, 7 Sep 2021 13:19:14 +0200 Subject: [PATCH 4/5] Getting rid of mockall in multitest --- Cargo.lock | 128 ---------------------- packages/multi-test/Cargo.toml | 1 - packages/multi-test/src/app.rs | 31 +++--- packages/multi-test/src/custom_handler.rs | 81 +++++++++++++- packages/multi-test/src/lib.rs | 4 +- packages/multi-test/src/wasm.rs | 4 +- 6 files changed, 92 insertions(+), 157 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 681d5fcb5..bccf218e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - [[package]] name = "anyhow" version = "1.0.43" @@ -265,7 +256,6 @@ dependencies = [ "cw0", "derivative", "itertools", - "mockall", "prost", "schemars", "serde", @@ -634,12 +624,6 @@ dependencies = [ "syn", ] -[[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - [[package]] name = "digest" version = "0.8.1" @@ -658,12 +642,6 @@ dependencies = [ "generic-array 0.14.4", ] -[[package]] -name = "downcast" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" - [[package]] name = "dyn-clone" version = "1.0.4" @@ -734,21 +712,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "float-cmp" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" -dependencies = [ - "num-traits", -] - -[[package]] -name = "fragile" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2" - [[package]] name = "generic-array" version = "0.12.4" @@ -874,12 +837,6 @@ dependencies = [ "sha2 0.9.6", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.101" @@ -902,39 +859,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mockall" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab571328afa78ae322493cacca3efac6a0f2e0a67305b4df31fd439ef129ac0" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "lazy_static", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e25b214433f669161f414959594216d8e6ba83b6679d3db96899c0b4639033" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - [[package]] name = "num-traits" version = "0.2.14" @@ -975,35 +899,6 @@ dependencies = [ "spki", ] -[[package]] -name = "predicates" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" -dependencies = [ - "difference", - "float-cmp", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates-core" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" - -[[package]] -name = "predicates-tree" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d" -dependencies = [ - "predicates-core", - "treeline", -] - [[package]] name = "proc-macro2" version = "1.0.29" @@ -1063,23 +958,6 @@ dependencies = [ "getrandom 0.2.3", ] -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - [[package]] name = "rust_decimal" version = "1.15.0" @@ -1265,12 +1143,6 @@ dependencies = [ "syn", ] -[[package]] -name = "treeline" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" - [[package]] name = "typenum" version = "1.13.0" diff --git a/packages/multi-test/Cargo.toml b/packages/multi-test/Cargo.toml index b8cd3e607..9f15844ee 100644 --- a/packages/multi-test/Cargo.toml +++ b/packages/multi-test/Cargo.toml @@ -27,5 +27,4 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } prost = "0.8.0" anyhow = "1" thiserror = "1" -mockall = "0.10" derivative = "2" diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 1c2f964e2..da1df8c03 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -16,7 +16,7 @@ use crate::custom_handler::CustomHandler; use crate::executor::{AppResponse, Executor}; use crate::transactions::transactional; use crate::wasm::{ContractData, Wasm, WasmKeeper}; -use crate::{BankKeeper, MockSimpleCustomHandler}; +use crate::{BankKeeper, PanickingCustomHandler}; use anyhow::Result as AnyResult; use derivative::Derivative; @@ -85,7 +85,7 @@ pub struct AppBuilder { impl AppBuilder where ExecC: Debug + PartialEq + Clone + JsonSchema + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, + QueryC: Debug + CustomQuery + DeserializeOwned + 'static, { /// Overwrites default wasm executor. Panic if already set. #[track_caller] @@ -149,7 +149,7 @@ where let block = self.block.unwrap_or_else(|| mock_env().block); let custom = self .custom - .unwrap_or_else(|| Box::new(MockSimpleCustomHandler::new())); + .unwrap_or_else(|| Box::new(PanickingCustomHandler)); let router = Router { wasm, bank, custom }; @@ -1549,7 +1549,7 @@ mod test { mod custom_messages { use super::*; - use mockall as ma; + use crate::custom_handler::CachingCustomHandler; #[test] fn triggering_custom_msg() { @@ -1557,20 +1557,8 @@ mod test { let sender = api.addr_validate("sender").unwrap(); let owner = api.addr_validate("owner").unwrap(); - let mut custom_handler = MockSimpleCustomHandler::::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 custom_handler = CachingCustomHandler::::new(); + let custom_handler_state = custom_handler.state(); let mut app = AppBuilder::new() .with_api(api) @@ -1594,6 +1582,13 @@ mod test { &[], ) .unwrap(); + + assert_eq!( + custom_handler_state.execs().to_owned(), + vec![CustomMsg::SetAge { age: 20 }] + ); + + assert!(custom_handler_state.queries().is_empty()); } } } diff --git a/packages/multi-test/src/custom_handler.rs b/packages/multi-test/src/custom_handler.rs index 69d06d5c1..8fbd311f8 100644 --- a/packages/multi-test/src/custom_handler.rs +++ b/packages/multi-test/src/custom_handler.rs @@ -1,11 +1,14 @@ use cosmwasm_std::{Addr, Api, Binary, BlockInfo, Empty, Storage}; -use mockall::automock; use anyhow::Result as AnyResult; +use derivative::Derivative; +use std::cell::{Ref, RefCell}; +use std::ops::Deref; +use std::rc::Rc; use crate::AppResponse; -/// Custom message handler trait. Implementator of this trait is mocking environment behaviour on +/// Custom message handler trait. Implementor of this trait is mocking environment behavior on /// given custom message. pub trait CustomHandler { fn execute( @@ -27,11 +30,8 @@ pub trait CustomHandler { } /// Simplified version of `CustomHandler` having only arguments which are not app internals - they -/// are just discarded. Usefull for simpler mocking. -#[automock(type QueryResult = Binary;)] +/// are just discarded. Useful for simpler mocking. pub trait SimpleCustomHandler { - type QueryResult; - fn execute(&self, block: &BlockInfo, sender: Addr, msg: ExecC) -> AnyResult; fn query(&self, block: &BlockInfo, msg: QueryC) -> AnyResult; } @@ -58,3 +58,72 @@ impl> CustomHandler SimpleCustomHandler for PanickingCustomHandler +where + ExecC: std::fmt::Debug, + QueryC: std::fmt::Debug, +{ + fn execute(&self, _block: &BlockInfo, sender: Addr, msg: ExecC) -> AnyResult { + panic!("Unexpected custom exec msg {:?} from {:?}", msg, sender) + } + + fn query(&self, _block: &BlockInfo, msg: QueryC) -> AnyResult { + panic!("Unexpected custom query {:?}", msg) + } +} + +/// Internal state of `CachingCustomHandler` wrapping internal mutability so it is not exposed to +/// user. Those have to be shared internal state, as after mock is passed to app it is not +/// possible to access mock internals which are not exposed by API. +#[derive(Derivative)] +#[derivative(Default(bound = "", new = "true"), Clone(bound = ""))] +pub struct CachingCustomHandlerState { + execs: Rc>>, + queries: Rc>>, +} + +impl CachingCustomHandlerState { + pub fn execs(&self) -> impl Deref + '_ { + Ref::map(self.execs.borrow(), Vec::as_slice) + } + + pub fn queries(&self) -> impl Deref + '_ { + Ref::map(self.queries.borrow(), Vec::as_slice) + } + + pub fn reset(&self) { + self.execs.borrow_mut().clear(); + self.queries.borrow_mut().clear(); + } +} + +/// Custom handler storing all the messages it received, so they can be later verified. State is +/// thin shared state, so it can be hold after mock is passed to App to read state. +#[derive(Clone, Derivative)] +#[derivative(Default(bound = "", new = "true"))] +pub struct CachingCustomHandler { + state: CachingCustomHandlerState, +} + +impl CachingCustomHandler { + pub fn state(&self) -> CachingCustomHandlerState { + self.state.clone() + } +} + +impl SimpleCustomHandler for CachingCustomHandler { + fn execute(&self, _block: &BlockInfo, _sender: Addr, msg: ExecC) -> AnyResult { + self.state.execs.borrow_mut().push(msg); + Ok(AppResponse::default()) + } + + fn query(&self, _block: &BlockInfo, msg: QueryC) -> AnyResult { + self.state.queries.borrow_mut().push(msg); + Ok(Binary::default()) + } +} diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 0742ac149..343fce803 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -9,7 +9,7 @@ mod app; mod bank; mod contracts; -mod custom_handler; +pub mod custom_handler; pub mod error; mod executor; mod test_helpers; @@ -19,6 +19,6 @@ mod wasm; pub use crate::app::{next_block, App, AppBuilder, Router}; pub use crate::bank::{Bank, BankKeeper}; pub use crate::contracts::{Contract, ContractWrapper}; -pub use crate::custom_handler::{CustomHandler, MockSimpleCustomHandler, SimpleCustomHandler}; +pub use crate::custom_handler::{CustomHandler, PanickingCustomHandler, SimpleCustomHandler}; pub use crate::executor::{AppResponse, Executor}; pub use crate::wasm::{parse_contract_addr, Wasm, WasmKeeper}; diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index c2b391803..365ef6fe3 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -854,7 +854,7 @@ pub fn parse_contract_addr(data: &Option) -> AnyResult { #[cfg(test)] mod test { - use crate::MockSimpleCustomHandler; + use crate::PanickingCustomHandler; use cosmwasm_std::testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}; use cosmwasm_std::{coin, from_slice, to_vec, BankMsg, Coin, CosmosMsg, Empty, StdError}; @@ -872,7 +872,7 @@ mod test { Router { wasm: Box::new(WasmKeeper::new()), bank: Box::new(BankKeeper::new()), - custom: Box::new(MockSimpleCustomHandler::new()), + custom: Box::new(PanickingCustomHandler), } } From a3e574b56fef39f62de07a25e47bf3ab96ab3e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Tue, 7 Sep 2021 15:16:41 +0200 Subject: [PATCH 5/5] Getting rid of SimpleCustomHandler --- packages/multi-test/src/app.rs | 4 +- packages/multi-test/src/custom_handler.rs | 66 +++++++++++------------ packages/multi-test/src/lib.rs | 2 +- packages/multi-test/src/wasm.rs | 2 +- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index da1df8c03..8d915350a 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -12,11 +12,11 @@ use serde::Serialize; use crate::bank::Bank; use crate::contracts::Contract; -use crate::custom_handler::CustomHandler; +use crate::custom_handler::{CustomHandler, PanickingCustomHandler}; use crate::executor::{AppResponse, Executor}; use crate::transactions::transactional; use crate::wasm::{ContractData, Wasm, WasmKeeper}; -use crate::{BankKeeper, PanickingCustomHandler}; +use crate::BankKeeper; use anyhow::Result as AnyResult; use derivative::Derivative; diff --git a/packages/multi-test/src/custom_handler.rs b/packages/multi-test/src/custom_handler.rs index 8fbd311f8..f0eb399e3 100644 --- a/packages/multi-test/src/custom_handler.rs +++ b/packages/multi-test/src/custom_handler.rs @@ -29,50 +29,33 @@ pub trait CustomHandler { ) -> AnyResult; } -/// Simplified version of `CustomHandler` having only arguments which are not app internals - they -/// are just discarded. Useful for simpler mocking. -pub trait SimpleCustomHandler { - fn execute(&self, block: &BlockInfo, sender: Addr, msg: ExecC) -> AnyResult; - fn query(&self, block: &BlockInfo, msg: QueryC) -> AnyResult; -} +/// Custom handler implementation panicking on each call. Assuming, that unless specific behavior +/// is implemented, custom messages should not be send. +pub(crate) struct PanickingCustomHandler; -impl> CustomHandler for T { +impl CustomHandler for PanickingCustomHandler +where + ExecC: std::fmt::Debug, + QueryC: std::fmt::Debug, +{ fn execute( &self, - _: &dyn Api, - _: &mut dyn Storage, - block: &BlockInfo, + _api: &dyn Api, + _storage: &mut dyn Storage, + _block: &BlockInfo, sender: Addr, msg: ExecC, ) -> AnyResult { - self.execute(block, sender, msg) + panic!("Unexpected custom exec msg {:?} from {:?}", msg, sender) } fn query( &self, - _: &dyn Api, - _: &dyn Storage, - block: &BlockInfo, + _api: &dyn Api, + _storage: &dyn Storage, + _block: &BlockInfo, msg: QueryC, ) -> AnyResult { - self.query(block, msg) - } -} - -/// Custom handler implementation panicking on each call. Assuming, that unless specific behavior -/// is implemented, custom messages should not be send. -pub struct PanickingCustomHandler; - -impl SimpleCustomHandler for PanickingCustomHandler -where - ExecC: std::fmt::Debug, - QueryC: std::fmt::Debug, -{ - fn execute(&self, _block: &BlockInfo, sender: Addr, msg: ExecC) -> AnyResult { - panic!("Unexpected custom exec msg {:?} from {:?}", msg, sender) - } - - fn query(&self, _block: &BlockInfo, msg: QueryC) -> AnyResult { panic!("Unexpected custom query {:?}", msg) } } @@ -116,13 +99,26 @@ impl CachingCustomHandler { } } -impl SimpleCustomHandler for CachingCustomHandler { - fn execute(&self, _block: &BlockInfo, _sender: Addr, msg: ExecC) -> AnyResult { +impl CustomHandler for CachingCustomHandler { + fn execute( + &self, + _api: &dyn Api, + _storage: &mut dyn Storage, + _block: &BlockInfo, + _sender: Addr, + msg: ExecC, + ) -> AnyResult { self.state.execs.borrow_mut().push(msg); Ok(AppResponse::default()) } - fn query(&self, _block: &BlockInfo, msg: QueryC) -> AnyResult { + fn query( + &self, + _api: &dyn Api, + _storage: &dyn Storage, + _block: &BlockInfo, + msg: QueryC, + ) -> AnyResult { self.state.queries.borrow_mut().push(msg); Ok(Binary::default()) } diff --git a/packages/multi-test/src/lib.rs b/packages/multi-test/src/lib.rs index 343fce803..b3d83e37e 100644 --- a/packages/multi-test/src/lib.rs +++ b/packages/multi-test/src/lib.rs @@ -19,6 +19,6 @@ mod wasm; pub use crate::app::{next_block, App, AppBuilder, Router}; pub use crate::bank::{Bank, BankKeeper}; pub use crate::contracts::{Contract, ContractWrapper}; -pub use crate::custom_handler::{CustomHandler, PanickingCustomHandler, SimpleCustomHandler}; +pub use crate::custom_handler::CustomHandler; pub use crate::executor::{AppResponse, Executor}; pub use crate::wasm::{parse_contract_addr, Wasm, WasmKeeper}; diff --git a/packages/multi-test/src/wasm.rs b/packages/multi-test/src/wasm.rs index 365ef6fe3..66f3893ae 100644 --- a/packages/multi-test/src/wasm.rs +++ b/packages/multi-test/src/wasm.rs @@ -854,7 +854,7 @@ pub fn parse_contract_addr(data: &Option) -> AnyResult { #[cfg(test)] mod test { - use crate::PanickingCustomHandler; + use crate::custom_handler::PanickingCustomHandler; use cosmwasm_std::testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}; use cosmwasm_std::{coin, from_slice, to_vec, BankMsg, Coin, CosmosMsg, Empty, StdError};