1pub mod models {
6 #![allow(warnings)]
7 include!(concat!(env!("OUT_DIR"), "/hyperflow.core.v1.rs"));
8}
9
10#[cfg(test)]
11mod tests {
12 use super::models::{HyperliquidTrade, RawTrade, MarketType, EnrichedTrade, Position};
13 use prost::Message;
14
15 #[test]
16 fn test_create_hyperliquid_trade() {
17 let trade = HyperliquidTrade {
18 coin: "ETH".to_string(),
19 side: "buy".to_string(),
20 px: "123.45".to_string(),
21 sz: "1.0".to_string(),
22 hash: "0xabc123".to_string(),
23 time: 1678886400,
24 tid: 1,
25 users: vec!["buyer_address".to_string(), "seller_address".to_string()],
26 };
27
28 assert_eq!(trade.coin, "ETH");
29 assert_eq!(trade.side, "buy");
30 assert_eq!(trade.px, "123.45");
31 assert_eq!(trade.sz, "1.0");
32 assert_eq!(trade.hash, "0xabc123");
33 assert_eq!(trade.time, 1678886400);
34 assert_eq!(trade.tid, 1);
35 assert_eq!(trade.users, vec!["buyer_address", "seller_address"]);
36 }
37
38 #[test]
39 fn test_hyperliquid_trade_serialization() {
40 let trade = HyperliquidTrade {
41 coin: "BTC".to_string(),
42 side: "sell".to_string(),
43 px: "456.78".to_string(),
44 sz: "0.5".to_string(),
45 hash: "0xdef456".to_string(),
46 time: 1678886500,
47 tid: 2,
48 users: vec!["userA".to_string(), "userB".to_string()],
49 };
50
51 let mut buf = Vec::new();
52 trade.encode(&mut buf).unwrap();
53 let deserialized_trade = HyperliquidTrade::decode(&buf[..]).unwrap();
54
55 assert_eq!(deserialized_trade.coin, "BTC");
56 assert_eq!(deserialized_trade.side, "sell");
57 assert_eq!(deserialized_trade.px, "456.78");
58 assert_eq!(deserialized_trade.sz, "0.5");
59 assert_eq!(deserialized_trade.hash, "0xdef456");
60 assert_eq!(deserialized_trade.time, 1678886500);
61 assert_eq!(deserialized_trade.tid, 2);
62 assert_eq!(deserialized_trade.users, vec!["userA", "userB"]);
63 }
64
65 #[test]
66 fn test_create_raw_trade() {
67 let raw_trade = RawTrade {
68 symbol: "BTC/USD".to_string(),
69 is_buy: true,
70 is_taker: false,
71 price: "50000.0".to_string(),
72 amount: "0.1".to_string(),
73 quote_amount: "5000.0".to_string(),
74 trade_id: "abc-123".to_string(),
75 event_at: 1678887000,
76 transaction_id: "ext-xyz".to_string(),
77 wallet_address: "0x12345".to_string(),
78 market_type: MarketType::Perp as i32,
79 };
80
81 assert_eq!(raw_trade.symbol, "BTC/USD");
82 assert!(raw_trade.is_buy);
83 assert!(!raw_trade.is_taker);
84 assert_eq!(raw_trade.price, "50000.0");
85 assert_eq!(raw_trade.amount, "0.1");
86 assert_eq!(raw_trade.quote_amount, "5000.0");
87 assert_eq!(raw_trade.trade_id, "abc-123");
88 assert_eq!(raw_trade.event_at, 1678887000);
89 assert_eq!(raw_trade.transaction_id, "ext-xyz");
90 assert_eq!(raw_trade.wallet_address, "0x12345");
91 assert_eq!(raw_trade.market_type, MarketType::Perp as i32);
92 }
93
94 #[test]
95 fn test_raw_trade_serialization() {
96 let raw_trade = RawTrade {
97 symbol: "ETH/USD".to_string(),
98 is_buy: false,
99 is_taker: true,
100 price: "2000.0".to_string(),
101 amount: "0.5".to_string(),
102 quote_amount: "1000.0".to_string(),
103 trade_id: "def-456".to_string(),
104 event_at: 1678887100,
105 transaction_id: "ext-uvw".to_string(),
106 wallet_address: "0x67890".to_string(),
107 market_type: MarketType::Spot as i32,
108 };
109
110 let mut buf = Vec::new();
111 raw_trade.encode(&mut buf).unwrap();
112 let deserialized_raw_trade = RawTrade::decode(&buf[..]).unwrap();
113
114 assert_eq!(deserialized_raw_trade.symbol, "ETH/USD");
115 assert!(!deserialized_raw_trade.is_buy);
116 assert!(deserialized_raw_trade.is_taker);
117 assert_eq!(deserialized_raw_trade.price, "2000.0");
118 assert_eq!(deserialized_raw_trade.amount, "0.5");
119 assert_eq!(deserialized_raw_trade.quote_amount, "1000.0");
120 assert_eq!(deserialized_raw_trade.trade_id, "def-456");
121 assert_eq!(deserialized_raw_trade.event_at, 1678887100);
122 assert_eq!(deserialized_raw_trade.transaction_id, "ext-uvw");
123 assert_eq!(deserialized_raw_trade.wallet_address, "0x67890");
124 assert_eq!(deserialized_raw_trade.market_type, MarketType::Spot as i32);
125 }
126
127 #[test]
128 fn test_hyperliquid_trade_default_values() {
129 let trade = HyperliquidTrade::default();
130 assert_eq!(trade.coin, "");
131 assert_eq!(trade.side, "");
132 assert_eq!(trade.px, "");
133 assert_eq!(trade.sz, "");
134 assert_eq!(trade.hash, "");
135 assert_eq!(trade.time, 0);
136 assert_eq!(trade.tid, 0);
137 assert!(trade.users.is_empty());
138 }
139
140 #[test]
141 fn test_create_hyperliquid_trade_zero_values() {
142 let trade = HyperliquidTrade {
143 px: "0.0".to_string(),
144 sz: "0.0".to_string(),
145 users: vec!["buyer_address".to_string()],
146 ..Default::default()
147 };
148 assert_eq!(trade.px, "0.0");
149 assert_eq!(trade.sz, "0.0");
150 assert_eq!(trade.users, vec!["buyer_address"]);
151 }
152
153 #[test]
154 fn test_raw_trade_default_values() {
155 let raw_trade = RawTrade::default();
156 assert_eq!(raw_trade.symbol, "");
157 assert!(!raw_trade.is_buy);
158 assert!(!raw_trade.is_taker);
159 assert_eq!(raw_trade.price, "");
160 assert_eq!(raw_trade.amount, "");
161 assert_eq!(raw_trade.quote_amount, "");
162 assert_eq!(raw_trade.trade_id, "");
163 assert_eq!(raw_trade.event_at, 0);
164 assert_eq!(raw_trade.transaction_id, "");
165 assert_eq!(raw_trade.wallet_address, "");
166 assert_eq!(raw_trade.market_type, MarketType::Perp as i32); }
168
169 #[test]
170 fn test_create_raw_trade_zero_values() {
171 let raw_trade = RawTrade {
172 price: "0.0".to_string(),
173 amount: "0.0".to_string(),
174 quote_amount: "0.0".to_string(),
175 transaction_id: "".to_string(),
176 wallet_address: "".to_string(),
177 market_type: MarketType::Perp as i32,
178 ..Default::default()
179 };
180 assert_eq!(raw_trade.price, "0.0");
181 assert_eq!(raw_trade.amount, "0.0");
182 assert_eq!(raw_trade.quote_amount, "0.0");
183 assert_eq!(raw_trade.transaction_id, "");
184 assert_eq!(raw_trade.wallet_address, "");
185 }
186
187 #[test]
188 fn test_raw_trade_serialization_all_market_types() {
189 let market_types = [
190 MarketType::Perp,
191 MarketType::Spot,
192 ];
193 for mt in market_types.iter() {
194 let raw_trade = RawTrade {
195 symbol: "XRP/USD".to_string(),
196 is_buy: true,
197 is_taker: false,
198 price: "0.5".to_string(),
199 amount: "100.0".to_string(),
200 quote_amount: "50.0".to_string(),
201 trade_id: "test-id".to_string(),
202 event_at: 1678887300,
203 transaction_id: "ext-test".to_string(),
204 wallet_address: "0xabcde".to_string(),
205 market_type: *mt as i32,
206 };
207
208 let mut buf = Vec::new();
209 raw_trade.encode(&mut buf).unwrap();
210 let deserialized_raw_trade = RawTrade::decode(&buf[..]).unwrap();
211 assert_eq!(deserialized_raw_trade.market_type, *mt as i32);
212 }
213 }
214
215 #[test]
216 fn test_market_type_enum() {
217 assert_eq!(MarketType::Perp as i32, 0); assert_eq!(MarketType::Spot as i32, 1); }
220
221 #[test]
222 fn test_create_enriched_trade() {
223 let enriched_trade = EnrichedTrade {
224 symbol: "BTC/USD".to_string(),
225 is_buy: true,
226 is_taker: false,
227 price: "50000.0".to_string(),
228 amount: "0.1".to_string(),
229 quote_amount: "5000.0".to_string(),
230 trade_id: "abc-123".to_string(),
231 event_at: 1678887000,
232 transaction_id: "ext-xyz".to_string(),
233 wallet_address: "0x12345".to_string(),
234 market_type: MarketType::Perp as i32,
235 pnl: "100.0".to_string(),
236 pnl_usd: "100.0".to_string(),
237 holding_duration: 3600,
238 };
239
240 assert_eq!(enriched_trade.symbol, "BTC/USD");
241 assert!(enriched_trade.is_buy);
242 assert!(!enriched_trade.is_taker);
243 assert_eq!(enriched_trade.price, "50000.0");
244 assert_eq!(enriched_trade.amount, "0.1");
245 assert_eq!(enriched_trade.quote_amount, "5000.0");
246 assert_eq!(enriched_trade.trade_id, "abc-123");
247 assert_eq!(enriched_trade.event_at, 1678887000);
248 assert_eq!(enriched_trade.transaction_id, "ext-xyz");
249 assert_eq!(enriched_trade.wallet_address, "0x12345");
250 assert_eq!(enriched_trade.market_type, MarketType::Perp as i32);
251 assert_eq!(enriched_trade.pnl, "100.0");
252 assert_eq!(enriched_trade.pnl_usd, "100.0");
253 assert_eq!(enriched_trade.holding_duration, 3600);
254 }
255
256 #[test]
257 fn test_enriched_trade_default_values() {
258 let enriched_trade = EnrichedTrade::default();
259 assert_eq!(enriched_trade.symbol, "");
260 assert!(!enriched_trade.is_buy);
261 assert!(!enriched_trade.is_taker);
262 assert_eq!(enriched_trade.price, "");
263 assert_eq!(enriched_trade.amount, "");
264 assert_eq!(enriched_trade.quote_amount, "");
265 assert_eq!(enriched_trade.trade_id, "");
266 assert_eq!(enriched_trade.event_at, 0);
267 assert_eq!(enriched_trade.transaction_id, "");
268 assert_eq!(enriched_trade.wallet_address, "");
269 assert_eq!(enriched_trade.market_type, MarketType::Perp as i32);
270 assert_eq!(enriched_trade.pnl, "");
271 assert_eq!(enriched_trade.pnl_usd, "");
272 assert_eq!(enriched_trade.holding_duration, 0);
273 }
274
275 #[test]
276 fn test_enriched_trade_serialization() {
277 let enriched_trade = EnrichedTrade {
278 symbol: "ETH/USD".to_string(),
279 is_buy: false,
280 is_taker: true,
281 price: "2000.0".to_string(),
282 amount: "0.5".to_string(),
283 quote_amount: "1000.0".to_string(),
284 trade_id: "def-456".to_string(),
285 event_at: 1678887100,
286 transaction_id: "ext-uvw".to_string(),
287 wallet_address: "0x67890".to_string(),
288 market_type: MarketType::Spot as i32,
289 pnl: "-50.0".to_string(),
290 pnl_usd: "-50.0".to_string(),
291 holding_duration: 7200,
292 };
293
294 let mut buf = Vec::new();
295 enriched_trade.encode(&mut buf).unwrap();
296 let deserialized_enriched_trade = EnrichedTrade::decode(&buf[..]).unwrap();
297
298 assert_eq!(deserialized_enriched_trade.symbol, "ETH/USD");
299 assert!(!deserialized_enriched_trade.is_buy);
300 assert!(deserialized_enriched_trade.is_taker);
301 assert_eq!(deserialized_enriched_trade.price, "2000.0");
302 assert_eq!(deserialized_enriched_trade.amount, "0.5");
303 assert_eq!(deserialized_enriched_trade.quote_amount, "1000.0");
304 assert_eq!(deserialized_enriched_trade.trade_id, "def-456");
305 assert_eq!(deserialized_enriched_trade.event_at, 1678887100);
306 assert_eq!(deserialized_enriched_trade.transaction_id, "ext-uvw");
307 assert_eq!(deserialized_enriched_trade.wallet_address, "0x67890");
308 assert_eq!(deserialized_enriched_trade.market_type, MarketType::Spot as i32);
309 assert_eq!(deserialized_enriched_trade.pnl, "-50.0");
310 assert_eq!(deserialized_enriched_trade.pnl_usd, "-50.0");
311 assert_eq!(deserialized_enriched_trade.holding_duration, 7200);
312 }
313
314 #[test]
315 fn test_create_enriched_trade_zero_values() {
316 let enriched_trade = EnrichedTrade {
317 price: "0.0".to_string(),
318 amount: "0.0".to_string(),
319 quote_amount: "0.0".to_string(),
320 transaction_id: "".to_string(),
321 wallet_address: "".to_string(),
322 market_type: MarketType::Perp as i32,
323 pnl: "0.0".to_string(),
324 pnl_usd: "0.0".to_string(),
325 holding_duration: 0,
326 ..Default::default()
327 };
328 assert_eq!(enriched_trade.price, "0.0");
329 assert_eq!(enriched_trade.amount, "0.0");
330 assert_eq!(enriched_trade.quote_amount, "0.0");
331 assert_eq!(enriched_trade.transaction_id, "");
332 assert_eq!(enriched_trade.wallet_address, "");
333 assert_eq!(enriched_trade.pnl, "0.0");
334 assert_eq!(enriched_trade.pnl_usd, "0.0");
335 assert_eq!(enriched_trade.holding_duration, 0);
336 }
337
338 #[test]
339 fn test_create_position() {
340 let position = Position {
341 symbol: "BTC/USD".to_string(),
342 is_buy: true,
343 average_price: "50000.0".to_string(),
344 amount: "0.1".to_string(),
345 quote_amount: "5000.0".to_string(),
346 wallet_address: "0x12345".to_string(),
347 market_type: MarketType::Perp as i32,
348 holding_duration: 3600,
349 };
350
351 assert_eq!(position.symbol, "BTC/USD");
352 assert!(position.is_buy);
353 assert_eq!(position.average_price, "50000.0");
354 assert_eq!(position.amount, "0.1");
355 assert_eq!(position.quote_amount, "5000.0");
356 assert_eq!(position.wallet_address, "0x12345");
357 assert_eq!(position.market_type, MarketType::Perp as i32);
358 assert_eq!(position.holding_duration, 3600);
359 }
360
361 #[test]
362 fn test_position_default_values() {
363 let position = Position::default();
364 assert_eq!(position.symbol, "");
365 assert!(!position.is_buy);
366 assert_eq!(position.average_price, "");
367 assert_eq!(position.amount, "");
368 assert_eq!(position.quote_amount, "");
369 assert_eq!(position.wallet_address, "");
370 assert_eq!(position.market_type, MarketType::Perp as i32);
371 assert_eq!(position.holding_duration, 0);
372 }
373
374 #[test]
375 fn test_position_serialization() {
376 let position = Position {
377 symbol: "ETH/USD".to_string(),
378 is_buy: false,
379 average_price: "2000.0".to_string(),
380 amount: "0.5".to_string(),
381 quote_amount: "1000.0".to_string(),
382 wallet_address: "0x67890".to_string(),
383 market_type: MarketType::Spot as i32,
384 holding_duration: 7200,
385 };
386
387 let mut buf = Vec::new();
388 position.encode(&mut buf).unwrap();
389 let deserialized_position = Position::decode(&buf[..]).unwrap();
390
391 assert_eq!(deserialized_position.symbol, "ETH/USD");
392 assert!(!deserialized_position.is_buy);
393 assert_eq!(deserialized_position.average_price, "2000.0");
394 assert_eq!(deserialized_position.amount, "0.5");
395 assert_eq!(deserialized_position.quote_amount, "1000.0");
396 assert_eq!(deserialized_position.wallet_address, "0x67890");
397 assert_eq!(deserialized_position.market_type, MarketType::Spot as i32);
398 assert_eq!(deserialized_position.holding_duration, 7200);
399 }
400
401 #[test]
402 fn test_create_position_zero_values() {
403 let position = Position {
404 average_price: "0.0".to_string(),
405 amount: "0.0".to_string(),
406 quote_amount: "0.0".to_string(),
407 wallet_address: "".to_string(),
408 market_type: MarketType::Perp as i32,
409 holding_duration: 0,
410 ..Default::default()
411 };
412 assert_eq!(position.average_price, "0.0");
413 assert_eq!(position.amount, "0.0");
414 assert_eq!(position.quote_amount, "0.0");
415 assert_eq!(position.wallet_address, "");
416 assert_eq!(position.holding_duration, 0);
417 }
418}