Test
Continuing on from where we left off in the last test we will now read and increment the counter.
Continue adding to the bottom of the same test.
`tests/counter.rs` code from previous section.
#![allow(unused)] fn main() { use essential_app_utils::{compile::compile_pint_project, local_server::setup_server}; use counter_app::App; use essential_types::{PredicateAddress, Word}; #[tokio::test] async fn test_counter() { let (addr, _server) = setup_server().await.unwrap(); let counter = compile_pint_project( concat!(env!("CARGO_MANIFEST_DIR"), "/../contract").into(), ) .await .unwrap(); let contract_address = essential_hash::contract_addr::from_contract(&counter); let predicate_address = essential_hash::content_addr(&counter.predicates[0]); let predicate_address = PredicateAddress { contract: contract_address, predicate: predicate_address, }; let mut wallet = essential_wallet::Wallet::temp().unwrap(); wallet .new_key_pair("alice", essential_wallet::Scheme::Secp256k1) .unwrap(); essential_deploy_contract::sign_and_deploy(addr.clone(), "alice", &mut wallet, counter) .await .unwrap(); // Add new code here. } }
Create a new App
we defined earlier in the lib.rs
.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... let app = App::new(addr, predicate_address).unwrap(); } }
Read the current count value and assert that it's 0
.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... assert_eq!(app.read_count().await.unwrap(), 0); } }
Increment the counter. Remember this creates and submits the solution.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... app.increment().await.unwrap(); } }
Stepping out of the test function for a second. We want to check for new state however the state only changes once a solution has been included in a block.
Add this wait_for_change
function that will check if the state is the expected value. If it is not then it will wait one second and check again.
#![allow(unused)] fn main() { async fn wait_for_change(app: &App, expected: Word) { loop { if app.read_count().await.unwrap() == expected { break; } tokio::time::sleep(std::time::Duration::from_secs(1)).await; } } }
Back in the test function now let's use the wait_for_change
we just wrote to wait for the count to reach 1
.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... wait_for_change(&app, 1).await; } }
Exciting the your solution has successfully satisfied the constraints and the state has been mutated.
Now just to make sure let's increment it again.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... app.increment().await.unwrap(); } }
And wait for the state to change.
#![allow(unused)] fn main() { #[tokio::test] async fn test_counter() { // ... wait_for_change(&app, 2).await; } }
The state has changed again to 2
!
Check your `tests/counter.rs` matches this.
#![allow(unused)] fn main() { use essential_app_utils::{compile::compile_pint_project, local_server::setup_server}; use counter_app::App; use essential_types::{PredicateAddress, Word}; #[tokio::test] async fn test_counter() { let (addr, _server) = setup_server().await.unwrap(); let counter = compile_pint_project( concat!(env!("CARGO_MANIFEST_DIR"), "/../contract").into(), ) .await .unwrap(); let contract_address = essential_hash::contract_addr::from_contract(&counter); let predicate_address = essential_hash::content_addr(&counter.predicates[0]); let predicate_address = PredicateAddress { contract: contract_address, predicate: predicate_address, }; let mut wallet = essential_wallet::Wallet::temp().unwrap(); wallet .new_key_pair("alice", essential_wallet::Scheme::Secp256k1) .unwrap(); essential_deploy_contract::sign_and_deploy(addr.clone(), "alice", &mut wallet, counter) .await .unwrap(); let app = App::new(addr, predicate_address).unwrap(); assert_eq!(app.read_count().await.unwrap(), 0); app.increment().await.unwrap(); wait_for_change(&app, 1).await; app.increment().await.unwrap(); wait_for_change(&app, 2).await; } async fn wait_for_change(app: &App, expected: Word) { loop { if app.read_count().await.unwrap() == expected { break; } tokio::time::sleep(std::time::Duration::from_secs(1)).await; } } }
Run the test
Run the test and check it all works.
cargo test
Congratulations on building your first essential
application.
It may be a very simple example but this declarative way of creating applications is very powerful. \
In future sections we will dive into more complex and interesting applications.
This concludes the "hello world" introduction to the essential
system.