use debugit::DebugIt;
use simulacrum_shared::Validator;
use constraint::{Constraint, ConstraintError, ConstraintResult};
pub struct Params<I> {
is_valid: bool,
received_param_msg: String,
validator: Box<Validator<I>>
}
impl<I> Params<I> {
pub fn new<V>(validator: V) -> Self where
V: Validator<I> + 'static
{
Params {
is_valid: true,
received_param_msg: "".to_owned(),
validator: Box::new(validator)
}
}
}
impl<I> Constraint<I> for Params<I> {
fn handle_call(&mut self, params: &I) {
if self.is_valid {
self.is_valid = self.validator.validate(params);
if !self.is_valid {
self.received_param_msg = format!("{:?}", DebugIt(params));
}
}
}
fn verify(&self) -> ConstraintResult {
if self.is_valid {
Ok(())
} else {
let expected_msg = self.validator.print();
let received_msg = self.received_param_msg.clone();
Err(ConstraintError::MismatchedParams(expected_msg, received_msg))
}
}
}
#[cfg(test)]
mod tests {
use simulacrum_user::*;
use super::*;
#[test]
fn test_new() {
let c = Params::new(none());
let r = <Constraint<()>>::verify(&c);
assert!(r.is_ok(), "Constraint should pass after being created");
}
#[test]
fn test_handle_call_pass() {
let mut c = Params::new(any());
c.handle_call(&());
let r = <Constraint<()>>::verify(&c);
assert!(r.is_ok(), "Constraint should pass");
}
#[test]
fn test_handle_call_fail() {
let mut c = Params::new(none());
c.handle_call(&());
let r = <Constraint<()>>::verify(&c);
assert!(r.is_err(), "Constraint should fail");
assert_eq!(r.unwrap_err(), ConstraintError::MismatchedParams("<Always Fails>".to_owned(), "()".to_owned()), "Constraint should return the correct error");
}
#[test]
fn test_handle_call_good_then_bad() {
let mut c = Params::new(passes(|arg| *arg > 5));
c.handle_call(&10); c.handle_call(&3); let r = <Constraint<i32>>::verify(&c);
assert!(r.is_err(), "Constraint should fail");
}
#[test]
fn test_handle_call_bad_then_good() {
let mut c = Params::new(passes(|arg| *arg > 5));
c.handle_call(&3); c.handle_call(&10); let r = <Constraint<i32>>::verify(&c);
assert!(r.is_err(), "Constraint should fail");
}
}