82 lines
2.6 KiB
Rust
Raw Normal View History

2019-05-14 09:36:25 +10:00
use super::*;
2019-05-15 11:41:25 +10:00
use crate::case_result::compare_result;
use ethereum_types::{U128, U256};
use serde_derive::Deserialize;
use ssz::Decode;
use std::fmt::Debug;
2019-05-14 17:40:17 +10:00
use types::EthSpec;
2019-05-14 09:36:25 +10:00
#[derive(Debug, Clone, Deserialize)]
pub struct SszGeneric {
#[serde(alias = "type")]
pub type_name: String,
pub valid: bool,
2019-05-14 11:28:42 +10:00
pub value: Option<String>,
2019-05-14 09:36:25 +10:00
pub ssz: Option<String>,
}
2019-05-15 11:12:49 +10:00
impl YamlDecode for SszGeneric {
fn yaml_decode(yaml: &String) -> Result<Self, Error> {
2019-05-14 15:08:42 +10:00
Ok(serde_yaml::from_str(&yaml.as_str()).unwrap())
}
}
2019-05-15 11:27:22 +10:00
impl EfTest for Cases<SszGeneric> {
fn test_results<E: EthSpec>(&self) -> Vec<CaseResult> {
2019-05-14 09:36:25 +10:00
self.test_cases
.iter()
.enumerate()
.map(|(i, tc)| {
let result = if let Some(ssz) = &tc.ssz {
match tc.type_name.as_ref() {
"uint8" => ssz_generic_test::<u8>(tc.valid, ssz, &tc.value),
"uint16" => ssz_generic_test::<u16>(tc.valid, ssz, &tc.value),
"uint32" => ssz_generic_test::<u32>(tc.valid, ssz, &tc.value),
"uint64" => ssz_generic_test::<u64>(tc.valid, ssz, &tc.value),
"uint128" => ssz_generic_test::<U128>(tc.valid, ssz, &tc.value),
"uint256" => ssz_generic_test::<U256>(tc.valid, ssz, &tc.value),
_ => Err(Error::FailedToParseTest(format!(
"Unknown type: {}",
tc.type_name
))),
}
} else {
// Skip tests that do not have an ssz field.
//
// See: https://github.com/ethereum/eth2.0-specs/issues/1079
Ok(())
};
2019-05-15 11:27:22 +10:00
CaseResult::new(i, tc, result)
2019-05-14 09:36:25 +10:00
})
.collect()
}
}
/// Execute a `ssz_generic` test case.
2019-05-14 11:28:42 +10:00
fn ssz_generic_test<T>(
should_be_ok: bool,
ssz: &String,
value: &Option<String>,
) -> Result<(), Error>
2019-05-14 09:36:25 +10:00
where
2019-05-15 11:12:49 +10:00
T: Decode + YamlDecode + Debug + PartialEq<T>,
2019-05-14 09:36:25 +10:00
{
let ssz = hex::decode(&ssz[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
2019-05-14 11:28:42 +10:00
// We do not cater for the scenario where the test is valid but we are not passed any SSZ.
if should_be_ok && value.is_none() {
panic!("Unexpected test input. Cannot pass without value.")
}
let expected = if let Some(string) = value {
2019-05-15 11:12:49 +10:00
Some(T::yaml_decode(string)?)
2019-05-14 09:36:25 +10:00
} else {
None
};
let decoded = T::from_ssz_bytes(&ssz);
2019-05-15 09:50:05 +10:00
compare_result(&decoded, &expected)
2019-05-14 09:36:25 +10:00
}