1use crate::{
16 config::{
17 Backend,
18 Node,
19 },
20 ir,
21};
22use derive_more::From;
23use proc_macro2::TokenStream as TokenStream2;
24use quote::quote;
25
26#[derive(From)]
28pub struct InkE2ETest {
29 test: ir::InkE2ETest,
31}
32
33impl InkE2ETest {
34 pub fn generate_code(&self) -> TokenStream2 {
36 #[cfg(clippy)]
37 if true {
38 return quote! {};
39 }
40
41 let item_fn = &self.test.item_fn.item_fn;
42 let fn_name = &item_fn.sig.ident;
43 let block = &item_fn.block;
44 let fn_return_type = &item_fn.sig.output;
45 let vis = &item_fn.vis;
46 let attrs = &item_fn.attrs;
47 let ret = match fn_return_type {
48 syn::ReturnType::Default => quote! {},
49 syn::ReturnType::Type(rarrow, ret_type) => quote! { #rarrow #ret_type },
50 };
51
52 let environment = self
53 .test
54 .config
55 .environment()
56 .unwrap_or_else(|| syn::parse_quote! { ::ink::env::DefaultEnvironment });
57
58 let features = self.test.config.features();
59 let exec_build_contracts = quote! {
60 ::ink_e2e::build_root_and_contract_dependencies(
61 vec![#( #features.to_string() ),*]
62 )
63 };
64
65 let client_building = match self.test.config.backend() {
66 Backend::Node(node_config) => {
67 build_full_client(&environment, exec_build_contracts, node_config)
68 }
69 #[cfg(any(test, feature = "sandbox"))]
70 Backend::RuntimeOnly(runtime) => {
71 build_runtime_client(exec_build_contracts, runtime.into())
72 }
73 };
74
75 quote! {
76 #( #attrs )*
77 #[test]
78 #vis fn #fn_name () #ret {
79 use ::ink_e2e::log_info;
80 ::ink_e2e::LOG_PREFIX.with(|log_prefix| {
81 let str = format!("test: {}", stringify!(#fn_name));
82 *log_prefix.borrow_mut() = String::from(str);
83 });
84 log_info("setting up e2e test");
85
86 ::ink_e2e::INIT.call_once(|| {
87 ::ink_e2e::tracing_subscriber::fmt::init();
88 });
89
90 log_info("creating new client");
91
92 let run = async {
93 #client_building
94
95 let __ret = {
96 #block
97 };
98 __ret
99 };
100
101 {
102 return ::ink_e2e::tokio::runtime::Builder::new_current_thread()
103 .enable_all()
104 .build()
105 .unwrap_or_else(|err| panic!("Failed building the Runtime: {err}"))
106 .block_on(run);
107 }
108 }
109 }
110 }
111}
112
113fn build_full_client(
114 environment: &syn::Path,
115 contracts: TokenStream2,
116 node_config: Node,
117) -> TokenStream2 {
118 match node_config.url() {
119 Some(url) => {
120 quote! {
121 let contracts = #contracts;
122 let rpc = ::ink_e2e::RpcClient::from_url(#url)
123 .await
124 .unwrap_or_else(|err|
125 ::core::panic!("Error connecting to node at {}: {err:?}", #url)
126 );
127 let mut client = ::ink_e2e::Client::<
128 ::ink_e2e::PolkadotConfig,
129 #environment
130 >::new(rpc, contracts, #url.to_string()).await?;
131 }
132 }
133 None => {
134 quote! {
135 let contracts = #contracts;
136 let node_rpc = ::ink_e2e::TestNodeProcess::<::ink_e2e::PolkadotConfig>
137 ::build_with_env_or_default()
138 .spawn()
139 .await
140 .unwrap_or_else(|err|
141 ::core::panic!("Error spawning ink-node: {err:?}")
142 );
143 let mut client = ::ink_e2e::Client::<
144 ::ink_e2e::PolkadotConfig,
145 #environment
146 >::new(node_rpc.rpc(), contracts, node_rpc.url().to_string()).await?;
147 }
148 }
149 }
150}
151
152#[cfg(any(test, feature = "sandbox"))]
153fn build_runtime_client(contracts: TokenStream2, runtime: syn::Path) -> TokenStream2 {
154 quote! {
155 let contracts = #contracts;
156 let mut client = ::ink_e2e::SandboxClient::<_, #runtime>::new(contracts);
157 }
158}