Skip to content

Commit 8f62721

Browse files
clean up the tests
1 parent 02972ce commit 8f62721

File tree

7 files changed

+75
-109
lines changed

7 files changed

+75
-109
lines changed

Cargo.Bazel.lock

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"checksum": "fd7fe8ea967274d2f13641d3bbfad70cb48ad849c110fd74440b62e666029e40",
2+
"checksum": "ad9783ce8e08ab1bcbcc853142e7d93648924113cbe1f4dffb641461593f5afe",
33
"crates": {
44
"addr2line 0.20.0": {
55
"name": "addr2line",
@@ -5060,6 +5060,10 @@
50605060
{
50615061
"id": "serde 1.0.171",
50625062
"target": "serde"
5063+
},
5064+
{
5065+
"id": "thiserror 1.0.44",
5066+
"target": "thiserror"
50635067
}
50645068
],
50655069
"selects": {}

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ rand = "0.8.5"
2121
ring = "0.16.20"
2222
serde = "=1.0.171"
2323
tempfile = "3.3"
24+
thiserror = "1"
2425
tokio = { version = "1.20.1", features = ["macros"] }
2526

2627
[workspace.package]
2728
authors = ["DFINITY Stiftung"]
2829
edition = "2018"
2930
repository = "https://github.com/dfinity/ICRC-1"
3031
rust-version = "1.31.0"
31-
license = "Apache-2.0"
32+
license = "Apache-2.0"

ref/ICRC1.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ actor class Ledger(init : { initial_mints : [{ account : { owner : Principal; su
142142
case (#Burn(args)) { total -= args.amount };
143143
case (#Mint(args)) { total += args.amount };
144144
case (#Transfer(_)) { total -= tx.fee };
145-
case (#Approve(_)) {total -= tx.fee};
145+
case (#Approve(_)) { total -= tx.fee };
146146
};
147147
};
148148
total;

test/env/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ path = "lib.rs"
1212

1313
[dependencies]
1414
anyhow = { workspace = true }
15+
async-trait = { workspace = true }
1516
candid = { workspace = true }
1617
serde = { workspace = true }
17-
async-trait = { workspace = true }
18+
thiserror = { workspace = true }

test/env/lib.rs

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use candid::utils::{ArgumentDecoder, ArgumentEncoder};
33
use candid::Principal;
44
use candid::{CandidType, Int, Nat};
55
use serde::Deserialize;
6-
use std::fmt;
6+
use thiserror::Error;
77

88
pub type Subaccount = [u8; 32];
99

@@ -36,58 +36,26 @@ pub enum Value {
3636
Int(Int),
3737
}
3838

39-
#[derive(CandidType, Deserialize, PartialEq, Eq, Debug, Clone)]
39+
#[derive(CandidType, Deserialize, PartialEq, Eq, Debug, Clone, Error)]
4040
pub enum TransferError {
41+
#[error("Invalid transfer fee, the ledger expected fee {expected_fee}")]
4142
BadFee { expected_fee: Nat },
43+
#[error("Invalid burn amount, the minimal burn amount is {min_burn_amount}")]
4244
BadBurn { min_burn_amount: Nat },
45+
#[error("The account owner doesn't have enough funds to for the transfer, balance: {balance}")]
4346
InsufficientFunds { balance: Nat },
47+
#[error("created_at_time is too far in the past")]
4448
TooOld,
49+
#[error("created_at_time is too far in the future, ledger time: {ledger_time}")]
4550
CreatedInFuture { ledger_time: u64 },
51+
#[error("the transfer is a duplicate of transaction {duplicate_of}")]
4652
Duplicate { duplicate_of: Nat },
53+
#[error("the ledger is temporarily unavailable")]
4754
TemporarilyUnavailable,
55+
#[error("generic error (code {error_code}): {message}")]
4856
GenericError { error_code: Nat, message: String },
4957
}
5058

51-
impl fmt::Display for TransferError {
52-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53-
match self {
54-
Self::BadFee { expected_fee } => write!(
55-
f,
56-
"Invalid transfer fee, the ledger expected fee {}",
57-
expected_fee
58-
),
59-
Self::BadBurn { min_burn_amount } => write!(
60-
f,
61-
"Invalid burn amount, the minimal burn amount is {}",
62-
min_burn_amount
63-
),
64-
Self::InsufficientFunds { balance } => write!(
65-
f,
66-
"The account owner doesn't have enough funds to for the transfer, balance: {}",
67-
balance
68-
),
69-
Self::TooOld => write!(f, "created_at_time is too far in the past"),
70-
Self::CreatedInFuture { ledger_time } => write!(
71-
f,
72-
"created_at_time is too far in the future, ledger time: {}",
73-
ledger_time
74-
),
75-
Self::Duplicate { duplicate_of } => write!(
76-
f,
77-
"the transfer is a duplicate of transaction {}",
78-
duplicate_of
79-
),
80-
Self::TemporarilyUnavailable => write!(f, "the ledger is temporarily unavailable"),
81-
Self::GenericError {
82-
error_code,
83-
message,
84-
} => write!(f, "generic error (code {}): {}", error_code, message),
85-
}
86-
}
87-
}
88-
89-
impl std::error::Error for TransferError {}
90-
9159
#[derive(CandidType, Debug, Clone)]
9260
pub struct Transfer {
9361
from_subaccount: Option<Subaccount>,
@@ -183,16 +151,25 @@ impl ApproveArgs {
183151
}
184152
}
185153

186-
#[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq)]
154+
#[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq, Error)]
187155
pub enum ApproveError {
156+
#[error("Invalid transfer fee, the ledger expected fee {expected_fee}")]
188157
BadFee { expected_fee: Nat },
158+
#[error("The account owner doesn't have enough funds to for the approval, balance: {balance}")]
189159
InsufficientFunds { balance: Nat },
160+
#[error("The allowance changed, current allowance: {current_allowance}")]
190161
AllowanceChanged { current_allowance: Nat },
162+
#[error("the approval expiration time is in the past, ledger time: {ledger_time}")]
191163
Expired { ledger_time: u64 },
164+
#[error("created_at_time is too far in the past")]
192165
TooOld,
166+
#[error("created_at_time is too far in the future, ledger time: {ledger_time}")]
193167
CreatedInFuture { ledger_time: u64 },
168+
#[error("the transfer is a duplicate of transaction {duplicate_of}")]
194169
Duplicate { duplicate_of: Nat },
170+
#[error("the ledger is temporarily unavailable")]
195171
TemporarilyUnavailable,
172+
#[error("generic error (code {error_code}): {message}")]
196173
GenericError { error_code: Nat, message: String },
197174
}
198175

@@ -245,16 +222,25 @@ impl TransferFromArgs {
245222
}
246223
}
247224

248-
#[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq)]
225+
#[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq, Error)]
249226
pub enum TransferFromError {
227+
#[error("Invalid transfer fee, the ledger expected fee {expected_fee}")]
250228
BadFee { expected_fee: Nat },
229+
#[error("Invalid burn amount, the minimal burn amount is {min_burn_amount}")]
251230
BadBurn { min_burn_amount: Nat },
231+
#[error("The account owner doesn't have enough funds to for the transfer, balance: {balance}")]
252232
InsufficientFunds { balance: Nat },
233+
#[error("The account owner doesn't have allowance for the transfer, allowance: {allowance}")]
253234
InsufficientAllowance { allowance: Nat },
235+
#[error("created_at_time is too far in the past")]
254236
TooOld,
237+
#[error("created_at_time is too far in the future, ledger time: {ledger_time}")]
255238
CreatedInFuture { ledger_time: u64 },
239+
#[error("the transfer is a duplicate of transaction {duplicate_of}")]
256240
Duplicate { duplicate_of: Nat },
241+
#[error("the ledger is temporarily unavailable")]
257242
TemporarilyUnavailable,
243+
#[error("generic error (code {error_code}): {message}")]
258244
GenericError { error_code: Nat, message: String },
259245
}
260246

@@ -296,10 +282,7 @@ pub trait LedgerEnv {
296282
}
297283

298284
pub mod icrc1 {
299-
use crate::{
300-
Account, Allowance, AllowanceArgs, ApproveArgs, ApproveError, LedgerEnv, SupportedStandard,
301-
Transfer, TransferError, TransferFromArgs, TransferFromError, Value,
302-
};
285+
use crate::{Account, LedgerEnv, SupportedStandard, Transfer, TransferError, Value};
303286
use candid::Nat;
304287

305288
pub async fn transfer(
@@ -354,6 +337,14 @@ pub mod icrc1 {
354337
pub async fn transfer_fee(ledger: &impl LedgerEnv) -> anyhow::Result<Nat> {
355338
ledger.query("icrc1_fee", ()).await.map(|(t,)| t)
356339
}
340+
}
341+
342+
pub mod icrc2 {
343+
use crate::{
344+
Allowance, AllowanceArgs, ApproveArgs, ApproveError, LedgerEnv, TransferFromArgs,
345+
TransferFromError,
346+
};
347+
use candid::Nat;
357348

358349
pub async fn approve(
359350
ledger: &impl LedgerEnv,

test/suite/lib.rs

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
use anyhow::{bail, Context};
22
use candid::Nat;
3-
use candid::Principal;
43
use futures::StreamExt;
5-
use icrc1_test_env::icrc1::allowance;
6-
use icrc1_test_env::icrc1::approve;
7-
use icrc1_test_env::icrc1::transfer_from;
84
use icrc1_test_env::icrc1::{
95
balance_of, metadata, minting_account, supported_standards, token_decimals, token_name,
106
token_symbol, transfer, transfer_fee,
117
};
8+
use icrc1_test_env::icrc2::{allowance, approve, transfer_from};
129
use icrc1_test_env::AllowanceArgs;
1310
use icrc1_test_env::ApproveArgs;
1411
use icrc1_test_env::TransferFromArgs;
@@ -78,64 +75,30 @@ async fn assert_balance(
7875
Ok(())
7976
}
8077

81-
async fn transfer_or_fail(ledger_env: &impl LedgerEnv, amount: Nat, receiver: Principal) -> Nat {
82-
transfer(ledger_env, Transfer::amount_to(amount.clone(), receiver))
83-
.await
84-
.with_context(|| format!("failed to transfer {} tokens to {}", amount, receiver))
85-
.unwrap()
86-
.unwrap()
87-
}
88-
89-
async fn approve_or_err(ledger_env: &impl LedgerEnv, args: ApproveArgs) -> anyhow::Result<()> {
90-
match approve(ledger_env, args.clone()).await? {
91-
Ok(_) => Ok(()),
92-
Err(err) => Err(anyhow::Error::msg(format!(
93-
"Expected approval of {:?}, spender {:?} to succeed but received {:?}.",
94-
args.amount, args.spender, err
95-
))),
96-
}
97-
}
98-
99-
async fn transfer_from_or_err(
100-
ledger_env: &impl LedgerEnv,
101-
args: TransferFromArgs,
102-
) -> anyhow::Result<()> {
103-
match transfer_from(ledger_env, args.clone()).await.unwrap(){
104-
Ok(_) => {
105-
Ok(())
106-
},
107-
Err(err) => {
108-
Err(anyhow::Error::msg(format!("Expected transfer from of {:?} from {:?},to {:?} with spender subaccount {:?} to succeed but received {:?}.",args.amount,args.from,args.to, args.spender_subaccount,err)))
109-
},
110-
}
111-
}
112-
11378
async fn assert_allowance(
11479
ledger_env: &impl LedgerEnv,
11580
from: Account,
11681
spender: Account,
11782
expected_allowance: Nat,
11883
) -> anyhow::Result<()> {
119-
match allowance(
84+
let allowance = allowance(
12085
ledger_env,
12186
AllowanceArgs {
12287
account: from.clone(),
12388
spender: spender.clone(),
12489
},
12590
)
126-
.await
127-
{
128-
Ok(allowance) => {
129-
if allowance.allowance != expected_allowance {
130-
return Err(anyhow::Error::msg(format!("Expected the allowance returned by the allowance endpoint to be the {:?}, received {:?}",expected_allowance,allowance.allowance)));
131-
}
132-
Ok(())
133-
}
134-
Err(err) => Err(anyhow::Error::msg(format!(
135-
"Expected allowance of {:?} from {:?}, spender {:?} to succeed but received {:?}.",
136-
expected_allowance, from, spender, err
137-
))),
91+
.await?;
92+
if allowance.allowance != expected_allowance {
93+
bail!(
94+
"Expected the {:?} -> {:?} allowance to be {}, got {}",
95+
from,
96+
spender,
97+
expected_allowance,
98+
allowance.allowance
99+
);
138100
}
101+
Ok(())
139102
}
140103

141104
async fn setup_test_account(
@@ -147,7 +110,7 @@ async fn setup_test_account(
147110
let receiver_env = ledger_env.fork();
148111
let receiver = receiver_env.principal();
149112
assert_balance(&receiver_env, receiver, 0).await?;
150-
let _tx = transfer_or_fail(ledger_env, amount.clone(), receiver).await;
113+
let _tx = transfer(ledger_env, Transfer::amount_to(amount.clone(), receiver)).await??;
151114
assert_balance(
152115
&receiver_env,
153116
Account {
@@ -170,7 +133,11 @@ pub async fn icrc1_test_transfer(ledger_env: impl LedgerEnv + LedgerEnv) -> Test
170133
let balance_p1 = balance_of(&p1_env, p1_env.principal()).await?;
171134
let balance_p2 = balance_of(&p2_env, p2_env.principal()).await?;
172135

173-
let _tx = transfer_or_fail(&p1_env, Nat::from(transfer_amount), p2_env.principal()).await;
136+
let _tx = transfer(
137+
&p1_env,
138+
Transfer::amount_to(transfer_amount, p2_env.principal()),
139+
)
140+
.await??;
174141

175142
assert_balance(
176143
&p2_env,
@@ -304,11 +271,11 @@ pub async fn icrc2_test_approve(ledger_env: impl LedgerEnv) -> anyhow::Result<Ou
304271
let p2_env = ledger_env.fork();
305272
let approve_amount = Nat::from(10_000);
306273

307-
approve_or_err(
274+
approve(
308275
&p1_env,
309276
ApproveArgs::approve_amount(approve_amount.clone(), p2_env.principal()),
310277
)
311-
.await?;
278+
.await??;
312279

313280
assert_balance(
314281
&ledger_env,
@@ -341,23 +308,24 @@ pub async fn icrc2_test_transfer_from(ledger_env: impl LedgerEnv) -> anyhow::Res
341308

342309
let approve_amount = Nat::from(50_000);
343310

344-
approve_or_err(
311+
approve(
345312
&p1_env,
346313
ApproveArgs::approve_amount(approve_amount.clone(), p2_env.principal()),
347314
)
348-
.await?;
315+
.await??;
349316

350317
// Transferred amount has to be smaller than the approved amount minus the fee for transfering tokens
351318
let transfer_amount = approve_amount - fee.clone() - Nat::from(1);
352-
transfer_from_or_err(
319+
transfer_from(
353320
&p2_env,
354321
TransferFromArgs::transfer_from(
355322
transfer_amount.clone(),
356323
p3_env.principal(),
357324
p1_env.principal(),
358325
),
359326
)
360-
.await?;
327+
.await??;
328+
361329
assert_balance(
362330
&ledger_env,
363331
p1_env.principal(),

0 commit comments

Comments
 (0)