diff --git a/Cargo.toml b/Cargo.toml index 425b79ed..7ace02b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,5 +58,6 @@ ws-tokio = ["soketto", "url", "tokio", "tokio-util"] ws-async-std = ["soketto", "url", "async-std"] ws-tls-tokio = ["async-native-tls", "native-tls", "async-native-tls/runtime-tokio", "ws-tokio"] ws-tls-async-std = ["async-native-tls", "native-tls", "async-native-tls/runtime-async-std", "ws-async-std"] +test = [] [workspace] diff --git a/src/api/accounts.rs b/src/api/accounts.rs index 2d0468f2..6424adb7 100644 --- a/src/api/accounts.rs +++ b/src/api/accounts.rs @@ -234,8 +234,8 @@ impl Transaction { #[cfg(test)] mod tests { use super::*; - use crate::helpers::tests::TestTransport; use crate::signing::{SecretKey, SecretKeyRef}; + use crate::transports::test::TestTransport; use crate::types::Bytes; use rustc_hex::FromHex; use serde_json::json; diff --git a/src/api/eth_filter.rs b/src/api/eth_filter.rs index d815f54a..3fc68d4d 100644 --- a/src/api/eth_filter.rs +++ b/src/api/eth_filter.rs @@ -202,8 +202,8 @@ impl EthFilter { mod tests { use super::EthFilter; use crate::api::Namespace; - use crate::helpers::tests::TestTransport; use crate::rpc::Value; + use crate::transports::test::TestTransport; use crate::types::{Address, Bytes, FilterBuilder, Log, H256}; use futures::stream::StreamExt; use std::time::Duration; diff --git a/src/confirm.rs b/src/confirm.rs index 0a0b8e15..4b12eace 100644 --- a/src/confirm.rs +++ b/src/confirm.rs @@ -117,8 +117,8 @@ where #[cfg(test)] mod tests { use super::send_transaction_with_confirmation; - use crate::helpers::tests::TestTransport; use crate::rpc::Value; + use crate::transports::test::TestTransport; use crate::types::{Address, TransactionReceipt, TransactionRequest, H256, U64}; use serde_json::json; use std::time::Duration; diff --git a/src/contract/deploy.rs b/src/contract/deploy.rs index 55934039..91ffa606 100644 --- a/src/contract/deploy.rs +++ b/src/contract/deploy.rs @@ -165,8 +165,8 @@ impl Builder { mod tests { use crate::api::{self, Namespace}; use crate::contract::{Contract, Options}; - use crate::helpers::tests::TestTransport; use crate::rpc; + use crate::transports::test::TestTransport; use crate::types::{Address, U256}; use serde_json::Value; use std::collections::HashMap; diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 3d21034e..daf18018 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -323,8 +323,8 @@ impl Contract { mod tests { use super::{Contract, Options}; use crate::api::{self, Namespace}; - use crate::helpers::tests::TestTransport; use crate::rpc; + use crate::transports::test::TestTransport; use crate::types::{Address, BlockId, BlockNumber, H256, U256}; use crate::Transport; diff --git a/src/helpers.rs b/src/helpers.rs index f21842c9..41c26da7 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -95,74 +95,6 @@ pub fn to_result_from_output(output: rpc::Output) -> error::Result { #[macro_use] #[cfg(test)] pub mod tests { - use crate::error::{self, Error}; - use crate::rpc; - use crate::{RequestId, Transport}; - use futures::future::{self, BoxFuture, FutureExt}; - use std::cell::RefCell; - use std::collections::VecDeque; - use std::rc::Rc; - - type Result = BoxFuture<'static, error::Result>; - - #[derive(Debug, Default, Clone)] - pub struct TestTransport { - asserted: usize, - requests: Rc)>>>, - responses: Rc>>, - } - - impl Transport for TestTransport { - type Out = Result; - - fn prepare(&self, method: &str, params: Vec) -> (RequestId, rpc::Call) { - let request = super::build_request(1, method, params.clone()); - self.requests.borrow_mut().push((method.into(), params)); - (self.requests.borrow().len(), request) - } - - fn send(&self, id: RequestId, request: rpc::Call) -> Result { - future::ready(match self.responses.borrow_mut().pop_front() { - Some(response) => Ok(response), - None => { - println!("Unexpected request (id: {:?}): {:?}", id, request); - Err(Error::Unreachable) - } - }) - .boxed() - } - } - - impl TestTransport { - pub fn set_response(&mut self, value: rpc::Value) { - *self.responses.borrow_mut() = vec![value].into(); - } - - pub fn add_response(&mut self, value: rpc::Value) { - self.responses.borrow_mut().push_back(value); - } - - pub fn assert_request(&mut self, method: &str, params: &[String]) { - let idx = self.asserted; - self.asserted += 1; - - let (m, p) = self.requests.borrow().get(idx).expect("Expected result.").clone(); - assert_eq!(&m, method); - let p: Vec = p.into_iter().map(|p| serde_json::to_string(&p).unwrap()).collect(); - assert_eq!(p, params); - } - - pub fn assert_no_more_requests(&self) { - let requests = self.requests.borrow(); - assert_eq!( - self.asserted, - requests.len(), - "Expected no more requests, got: {:?}", - &requests[self.asserted..] - ); - } - } - macro_rules! rpc_test { // With parameters ( @@ -172,7 +104,7 @@ pub mod tests { #[test] fn $test_name() { // given - let mut transport = $crate::helpers::tests::TestTransport::default(); + let mut transport = $crate::transports::test::TestTransport::default(); transport.set_response($returned); let result = { let eth = $namespace::new(&transport); @@ -207,7 +139,7 @@ pub mod tests { #[test] fn $test_name() { // given - let mut transport = $crate::helpers::tests::TestTransport::default(); + let mut transport = $crate::transports::test::TestTransport::default(); transport.set_response($returned); let result = { let eth = $namespace::new(&transport); diff --git a/src/transports/mod.rs b/src/transports/mod.rs index ced6bf6e..fe80a2a5 100644 --- a/src/transports/mod.rs +++ b/src/transports/mod.rs @@ -15,6 +15,9 @@ pub mod ws; #[cfg(any(feature = "ws-tokio", feature = "ws-async-std"))] pub use self::ws::WebSocket; +#[cfg(any(feature = "test", test))] +pub mod test; + #[cfg(feature = "url")] impl From for crate::Error { fn from(err: url::ParseError) -> Self { diff --git a/src/transports/test.rs b/src/transports/test.rs new file mode 100644 index 00000000..1ac9581f --- /dev/null +++ b/src/transports/test.rs @@ -0,0 +1,75 @@ +//! Test Transport + +use crate::error::{self, Error}; +use crate::helpers; +use crate::rpc; +use crate::{RequestId, Transport}; +use futures::future::{self, BoxFuture, FutureExt}; +use std::cell::RefCell; +use std::collections::VecDeque; +use std::rc::Rc; + +type Result = BoxFuture<'static, error::Result>; + +/// Test Transport +#[derive(Debug, Default, Clone)] +pub struct TestTransport { + asserted: usize, + requests: Rc)>>>, + responses: Rc>>, +} + +impl Transport for TestTransport { + type Out = Result; + + fn prepare(&self, method: &str, params: Vec) -> (RequestId, rpc::Call) { + let request = helpers::build_request(1, method, params.clone()); + self.requests.borrow_mut().push((method.into(), params)); + (self.requests.borrow().len(), request) + } + + fn send(&self, id: RequestId, request: rpc::Call) -> Result { + future::ready(match self.responses.borrow_mut().pop_front() { + Some(response) => Ok(response), + None => { + println!("Unexpected request (id: {:?}): {:?}", id, request); + Err(Error::Unreachable) + } + }) + .boxed() + } +} + +impl TestTransport { + /// Set response + pub fn set_response(&mut self, value: rpc::Value) { + *self.responses.borrow_mut() = vec![value].into(); + } + + /// Add response + pub fn add_response(&mut self, value: rpc::Value) { + self.responses.borrow_mut().push_back(value); + } + + /// Assert request + pub fn assert_request(&mut self, method: &str, params: &[String]) { + let idx = self.asserted; + self.asserted += 1; + + let (m, p) = self.requests.borrow().get(idx).expect("Expected result.").clone(); + assert_eq!(&m, method); + let p: Vec = p.into_iter().map(|p| serde_json::to_string(&p).unwrap()).collect(); + assert_eq!(p, params); + } + + /// Assert no more requests + pub fn assert_no_more_requests(&self) { + let requests = self.requests.borrow(); + assert_eq!( + self.asserted, + requests.len(), + "Expected no more requests, got: {:?}", + &requests[self.asserted..] + ); + } +}