Move ssz_generic tests into own file

This commit is contained in:
Paul Hauner
2019-05-14 09:36:25 +10:00
parent 1f6e393ff0
commit 55ff1e0b40
3 changed files with 73 additions and 64 deletions

View File

@@ -5,7 +5,10 @@ use ssz::Decode;
use std::fmt::Debug;
use test_decode::TestDecode;
pub use crate::ssz_generic::*;
mod error;
mod ssz_generic;
mod test_decode;
#[derive(Debug, Deserialize)]
@@ -20,15 +23,6 @@ pub struct TestDoc<T> {
pub test_cases: Vec<T>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct SszGenericCase {
#[serde(alias = "type")]
pub type_name: String,
pub valid: bool,
pub value: String,
pub ssz: Option<String>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct TestCaseResult<T> {
pub case_index: usize,
@@ -40,59 +34,10 @@ pub trait Test<T> {
fn test(&self) -> Vec<TestCaseResult<T>>;
}
impl Test<SszGenericCase> for TestDoc<SszGenericCase> {
fn test(&self) -> Vec<TestCaseResult<SszGenericCase>> {
self.test_cases
.iter()
.enumerate()
.map(|(i, tc)| {
let result = if let Some(ssz) = &tc.ssz {
match tc.type_name.as_ref() {
"uint8" => compare_decoding::<u8>(tc.valid, ssz, &tc.value),
"uint16" => compare_decoding::<u16>(tc.valid, ssz, &tc.value),
"uint32" => compare_decoding::<u32>(tc.valid, ssz, &tc.value),
"uint64" => compare_decoding::<u64>(tc.valid, ssz, &tc.value),
"uint128" => compare_decoding::<U128>(tc.valid, ssz, &tc.value),
"uint256" => compare_decoding::<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(())
};
TestCaseResult {
case_index: i,
case: tc.clone(),
result,
}
})
.collect()
}
}
fn compare_decoding<T>(should_be_ok: bool, ssz: &String, value: &String) -> Result<(), Error>
where
T: Decode + TestDecode + Debug + PartialEq<T>,
{
let ssz = hex::decode(&ssz[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
let expected = if should_be_ok {
Some(T::test_decode(value)?)
} else {
None
};
let decoded = T::from_ssz_bytes(&ssz);
compare_result(decoded, expected)
}
/// Compares `result` with `expected`.
///
/// If `expected.is_none()` then `result` is expected to be `Err`. Otherwise, `T` in `result` and
/// `expected` must be equal.
fn compare_result<T, E>(result: Result<T, E>, expected: Option<T>) -> Result<(), Error>
where
T: PartialEq<T> + Debug,

View File

@@ -0,0 +1,64 @@
use super::*;
#[derive(Debug, Clone, Deserialize)]
pub struct SszGeneric {
#[serde(alias = "type")]
pub type_name: String,
pub valid: bool,
pub value: String,
pub ssz: Option<String>,
}
impl Test<SszGeneric> for TestDoc<SszGeneric> {
fn test(&self) -> Vec<TestCaseResult<SszGeneric>> {
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(())
};
TestCaseResult {
case_index: i,
case: tc.clone(),
result,
}
})
.collect()
}
}
/// Execute a `ssz_generic` test case.
fn ssz_generic_test<T>(should_be_ok: bool, ssz: &String, value: &String) -> Result<(), Error>
where
T: Decode + TestDecode + Debug + PartialEq<T>,
{
let ssz = hex::decode(&ssz[2..]).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
let expected = if should_be_ok {
Some(T::test_decode(value)?)
} else {
None
};
let decoded = T::from_ssz_bytes(&ssz);
compare_result(decoded, expected)
}