Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: README.md #17

Closed

Conversation

chungquantin
Copy link
Collaborator

@chungquantin chungquantin commented Oct 10, 2024

Pop DRink!

R0GUE Logo

Twitter URL
Twitter URL
Telegram

Forked version of inkdevhub/drink for E2E testing smart contract using Pop API with Pop Network runtimes.

Overview

About the repository folder structure:

  • pop-drink: Provides utility methods for testing contract methods with DRink! and Pop Network runtimes.
  • examples: A collection of example contracts tested with DRink!
  • drink: DRink! is a toolbox for ink! developers that allows for a fully functional ink! contract development without any running node.
  • ink-sandbox: Sandbox refers to an isolated runtime environment that simulates the behavior of a full node, without requiring an actual node.
  • drink-cli: Simple command line tool to help you play with your local contracts in a convenient way.

Getting Started

Add pop-drink crate to your contract Cargo.toml:

drink = { version = "1.0.0",  package = "pop-drink" }

Setup a testing environment

Please see "Quick start with DRink!" for a detailed explanation.

Add the below code at the top of your contract test file to setup Sandbox for the Pop Network Devnet runtime.

#[derive(Default)]
struct Sandbox;

// Implement `Sandbox` environment for the Pop Network Devnet runtime.
drink::impl_sandbox!(Sandbox, drink::devnet::Runtime, ALICE);

Writing tests

Writing tests

Your typical test module will look like (See "Quick start with DRink!" example tests):

#[cfg(test)]
mod tests {
    use drink::session::{Session, NO_ARGS, None, NO_SALT};

    #[drink::contract_bundle_provider]
    enum BundleProvider {}

    #[drink::test]
    fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box<dyn Error>> {
        let result: bool = session
            .deploy_bundle_and(BundleProvider::local(), "new", &["true"], NO_SALT, None)?
            .call_and("flip", NO_ARGS, None)?
            .call_and("flip", NO_ARGS, None)?
            .call_and("flip", NO_ARGS, None)?
            .call("get", NO_ARGS, None)??;
        assert_eq!(result, false);
    }
}

So, firstly, you declare a bundle provider like:

#[drink::contract_bundle_provider]
enum BundleProvider {}

It will take care of building all contract dependencies in the compilation phase and gather all contract bundles into a single registry.
Then, you will be able to get a contract bundle by calling:

let bundle = BundleProvider::local()?; // for the contract from the current crate
let bundle = BundleProvider::Flipper.bundle()?; // for the contract from the `flipper` crate

We mark each testcase with #[drink::test] attribute and declare return type as Result so that we can use the ? operator:

#[drink::test]
fn testcase() -> Result<(), Box<dyn Error>> {
    // ...
}

Then, we can use the Session API to interact with both contracts and the whole runtime.
For details, check out testcases in lib.rs.

Writing tests for methods using Pop API

Pop DRink! also provides utilitiy methods that you can use to test your contracts. This example interacts with a PSP22 example contract that uses Pop API. The contract method returns PSP22Error custom error which is provided by Pop API library.

// Import required methods and types.
use drink::{call, session::Session};
use pop_api::v0::fungibles::PSP22Error;

// Interact with `transfer` method of the `Psp22` contract.
fn transfer(session: &mut Session<Pop>, to: AccountId, amount: Balance) -> Result<(), PSP22Error> {
 let empty_array = serde_json::to_string::<[u8; 0]>(&[]).unwrap();
 let input = vec![to.to_string(), amount.to_string(), empty_array];

 call::<Pop, (), PSP22Error>(session, "Psp22::transfer", input, None)
}

Asserts the returned error to an Error type using assert_err! to test errors of a runtime call.

use drink::{assert_err, v0::Error, Assets, AssetsError::NoAccount};

#[drink::test(sandbox = Pop)]
fn test_transfer_to_no_account() {
  // Test the contract call if a custom error is the runtime module error.
  assert_err!(
    transfer(&mut session, ALICE, AMOUNT),
    Error::Module(Assets(NoAccount))
  );
}

We need to specify the sandbox of Pop Network runtime for a testcase if the contract is using Pop API.

#[drink::test(sandbox = Pop)]

Development Guide

To run the examples contracts for DRink!

cargo test --release

Support

Copy link
Collaborator

@Daanvdplas Daanvdplas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skimmed over it and this can be simplified a lot.
The readme should only provide the information to get started and use the pop drink code in the developers tests. FYI: all the links I tried were broken. On that note, links should be provided when someone wants to learn more about something. There should be a minimal explanation tmo which gives the reader at least an idea of what it is / what it does without the link.

So to be a bit clearer, I think the things I commented on should stay for sure. The rest can be perhaps be removed. Don't take my word though and see what really needs to stay, you have a good eye for this as well.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants