pub mod models {
#![allow(warnings)]
include!(concat!(env!("OUT_DIR"), "/hyperflow.core.v1.rs"));
}
#[cfg(test)]
mod tests {
use super::models::{EnrichedTrade, HyperliquidTrade, MarketType, Position, RawTrade};
use prost::Message;
macro_rules! generate_model_tests {
(
$test_module_name:ident,
$model_type:ty,
$sample_data_fn:expr,
$default_checks:expr
) => {
mod $test_module_name {
use super::*;
#[test]
fn test_creation_with_sample_data() {
let instance = $sample_data_fn;
let expected_instance = $sample_data_fn;
assert_eq!(instance, expected_instance);
}
#[test]
fn test_default_values_are_correct() {
let instance = <$model_type>::default();
$default_checks(&instance);
}
#[test]
fn test_serialization_and_deserialization() {
let original = $sample_data_fn;
let mut buf = Vec::new();
original.encode(&mut buf).unwrap();
let deserialized = <$model_type>::decode(&buf[..]).unwrap();
assert_eq!(original, deserialized);
}
}
};
}
fn sample_hyperliquid_trade() -> HyperliquidTrade {
HyperliquidTrade {
coin: "ETH".to_string(),
side: "buy".to_string(),
px: "123.45".to_string(),
sz: "1.0".to_string(),
hash: "0xabc123".to_string(),
time: 1678886400,
tid: 1,
users: vec!["buyer_address".to_string(), "seller_address".to_string()],
}
}
generate_model_tests!(
hyperliquid_trade_tests,
HyperliquidTrade,
sample_hyperliquid_trade(),
|trade: &HyperliquidTrade| {
assert_eq!(trade.coin, "");
assert_eq!(trade.side, "");
assert_eq!(trade.px, "");
assert_eq!(trade.sz, "");
assert_eq!(trade.hash, "");
assert_eq!(trade.time, 0);
assert_eq!(trade.tid, 0);
assert!(trade.users.is_empty());
}
);
#[test]
fn test_create_hyperliquid_trade_with_overrides() {
let trade = HyperliquidTrade {
px: "0.0".to_string(),
sz: "0.0".to_string(),
users: vec!["buyer_address".to_string()],
..Default::default()
};
assert_eq!(trade.px, "0.0");
assert_eq!(trade.sz, "0.0");
assert_eq!(trade.users, vec!["buyer_address"]);
}
fn sample_raw_trade() -> RawTrade {
RawTrade {
symbol: "BTC/USD".to_string(),
is_buy: true,
is_taker: false,
price: "50000.0".to_string(),
amount: "0.1".to_string(),
quote_amount: "5000.0".to_string(),
hash: "abc-123".to_string(),
event_at: 1678887000,
transaction_id: "ext-xyz".to_string(),
wallet_address: "0x12345".to_string(),
market_type: MarketType::Perp as i32,
extra_data: None, }
}
generate_model_tests!(
raw_trade_tests,
RawTrade,
sample_raw_trade(),
|trade: &RawTrade| {
assert_eq!(trade.symbol, "");
assert!(!trade.is_buy);
assert!(!trade.is_taker);
assert_eq!(trade.price, "");
assert_eq!(trade.amount, "");
assert_eq!(trade.quote_amount, "");
assert_eq!(trade.hash, "");
assert_eq!(trade.event_at, 0);
assert_eq!(trade.transaction_id, "");
assert_eq!(trade.wallet_address, "");
assert_eq!(trade.market_type, MarketType::Perp as i32);
}
);
mod raw_trade_specific_tests {
use super::*;
#[test]
fn test_serialization_all_market_types() {
for mt in [MarketType::Perp, MarketType::Spot] {
let mut trade = sample_raw_trade();
trade.market_type = mt as i32;
let mut buf = Vec::new();
trade.encode(&mut buf).unwrap();
let deserialized = RawTrade::decode(&buf[..]).unwrap();
assert_eq!(deserialized.market_type, mt as i32);
}
}
#[test]
fn test_market_type_enum_values() {
assert_eq!(MarketType::Perp as i32, 0);
assert_eq!(MarketType::Spot as i32, 1);
}
}
fn sample_enriched_trade() -> EnrichedTrade {
EnrichedTrade {
symbol: "BTC/USD".to_string(),
is_buy: true,
is_taker: false,
price: "50000.0".to_string(),
amount: "0.1".to_string(),
quote_amount: "5000.0".to_string(),
hash: "abc-123".to_string(),
event_at: 1678887000,
transaction_id: "ext-xyz".to_string(),
wallet_address: "0x12345".to_string(),
market_type: MarketType::Perp as i32,
pnl: "100.0".to_string(),
pnl_usd: "100.0".to_string(),
holding_duration: 3600,
extra_data: None,
}
}
generate_model_tests!(
enriched_trade_tests,
EnrichedTrade,
sample_enriched_trade(),
|trade: &EnrichedTrade| {
assert_eq!(trade.symbol, "");
assert_eq!(trade.pnl, "");
assert_eq!(trade.pnl_usd, "");
assert_eq!(trade.holding_duration, 0);
}
);
fn sample_position() -> Position {
Position {
symbol: "BTC/USD".to_string(),
is_buy: true,
average_price: "50000.0".to_string(),
amount: "0.1".to_string(),
quote_amount: "5000.0".to_string(),
wallet_address: "0x12345".to_string(),
market_type: MarketType::Perp as i32,
}
}
generate_model_tests!(
position_tests,
Position,
sample_position(),
|pos: &Position| {
assert_eq!(pos.symbol, "");
assert!(!pos.is_buy);
assert_eq!(pos.average_price, "");
assert_eq!(pos.amount, "");
assert_eq!(pos.quote_amount, "");
assert_eq!(pos.wallet_address, "");
assert_eq!(pos.market_type, MarketType::Perp as i32);
}
);
}