From 55ff1e0b408da6e80ba706e0a92fe5af438ee133 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 14 May 2019 09:36:25 +1000 Subject: [PATCH] Move ssz_generic tests into own file --- tests/ef_tests/src/lib.rs | 69 ++++--------------------------- tests/ef_tests/src/ssz_generic.rs | 64 ++++++++++++++++++++++++++++ tests/ef_tests/tests/tests.rs | 4 +- 3 files changed, 73 insertions(+), 64 deletions(-) create mode 100644 tests/ef_tests/src/ssz_generic.rs diff --git a/tests/ef_tests/src/lib.rs b/tests/ef_tests/src/lib.rs index a4093cf2c..19df3754c 100644 --- a/tests/ef_tests/src/lib.rs +++ b/tests/ef_tests/src/lib.rs @@ -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 { pub test_cases: Vec, } -#[derive(Debug, Clone, Deserialize)] -pub struct SszGenericCase { - #[serde(alias = "type")] - pub type_name: String, - pub valid: bool, - pub value: String, - pub ssz: Option, -} - #[derive(Debug, PartialEq, Clone)] pub struct TestCaseResult { pub case_index: usize, @@ -40,59 +34,10 @@ pub trait Test { fn test(&self) -> Vec>; } -impl Test for TestDoc { - fn test(&self) -> Vec> { - 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::(tc.valid, ssz, &tc.value), - "uint16" => compare_decoding::(tc.valid, ssz, &tc.value), - "uint32" => compare_decoding::(tc.valid, ssz, &tc.value), - "uint64" => compare_decoding::(tc.valid, ssz, &tc.value), - "uint128" => compare_decoding::(tc.valid, ssz, &tc.value), - "uint256" => compare_decoding::(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(should_be_ok: bool, ssz: &String, value: &String) -> Result<(), Error> -where - T: Decode + TestDecode + Debug + PartialEq, -{ - 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(result: Result, expected: Option) -> Result<(), Error> where T: PartialEq + Debug, diff --git a/tests/ef_tests/src/ssz_generic.rs b/tests/ef_tests/src/ssz_generic.rs new file mode 100644 index 000000000..fbd307169 --- /dev/null +++ b/tests/ef_tests/src/ssz_generic.rs @@ -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, +} + +impl Test for TestDoc { + fn test(&self) -> Vec> { + 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::(tc.valid, ssz, &tc.value), + "uint16" => ssz_generic_test::(tc.valid, ssz, &tc.value), + "uint32" => ssz_generic_test::(tc.valid, ssz, &tc.value), + "uint64" => ssz_generic_test::(tc.valid, ssz, &tc.value), + "uint128" => ssz_generic_test::(tc.valid, ssz, &tc.value), + "uint256" => ssz_generic_test::(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(should_be_ok: bool, ssz: &String, value: &String) -> Result<(), Error> +where + T: Decode + TestDecode + Debug + PartialEq, +{ + 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) +} diff --git a/tests/ef_tests/tests/tests.rs b/tests/ef_tests/tests/tests.rs index 3f954da08..e62c16c28 100644 --- a/tests/ef_tests/tests/tests.rs +++ b/tests/ef_tests/tests/tests.rs @@ -19,11 +19,11 @@ fn load_test_case(test_name: &str) -> TestDoc { #[test] fn ssz() { - let doc: TestDoc = load_test_case("ssz_generic/uint/uint_bounds.yaml"); + let doc: TestDoc = load_test_case("ssz_generic/uint/uint_bounds.yaml"); let results = doc.test(); - let failures: Vec<&TestCaseResult> = + let failures: Vec<&TestCaseResult> = results.iter().filter(|r| r.result.is_err()).collect(); if !failures.is_empty() {