Skip to content

Commit

Permalink
unified syntax - ReturnsResultOrError + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-marinica committed Oct 8, 2024
1 parent 06fc066 commit 07207f6
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
"gasLimit": "70,000,000"
},
"expect": {
"out": [],
"out": [
"str:init-result"
],
"status": "0"
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
"gasPrice": "0"
},
"expect": {
"out": [],
"out": [
"str:init-result"
],
"status": "",
"logs": "*",
"gas": "*",
Expand Down
4 changes: 3 additions & 1 deletion contracts/feature-tests/scenario-tester/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ pub trait ScenarioTester {
#[storage_mapper("sum")]
fn sum(&self) -> SingleValueMapper<BigUint>;

/// Return value for testing reasons.
#[init]
fn init(&self, initial_value: BigUint) {
fn init(&self, initial_value: BigUint) -> &'static str {
self.sum().set(initial_value);
"init-result"
}

#[upgrade]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ where
From: TxFrom<Env>,
Gas: TxGas<Env>,
{
/// Return value for testing reasons.
pub fn init<
Arg0: ProxyArg<BigUint<Env::Api>>,
>(
self,
initial_value: Arg0,
) -> TxTypedDeploy<Env, From, NotPayable, Gas, ()> {
) -> TxTypedDeploy<Env, From, NotPayable, Gas, &'static str> {
self.wrapped_tx
.payment(NotPayable)
.raw_deploy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn scenario_tester_blackbox_raw() {
.from("address:owner")
.code(scenario_tester_code)
.argument("5")
.expect(TxExpect::ok().no_result()),
.expect(TxExpect::ok().result("str:init-result")),
)
.sc_query(
ScQueryStep::new()
Expand Down
38 changes: 38 additions & 0 deletions contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,41 @@ fn st_blackbox_tx_hash() {

assert_eq!(tx_hash.as_array(), &[22u8; 32]);
}

#[test]
fn st_blackbox_returns_result_or_error() {
let mut world = world();

world
.account(OWNER_ADDRESS)
.nonce(1)
.balance(100)
.account(OTHER_ADDRESS)
.nonce(2)
.balance(300)
.esdt_balance(TOKEN_ID, 500)
.commit();

let (result, check_tx_hash) = world
.tx()
.from(OWNER_ADDRESS)
.typed(scenario_tester_proxy::ScenarioTesterProxy)
.init(5u32)
.code(CODE_PATH)
.new_address(ST_ADDRESS)
.tx_hash([33u8; 32])
.returns(
ReturnsResultOrError::new()
.returns(ReturnsNewAddress)
.returns(ReturnsResultAs::<String>::new())
.returns(ReturnsTxHash),
)
.returns(ReturnsTxHash)
.run();

assert_eq!(check_tx_hash.as_array(), &[33u8; 32]);
let (new_address, out_value, also_check_tx_hash) = result.unwrap();
assert_eq!(new_address, ST_ADDRESS.to_address());
assert_eq!(out_value, "init-result");
assert_eq!(also_check_tx_hash.as_array(), &[33u8; 32]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn st_blackbox_upgrade() {
.code(&st_code)
.argument("5")
.gas_limit("5,000,000")
.expect(TxExpect::ok().no_result()),
.expect(TxExpect::ok().result("str:init-result")),
)
.sc_call(
ScCallStep::new()
Expand Down
2 changes: 2 additions & 0 deletions framework/scenario/src/facade/result_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod returns_logs;
mod returns_message;
mod returns_new_bech32_address;
mod returns_new_token_identifier;
mod returns_result_or_err;
mod returns_status;
mod returns_tx_hash;
mod with_tx_raw_response;
Expand All @@ -18,6 +19,7 @@ pub use returns_logs::ReturnsLogs;
pub use returns_message::ReturnsMessage;
pub use returns_new_bech32_address::ReturnsNewBech32Address;
pub use returns_new_token_identifier::ReturnsNewTokenIdentifier;
pub use returns_result_or_err::ReturnsResultOrError;
pub use returns_status::ReturnsStatus;
pub use returns_tx_hash::ReturnsTxHash;
pub use with_tx_raw_response::WithRawTxResponse;
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use std::marker::PhantomData;

use multiversx_sc::{
tuple_util::NestedTupleFlatten,
types::{
OriginalResultMarker, RHList, RHListAppendRet, RHListExec, RHListItem, RHListItemExec,
TxEnv,
},
};

use crate::scenario_model::{TxResponse, TxResponseStatus};

/// Indicates that a `Result` will be returned, either with the handled result,
/// according to the inner result handlers, or with an error in case of a failed transaction.
pub struct ReturnsResultOrError<Env, Original, Ok>
where
Env: TxEnv,
Ok: RHList<Env>,
{
_phantom_env: PhantomData<Env>,
_phantom_original: PhantomData<Original>,
pub ok_t: Ok,
}

impl<Env, Original> Default for ReturnsResultOrError<Env, Original, OriginalResultMarker<Original>>
where
Env: TxEnv,
{
fn default() -> Self {
ReturnsResultOrError {
_phantom_env: PhantomData,
_phantom_original: PhantomData,
ok_t: OriginalResultMarker::new(),
}
}
}

impl<Env, Original> ReturnsResultOrError<Env, Original, OriginalResultMarker<Original>>
where
Env: TxEnv,
{
pub fn new() -> Self {
ReturnsResultOrError::default()
}
}

impl<Env, Original, Ok> ReturnsResultOrError<Env, Original, Ok>
where
Env: TxEnv,
Ok: RHListExec<TxResponse, Env>,
{
pub fn returns<RH>(self, item: RH) -> ReturnsResultOrError<Env, Original, Ok::RetOutput>
where
RH: RHListItem<Env, Ok::OriginalResult>,
Ok: RHListAppendRet<Env, RH>,
{
ReturnsResultOrError {
_phantom_env: PhantomData,
_phantom_original: PhantomData,
ok_t: self.ok_t.append_ret(item),
}
}
}

impl<Env, Original, Ok> RHListItem<Env, Original> for ReturnsResultOrError<Env, Original, Ok>
where
Env: TxEnv,
Ok: RHListExec<TxResponse, Env>,
Ok::ListReturns: NestedTupleFlatten,
{
type Returns = Result<<Ok::ListReturns as NestedTupleFlatten>::Unpacked, TxResponseStatus>;
}

impl<Env, Original, Ok> RHListItemExec<TxResponse, Env, Original>
for ReturnsResultOrError<Env, Original, Ok>
where
Env: TxEnv,
Ok: RHListExec<TxResponse, Env>,
Ok::ListReturns: NestedTupleFlatten,
{
fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns {
if raw_result.tx_error.is_success() {
let tuple_result = self.ok_t.list_process_result(raw_result);
Ok(tuple_result.flatten_unpack())
} else {
Err(raw_result.tx_error.clone())
}
}
}
21 changes: 0 additions & 21 deletions framework/scenario/src/scenario/model/transaction/tx_error.rs

This file was deleted.

0 comments on commit 07207f6

Please sign in to comment.