diff --git a/.config/cargo_spellcheck.dic b/.config/cargo_spellcheck.dic index a27b9840d85..fafdff77c7b 100644 --- a/.config/cargo_spellcheck.dic +++ b/.config/cargo_spellcheck.dic @@ -128,9 +128,7 @@ WebSocket/S StorageVec KiB GB -BufferTooSmall -KeyNotFound -ink_env +DRink ^ externalities sandbox_client diff --git a/CHANGELOG.md b/CHANGELOG.md index 19f46f3e975..682b6609a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fix outdated docs for `[ink_e2e::test]` ‒ [#2162](https://github.com/paritytech/ink/pull/2162) + ## Version 5.0.0 ℹ️ _We've created a migration guide from ink! 4 to ink! 5. It also contains an diff --git a/Cargo.lock b/Cargo.lock index 476befad3fb..717ad74f0c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2668,6 +2668,8 @@ version = "5.0.0" dependencies = [ "darling 0.20.8", "derive_more", + "ink", + "ink_e2e", "ink_ir", "proc-macro2", "quote", diff --git a/crates/e2e/macro/Cargo.toml b/crates/e2e/macro/Cargo.toml index bb05f3dea01..854fb778507 100644 --- a/crates/e2e/macro/Cargo.toml +++ b/crates/e2e/macro/Cargo.toml @@ -29,6 +29,8 @@ proc-macro2 = { workspace = true } quote = { workspace = true } [dev-dependencies] +ink = { path = "../../ink" } +ink_e2e = { path = "../", features = ["drink"] } temp-env = "0.3.6" [features] diff --git a/crates/e2e/macro/src/codegen.rs b/crates/e2e/macro/src/codegen.rs index ac4effabc8a..8fe73fb959d 100644 --- a/crates/e2e/macro/src/codegen.rs +++ b/crates/e2e/macro/src/codegen.rs @@ -23,7 +23,7 @@ use derive_more::From; use proc_macro2::TokenStream as TokenStream2; use quote::quote; -/// Generates code for the `[ink::e2e_test]` macro. +/// Generates code for the `[ink_e2e::test]` macro. #[derive(From)] pub struct InkE2ETest { /// The test function to generate code for. @@ -31,7 +31,7 @@ pub struct InkE2ETest { } impl InkE2ETest { - /// Generates the code for `#[ink:e2e_test]`. + /// Generates the code for `#[ink_e2e:test]`. pub fn generate_code(&self) -> TokenStream2 { #[cfg(clippy)] if true { diff --git a/crates/e2e/macro/src/lib.rs b/crates/e2e/macro/src/lib.rs index f13afa8f2ff..bcdad3e5886 100644 --- a/crates/e2e/macro/src/lib.rs +++ b/crates/e2e/macro/src/lib.rs @@ -34,63 +34,107 @@ use syn::Result; /// and install it on your PATH, or provide a path to an executable using the /// `CONTRACTS_NODE` environment variable. /// -/// Before the test function is invoked the contract will have been build. Any errors -/// that occur during the contract build will prevent the test function from being -/// invoked. +/// Before the test function is invoked the contract will be built. Any errors that occur +/// during the contract build will prevent the test function from being invoked. /// /// ## Header Arguments /// -/// The `#[ink::e2e_test]` macro can be provided with some additional comma-separated -/// header arguments: +/// The `#[ink_e2e::test]` macro can be provided with additional arguments. +/// +/// ### Custom Environment +/// +/// You can specify the usage of a custom environment: +/// +/// ```ignore +/// #[ink_e2e::test(environment = crate::EnvironmentWithManyTopics)] +/// ``` +/// +/// Our documentation contains [an explainer of what custom environments are](https://use.ink/basics/chain-environment-types). +/// For a full example [see here](https://github.com/paritytech/ink-examples/tree/v5.x.x/custom-environment). +/// +/// ### Custom Backend +/// +/// You can switch the E2E test to use the [DRink!](https://use.ink/basics/contract-testing/drink) +/// testing framework with this syntax: +/// +/// ``` +/// type E2EResult = std::result::Result>; +/// +/// #[ink_e2e::test(backend(runtime_only))] +/// async fn runtime_call_works() -> E2EResult<()> { +/// // ... +/// } +/// ``` +/// +/// In this configuration the test will not run against a node that is running in the +/// background, but against an in-process slimmed down `pallet-contracts` execution +/// environment. +/// +/// Please see [the page on testing with DRink!](https://use.ink/basics/contract-testing/drink) +/// in our documentation for more details. +/// For a full example [see here](https://github.com/paritytech/ink-examples/tree/v5.x.x/e2e-runtime-only-backend). /// /// # Example /// -/// ```no_compile -/// # // TODO(#xxx) Remove the `no_compile`. -/// #[cfg(test)] -/// mod tests { -/// use ::ink_e2e::*; -/// type E2EResult = std::result::Result>; -/// -/// #[ink::e2e_test] -/// async fn e2e_test_2(mut client: ::ink_e2e::Client) -> E2EResult<()> { -/// // given -/// let constructor = contract_transfer::constructors::new(); -/// let contract_acc_id = client.instantiate( -/// &mut ::ink_e2e::alice(), -/// constructor, -/// 1337, -/// None, -/// ) -/// .await -/// .expect("instantiating contract failed") -/// .account_id; -/// -/// // when -/// let transfer = contract_transfer::messages::give_me(120); -/// let call_res = client.call( -/// &mut ::ink_e2e::bob(), -/// contract_acc_id.clone(), -/// transfer.into(), -/// 10, -/// None, -/// ) -/// .await; -/// -/// // then -/// assert!(call_res.is_ok()); -/// Ok(()) +/// ``` +/// # use ink::env::{ +/// # Environment, +/// # DefaultEnvironment, +/// # }; +/// # type AccountId = ::AccountId; +/// # +/// #[ink::contract] +/// mod my_module { +/// #[ink(storage)] +/// pub struct MyContract {} +/// +/// impl MyContract { +/// #[ink(constructor)] +/// pub fn new() -> Self { +/// Self {} +/// } +/// +/// #[ink(message)] +/// pub fn my_message(&self) {} /// } /// } +/// +/// type E2EResult = std::result::Result>; +/// +/// #[ink_e2e::test] +/// async fn e2e_test(mut client: ::ink_e2e::Client) -> E2EResult<()> { +/// // given +/// use my_module::MyContract; +/// let mut constructor = MyContract::new(); +/// let contract = client +/// .instantiate("contract_transfer", &ink_e2e::bob(), &mut constructor) +/// .submit() +/// .await +/// .expect("instantiate failed"); +/// let mut call_builder = contract.call_builder::(); +/// +/// // when +/// let my_message = call_builder.my_message(); +/// let call_res = client +/// .call(&ink_e2e::eve(), &my_message) +/// .submit() +/// .await +/// .expect("call failed"); +/// +/// // then +/// assert!(call_res.is_ok()); +/// +/// Ok(()) +/// } /// ``` /// -/// You can also use build the `Signer` type yourself, without going through -/// the pre-defined functions: +/// You can also build the `Keypair` type yourself, without going through +/// the pre-defined functions (`ink_e2e::alice()`, …): /// -/// ```no_compile -/// let mut bob = ::ink_e2e::PairSigner::new( -/// ::ink_e2e::AccountKeyring::Bob.pair() -/// ); +/// ``` +/// use std::str::FromStr; +/// let suri = ::ink_e2e::subxt_signer::SecretUri::from_str("//Alice").unwrap(); +/// let alice = ::ink_e2e::Keypair::from_uri(&suri).unwrap(); /// ``` #[proc_macro_attribute] pub fn test(attr: TokenStream, item: TokenStream) -> TokenStream { diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index 289b96612dd..bb69aab0088 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -86,3 +86,6 @@ ink-debug = [] # Disable the ink! provided global memory allocator. no-allocator = [ "ink_allocator/no-allocator" ] + +# Disable the ink! provided panic handler. +no-panic-handler = [] diff --git a/crates/env/src/lib.rs b/crates/env/src/lib.rs index f5adef5763f..9959ccccef5 100644 --- a/crates/env/src/lib.rs +++ b/crates/env/src/lib.rs @@ -55,7 +55,7 @@ pub const BUFFER_SIZE: usize = 16384; #[allow(unused_extern_crates)] extern crate rlibc; -#[cfg(not(feature = "std"))] +#[cfg(not(any(feature = "std", feature = "no-panic-handler")))] #[allow(unused_variables)] #[panic_handler] fn panic(info: &core::panic::PanicInfo) -> ! { diff --git a/crates/ink/Cargo.toml b/crates/ink/Cargo.toml index f2790b07147..bb23bdc9181 100644 --- a/crates/ink/Cargo.toml +++ b/crates/ink/Cargo.toml @@ -53,3 +53,6 @@ show-codegen-docs = [] # Disable the ink! provided global memory allocator. no-allocator = [ "ink_env/no-allocator" ] + +# Disable the ink! provided panic handler. +no-panic-handler = ["ink_env/no-panic-handler"] diff --git a/integration-tests/flipper/lib.rs b/integration-tests/flipper/lib.rs index d2eb93edaea..3730b8e2261 100644 --- a/integration-tests/flipper/lib.rs +++ b/integration-tests/flipper/lib.rs @@ -131,7 +131,7 @@ pub mod flipper { /// # node process for each test. /// $ export CONTRACTS_NODE_URL=ws://127.0.0.1:9944 /// - /// $ export CONTRACT_HEX=0x2c75f0aa09dbfbfd49e6286a0f2edd3b4913f04a58b13391c79e96782f5713e3 + /// $ export CONTRACT_ADDR_HEX=0x2c75f0aa09dbfbfd49e6286a0f2edd3b4913f04a58b13391c79e96782f5713e3 /// $ cargo test --features e2e-tests e2e_test_deployed_contract -- --ignored /// ``` /// @@ -150,14 +150,19 @@ pub mod flipper { let acc_id = hex::decode(addr).unwrap(); let acc_id = AccountId::try_from(&acc_id[..]).unwrap(); + use std::str::FromStr; + let suri = ink_e2e::subxt_signer::SecretUri::from_str("//Alice").unwrap(); + let caller = ink_e2e::Keypair::from_uri(&suri).unwrap(); + // when - // Invoke `Flipper::get()` from Bob's account + // Invoke `Flipper::get()` from `caller`'s account let call_builder = ink_e2e::create_call_builder::(acc_id); let get = call_builder.get(); - let get_res = client.call(&ink_e2e::bob(), &get).dry_run().await?; + let get_res = client.call(&caller, &get).dry_run().await?; // then - assert!(matches!(get_res.return_value(), true)); + assert_eq!(get_res.return_value(), true); + Ok(()) } }