-
Notifications
You must be signed in to change notification settings - Fork 54
/
lib.rs
164 lines (142 loc) · 5.46 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#![cfg_attr(not(feature = "std"), no_std, no_main)]
#[ink::contract]
pub mod flipper {
#[ink(storage)]
pub struct Flipper {
value: bool,
}
impl Flipper {
/// Creates a new flipper smart contract initialized with the given value.
#[ink(constructor)]
pub fn new(init_value: bool) -> Self {
Self { value: init_value }
}
/// Creates a new flipper smart contract initialized to `false`.
#[ink(constructor)]
pub fn new_default() -> Self {
Self::new(Default::default())
}
/// Flips the current value of the Flipper's boolean.
#[ink(message)]
pub fn flip(&mut self) {
self.value = !self.value;
}
/// Returns the current value of the Flipper's boolean.
#[ink(message)]
pub fn get(&self) -> bool {
self.value
}
}
#[cfg(test)]
mod tests {
use super::*;
#[ink::test]
fn default_works() {
let flipper = Flipper::new_default();
assert!(!flipper.get());
}
#[ink::test]
fn it_works() {
let mut flipper = Flipper::new(false);
assert!(!flipper.get());
flipper.flip();
assert!(flipper.get());
}
}
#[cfg(all(test, feature = "e2e-tests"))]
mod e2e_tests {
use super::*;
use ink_e2e::ContractsBackend;
type E2EResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[ink_e2e::test]
async fn it_works<Client: E2EBackend>(mut client: Client) -> E2EResult<()> {
// given
let mut constructor = FlipperRef::new(false);
let contract = client
.instantiate("flipper", &ink_e2e::alice(), &mut constructor)
.submit()
.await
.expect("instantiate failed");
let mut call_builder = contract.call_builder::<Flipper>();
let get = call_builder.get();
let get_res = client.call(&ink_e2e::bob(), &get).dry_run().await?;
assert!(matches!(get_res.return_value(), false));
// when
let flip = call_builder.flip();
let _flip_res = client
.call(&ink_e2e::bob(), &flip)
.submit()
.await
.expect("flip failed");
// then
let get = call_builder.get();
let get_res = client.call(&ink_e2e::bob(), &get).dry_run().await?;
assert!(matches!(get_res.return_value(), true));
Ok(())
}
#[ink_e2e::test]
async fn default_works<Client: E2EBackend>(mut client: Client) -> E2EResult<()> {
// given
let mut constructor = FlipperRef::new_default();
// when
let contract = client
.instantiate("flipper", &ink_e2e::bob(), &mut constructor)
.submit()
.await
.expect("instantiate failed");
let call_builder = contract.call_builder::<Flipper>();
// then
let get = call_builder.get();
let get_res = client.call(&ink_e2e::bob(), &get).dry_run().await?;
assert!(matches!(get_res.return_value(), false));
Ok(())
}
/// This test illustrates how to test an existing on-chain contract.
///
/// You can utilize this to e.g. create a snapshot of a production chain
/// and run the E2E tests against a deployed contract there.
/// This process is explained [here](https://use.ink/5.x/basics/contract-testing/chain-snapshot).
///
/// Before executing the test:
/// * Make sure you have a node running in the background,
/// * Supply the environment variable `CONTRACT_HEX` that points to a deployed
/// flipper contract. You can take the SS58 address which `cargo contract
/// instantiate` gives you and convert it to hex using `subkey inspect
/// <SS58>`.
///
/// The test is then run like this:
///
/// ```
/// # The env variable needs to be set, otherwise `ink_e2e` will spawn a new
/// # node process for each test.
/// $ export CONTRACTS_NODE_URL=ws://127.0.0.1:9944
///
/// $ export CONTRACT_HEX=0x2c75f0aa09dbfbfd49e6286a0f2edd3b4913f04a58b13391c79e96782f5713e3
/// $ cargo test --features e2e-tests e2e_test_deployed_contract -- --ignored
/// ```
///
/// # Developer Note
///
/// The test is marked as ignored, as it has the above pre-conditions to succeed.
#[ink_e2e::test]
#[ignore]
async fn e2e_test_deployed_contract<Client: E2EBackend>(
mut client: Client,
) -> E2EResult<()> {
// given
let addr = std::env::var("CONTRACT_ADDR_HEX")
.unwrap()
.replace("0x", "");
let acc_id = hex::decode(addr).unwrap();
let acc_id = AccountId::try_from(&acc_id[..]).unwrap();
// when
// Invoke `Flipper::get()` from Bob's account
let call_builder = ink_e2e::create_call_builder::<Flipper>(acc_id);
let get = call_builder.get();
let get_res = client.call(&ink_e2e::bob(), &get).dry_run().await?;
// then
assert!(matches!(get_res.return_value(), true));
Ok(())
}
}
}