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
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

151 changes: 117 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,151 @@
<h1 align="center"> Pop DRink! (forked from DRink!) </h1>
<p align="center"> <b>D</b>echained <b>R</b>eady-to-play <b>ink!</b> playground </p>
<div align="center">
<h1>Pop DRink!</h1>

> [!IMPORTANT]
> This repository is customized and maintained for Pop API contract end-to-end testing.
>
> Quasi tests must be run with `cargo test --release`.
<a href="r0gue.io"><img width="100px" style="border-radius:10px;" src="https://github.com/user-attachments/assets/96830651-c3db-412a-9cb4-6fcd8ea6231b" alt="R0GUE Logo" /></a>

# Pop Sandbox
[![Twitter URL](https://img.shields.io/twitter/follow/Pop?style=social)](https://x.com/onpopio/)
[![Twitter URL](https://img.shields.io/twitter/follow/R0GUE?style=social)](https://twitter.com/gor0gue)
[![Telegram](https://img.shields.io/badge/Telegram-gray?logo=telegram)](https://t.me/onpopio)

Implementation of the [`pop_drink::Sandbox`](https://github.com/r0gue-io/pop-drink) struct for the Pop Network runtimes (located in `pop-node/runtime`) required for the quasi testing with `drink`.
Forked version of [inkdevhub/drink](https://github.com/inkdevhub/drink) for E2E testing smart contract using [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api) with [Pop Network runtimes](https://github.com/r0gue-io/pop-node/tree/main/runtime).

In the context of quasi-testing with pop-drink, a sandbox refers to an isolated runtime environment that simulates the behavior of a full node, without requiring an actual node. It can emulate key processes (where runtime `pallets` are involved) such as block initialization, execution, and block finalization.
</div>

## Overview

About the repository folder structure:

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

## Getting Started

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

```toml
pop_drink = { version = "1.0.0", package = "pop-drink" }
drink = { version = "1.0.0", package = "pop-drink" }
```

### Import Sandbox for the specific runtime
### Setup a testing environment

- For `devnet` runtime
Please see ["Quick start with DRink!"](/crates/drink/examples/quick-start-with-drink/README.md) for a detailed explanation.

Implementation of the sandbox runtime environment for `devnet` runtime located in `pop-node/runtime/devnet`
Add the below code at the top of your contract test file to setup [Sandbox](TODO) for the [**Pop Network Devnet**](https://github.com/r0gue-io/pop-node/tree/main/runtime/devnet) runtime.

```rs
use pop_sandbox::DevnetSandbox;
#[derive(Default)]
struct Sandbox;

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

- For `testnet` runtime
## Writing tests

Implementation of the sandbox runtime environment for `testnet` runtime located in `pop-node/runtime/testnet`
### Writing tests

```rs
use pop_sandbox::TestnetSandbox;
Your typical test module will look like (See ["Quick start with DRink!"](/crates/drink/examples/quick-start-with-drink/README.md) example tests):

```rust
#[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);
}
}
```

- For `mainnet` runtime
So, firstly, you declare a bundle provider like:

Implementation of the sandbox runtime environment for `mainnet` runtime located in `pop-node/runtime/mainnet`
```rust
#[drink::contract_bundle_provider]
enum BundleProvider {}
```

```rs
use pop_sandbox::MainnetSandbox;
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:

```rust
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:

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

### Setup test environment for your contract
Then, we can use the `Session` API to interact with both contracts and the whole runtime.
For details, check out testcases in [lib.rs](lib.rs).

Below is an example for the contract testing with `pop_drink` and `pop_sandbox` for `devnet` environment using `DevnetSandbox`.
### Writing tests for methods using [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api)

Pop DRink! also provides [utilitiy methods](/crates/pop-drink/src/lib.rs) that you can use to test your contracts. This example interacts with a [PSP22 example contract](https://github.com/r0gue-io/pop-node/blob/main/pop-api/examples/fungibles/lib.rs) that uses [Pop API](https://github.com/r0gue-io/pop-node/tree/main/pop-api). The contract method returns [`PSP22Error`](https://github.com/r0gue-io/pop-node/blob/main/pop-api/src/v0/fungibles/errors.rs#L73C1-L73C22) custom error which is provided by Pop API library.

```rs
use pop_drink::session::Session;
use pop_sandbox::DevnetSandbox as Sandbox;
// Import required methods and types.
use drink::{call, session::Session};
use pop_api::v0::fungibles::PSP22Error;

#[drink::contract_bundle_provider]
enum BundleProvider {}
// 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];

#[drink::test(sandbox = Sandbox)]
fn test(mut session: Session) {
// Your test case
call::<Pop, (), PSP22Error>(session, "Psp22::transfer", input, None)
}
```

## Examples
Asserts the returned error to an [`Error`](TODO) type using [`assert_err!`](TODO) to test errors of a runtime call.

```rs
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.

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

## Development Guide

To run the `examples` contracts for DRink!

```
cargo test --release
```

### Support

Please find more examples of `pop_drink` tests in the [`pop_drink/examples`](https://github.com/r0gue-io/pop-drink/tree/main/examples).
- Be part of our passionate community of Web3 pioneers. [Join our Telegram](https://t.me/onpopio)!
- Additionally, there are [GitHub issues](https://github.com/r0gue-io/pop-drink/issues) and
[Polkadot Stack Exchange](https://polkadot.stackexchange.com/).
Loading