#[path = "suites/market_data.rs"]
pub mod market_data;
#[path = "suites/trading.rs"]
pub mod trading;
#[path = "suites/account.rs"]
pub mod account;
#[path = "suites/positions.rs"]
pub mod positions;
#[path = "suites/operations.rs"]
pub mod operations;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TestStatus {
Passed,
Failed,
Skipped,
Error,
}
impl fmt::Display for TestStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Passed => write!(f, "PASS"),
Self::Failed => write!(f, "FAIL"),
Self::Skipped => write!(f, "SKIP"),
Self::Error => write!(f, "ERR "),
}
}
}
#[derive(Debug, Clone)]
pub struct TestResult {
pub test_name: String,
pub exchange: String,
pub status: TestStatus,
pub message: Option<String>,
pub duration_ms: u64,
}
impl TestResult {
pub fn pass(test_name: impl Into<String>, exchange: impl Into<String>, duration_ms: u64) -> Self {
Self {
test_name: test_name.into(),
exchange: exchange.into(),
status: TestStatus::Passed,
message: None,
duration_ms,
}
}
pub fn fail(
test_name: impl Into<String>,
exchange: impl Into<String>,
duration_ms: u64,
reason: impl Into<String>,
) -> Self {
Self {
test_name: test_name.into(),
exchange: exchange.into(),
status: TestStatus::Failed,
message: Some(reason.into()),
duration_ms,
}
}
pub fn skip(
test_name: impl Into<String>,
exchange: impl Into<String>,
duration_ms: u64,
reason: impl Into<String>,
) -> Self {
Self {
test_name: test_name.into(),
exchange: exchange.into(),
status: TestStatus::Skipped,
message: Some(reason.into()),
duration_ms,
}
}
pub fn error(
test_name: impl Into<String>,
exchange: impl Into<String>,
duration_ms: u64,
err: impl Into<String>,
) -> Self {
Self {
test_name: test_name.into(),
exchange: exchange.into(),
status: TestStatus::Error,
message: Some(err.into()),
duration_ms,
}
}
}
impl fmt::Display for TestResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] {}/{}", self.status, self.exchange, self.test_name)?;
if let Some(ref msg) = self.message {
write!(f, " — {}", msg)?;
}
write!(f, " ({}ms)", self.duration_ms)
}
}
use crate::core::types::ExchangeError;
pub fn is_unsupported(err: &ExchangeError) -> bool {
matches!(err, ExchangeError::UnsupportedOperation(_) | ExchangeError::NotSupported(_))
}
pub fn is_auth_error(err: &ExchangeError) -> bool {
matches!(
err,
ExchangeError::Auth(_)
| ExchangeError::InvalidCredentials(_)
| ExchangeError::PermissionDenied(_)
)
}
pub use crate::testing::assertions::{
assert_balance_sane, assert_kline_sane, assert_orderbook_sane,
assert_position_sane, assert_price_sane, assert_ticker_sane,
};
pub use crate::testing::harness::TestHarness;