use serde::{Serialize, de::DeserializeOwned};
use super::{
generated::types as spec,
types::{AppDataObject, Auction, CompetitionAuction, InteractionData, Trade},
};
fn roundtrip<T: Serialize, G: DeserializeOwned>(label: &str, value: &T) -> G {
let json = serde_json::to_value(value)
.unwrap_or_else(|e| panic!("{label}: failed to serialise hand-written value: {e}"));
serde_json::from_value::<G>(json.clone()).unwrap_or_else(|e| {
panic!(
"{label}: hand-written value is not wire-compatible with generated type.\n\
Deserialisation error: {e}\n\
Emitted JSON: {json}"
)
})
}
#[test]
fn trade_is_wire_compatible() {
let trade = Trade {
block_number: 18_123_456,
log_index: 42,
order_uid: format!("0x{}", "ab".repeat(56)),
owner: "0xb6bad41ae76a11d10f7b0e664c5007b908bc77c9".to_owned(),
sell_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_owned(),
buy_token: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48".to_owned(),
sell_amount: "1000000000000000000".to_owned(),
sell_amount_before_fees: "995000000000000000".to_owned(),
buy_amount: "2450000000".to_owned(),
tx_hash: Some(
"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20".to_owned(),
),
};
let _: spec::Trade = roundtrip("Trade", &trade);
}
#[test]
fn interaction_data_is_wire_compatible() {
let interaction = InteractionData {
target: "0xb6bad41ae76a11d10f7b0e664c5007b908bc77c9".parse().unwrap(),
value: "0".to_owned(),
call_data: "0xdeadbeef".to_owned(),
};
let _: spec::InteractionData = roundtrip("InteractionData", &interaction);
}
#[test]
fn total_surplus_is_wire_compatible() {
let surplus = super::types::TotalSurplus::new("12345678901234567890");
let _: spec::TotalSurplus = roundtrip("TotalSurplus", &surplus);
}
#[test]
fn app_data_object_is_wire_compatible() {
let obj = AppDataObject::new(r#"{"version":"1.6.0","metadata":{}}"#);
let emitted = serde_json::to_value(&obj).expect("serialise AppDataObject");
assert!(
emitted.get("fullAppData").is_some(),
"AppDataObject must emit a `fullAppData` field for wire compatibility"
);
}
#[test]
fn auction_envelope_is_wire_compatible() {
let auction = Auction {
id: Some(7),
block: 18_000_000,
orders: Vec::new(),
prices: foldhash::HashMap::default(),
};
let json = serde_json::to_value(&auction).expect("serialise Auction");
assert_eq!(json.get("block"), Some(&serde_json::Value::from(18_000_000_u64)));
assert!(
json.get("orders").is_some_and(serde_json::Value::is_array),
"Auction must emit `orders` as a JSON array"
);
assert_eq!(json.get("id"), Some(&serde_json::Value::from(7_i64)));
}
#[test]
fn competition_auction_is_wire_compatible() {
let mut prices = foldhash::HashMap::default();
prices.insert(
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_owned(),
"1000000000000000000".to_owned(),
);
let ca = CompetitionAuction { orders: vec![format!("0x{}", "11".repeat(56))], prices };
let _: spec::CompetitionAuction = roundtrip("CompetitionAuction", &ca);
}