2019-05-14 01:13:28 +00:00
|
|
|
use super::*;
|
2019-05-24 03:57:24 +00:00
|
|
|
use compare_fields::{CompareFields, Comparison, FieldComparison};
|
2019-05-15 01:41:25 +00:00
|
|
|
use std::fmt::Debug;
|
2019-05-22 08:00:21 +00:00
|
|
|
use types::BeaconState;
|
2019-05-14 01:13:28 +00:00
|
|
|
|
2019-05-22 06:46:50 +00:00
|
|
|
pub const MAX_VALUE_STRING_LEN: usize = 500;
|
|
|
|
|
2019-05-14 01:13:28 +00:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2019-05-15 01:27:22 +00:00
|
|
|
pub struct CaseResult {
|
2019-05-14 01:13:28 +00:00
|
|
|
pub case_index: usize,
|
|
|
|
pub desc: String,
|
|
|
|
pub result: Result<(), Error>,
|
|
|
|
}
|
|
|
|
|
2019-05-15 01:27:22 +00:00
|
|
|
impl CaseResult {
|
2019-05-23 06:55:50 +00:00
|
|
|
pub fn new(case_index: usize, case: &impl Case, result: Result<(), Error>) -> Self {
|
2019-05-15 01:27:22 +00:00
|
|
|
CaseResult {
|
2019-05-14 01:13:28 +00:00
|
|
|
case_index,
|
2019-05-23 06:55:50 +00:00
|
|
|
desc: case.description(),
|
2019-05-14 01:13:28 +00:00
|
|
|
result,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-22 08:00:21 +00:00
|
|
|
/// Same as `compare_result_detailed`, however it drops the caches on both states before
|
|
|
|
/// comparison.
|
|
|
|
pub fn compare_beacon_state_results_without_caches<T: EthSpec, E: Debug>(
|
|
|
|
result: &mut Result<BeaconState<T>, E>,
|
|
|
|
expected: &mut Option<BeaconState<T>>,
|
|
|
|
) -> Result<(), Error> {
|
|
|
|
match (result.as_mut(), expected.as_mut()) {
|
|
|
|
(Ok(ref mut result), Some(ref mut expected)) => {
|
|
|
|
result.drop_all_caches();
|
|
|
|
expected.drop_all_caches();
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
};
|
|
|
|
|
|
|
|
compare_result_detailed(&result, &expected)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Same as `compare_result`, however utilizes the `CompareFields` trait to give a list of
|
|
|
|
/// mismatching fields when `Ok(result) != Some(expected)`.
|
|
|
|
pub fn compare_result_detailed<T, E>(
|
|
|
|
result: &Result<T, E>,
|
|
|
|
expected: &Option<T>,
|
|
|
|
) -> Result<(), Error>
|
|
|
|
where
|
|
|
|
T: PartialEq<T> + Debug + CompareFields,
|
|
|
|
E: Debug,
|
|
|
|
{
|
|
|
|
match (result, expected) {
|
|
|
|
(Ok(result), Some(expected)) => {
|
2019-05-24 03:57:24 +00:00
|
|
|
let mut mismatching_fields: Vec<Comparison> = expected
|
2019-05-22 08:00:21 +00:00
|
|
|
.compare_fields(result)
|
|
|
|
.into_iter()
|
2019-05-24 03:57:24 +00:00
|
|
|
// Filter all out all fields that are equal.
|
|
|
|
.filter(Comparison::not_equal)
|
2019-05-22 08:00:21 +00:00
|
|
|
.collect();
|
|
|
|
|
2019-05-24 03:57:24 +00:00
|
|
|
mismatching_fields
|
|
|
|
.iter_mut()
|
|
|
|
.for_each(|f| f.retain_children(FieldComparison::not_equal));
|
|
|
|
|
2019-05-22 08:00:21 +00:00
|
|
|
if !mismatching_fields.is_empty() {
|
|
|
|
Err(Error::NotEqual(format!(
|
2019-05-23 06:55:50 +00:00
|
|
|
"Fields not equal (a = expected, b = result): {:#?}",
|
2019-05-22 08:00:21 +00:00
|
|
|
mismatching_fields
|
|
|
|
)))
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => compare_result(result, expected),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-14 01:13:28 +00:00
|
|
|
/// Compares `result` with `expected`.
|
|
|
|
///
|
|
|
|
/// If `expected.is_none()` then `result` is expected to be `Err`. Otherwise, `T` in `result` and
|
|
|
|
/// `expected` must be equal.
|
2019-05-14 23:50:05 +00:00
|
|
|
pub fn compare_result<T, E>(result: &Result<T, E>, expected: &Option<T>) -> Result<(), Error>
|
2019-05-14 01:13:28 +00:00
|
|
|
where
|
|
|
|
T: PartialEq<T> + Debug,
|
|
|
|
E: Debug,
|
|
|
|
{
|
|
|
|
match (result, expected) {
|
|
|
|
// Pass: The should have failed and did fail.
|
|
|
|
(Err(_), None) => Ok(()),
|
|
|
|
// Fail: The test failed when it should have produced a result (fail).
|
|
|
|
(Err(e), Some(expected)) => Err(Error::NotEqual(format!(
|
2019-05-22 06:46:50 +00:00
|
|
|
"Got {:?} | Expected {:?}",
|
|
|
|
e,
|
|
|
|
fmt_val(expected)
|
2019-05-14 01:13:28 +00:00
|
|
|
))),
|
|
|
|
// Fail: The test produced a result when it should have failed (fail).
|
2019-05-22 06:46:50 +00:00
|
|
|
(Ok(result), None) => Err(Error::DidntFail(format!("Got {:?}", fmt_val(result)))),
|
2019-05-14 01:13:28 +00:00
|
|
|
// Potential Pass: The test should have produced a result, and it did.
|
|
|
|
(Ok(result), Some(expected)) => {
|
|
|
|
if result == expected {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(Error::NotEqual(format!(
|
2019-05-22 06:46:50 +00:00
|
|
|
"Got {:?} | Expected {:?}",
|
|
|
|
fmt_val(result),
|
|
|
|
fmt_val(expected)
|
2019-05-14 01:13:28 +00:00
|
|
|
)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-22 06:46:50 +00:00
|
|
|
|
|
|
|
fn fmt_val<T: Debug>(val: T) -> String {
|
|
|
|
let mut string = format!("{:?}", val);
|
|
|
|
string.truncate(MAX_VALUE_STRING_LEN);
|
|
|
|
string
|
|
|
|
}
|