Increase test coverage.
This commit is contained in:
parent
936960ee3a
commit
bd9a314baa
@ -50,6 +50,7 @@ pub trait GetFunctionContext: Context {
|
||||
}*/
|
||||
|
||||
/// A context that returns `None` for each identifier.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct EmptyContext;
|
||||
|
||||
impl Context for EmptyContext {
|
||||
@ -150,20 +151,19 @@ macro_rules! context_map {
|
||||
|
||||
// The user has to specify a literal 'Function::new' in order to create a function
|
||||
( ($ctx:expr) $k:expr => Function::new($($v:tt)*) , $($tt:tt)*) => {{
|
||||
$ctx.set_function($k.into(), $crate::Function::new($($v)*))
|
||||
$crate::ContextWithMutableFunctions::set_function($ctx, $k.into(), $crate::Function::new($($v)*))
|
||||
.and($crate::context_map!(($ctx) $($tt)*))
|
||||
}};
|
||||
// add a value, and chain the eventual error with the ones in the next values
|
||||
( ($ctx:expr) $k:expr => $v:expr , $($tt:tt)*) => {{
|
||||
$ctx.set_value($k.into(), $v.into())
|
||||
$crate::ContextWithMutableVariables::set_value($ctx, $k.into(), $v.into())
|
||||
.and($crate::context_map!(($ctx) $($tt)*))
|
||||
}};
|
||||
|
||||
// Create a context, then recurse to add the values in it
|
||||
( $($tt:tt)* ) => {{
|
||||
use $crate::Context;
|
||||
let mut context = $crate::HashMapContext::new();
|
||||
$crate::context_map!((context) $($tt)*)
|
||||
$crate::context_map!((&mut context) $($tt)*)
|
||||
.map(|_| context)
|
||||
}};
|
||||
}
|
||||
}
|
@ -517,6 +517,7 @@ pub use crate::{
|
||||
operator::Operator,
|
||||
tree::Node,
|
||||
value::{value_type::ValueType, EmptyType, FloatType, IntType, TupleType, Value, EMPTY_VALUE},
|
||||
token::PartialToken,
|
||||
};
|
||||
|
||||
mod context;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![cfg(not(tarpaulin_include))]
|
||||
|
||||
use std::fmt::{Display, Error, Formatter};
|
||||
|
||||
use crate::operator::*;
|
||||
|
@ -53,22 +53,38 @@ pub enum Token {
|
||||
String(String),
|
||||
}
|
||||
|
||||
/// A partial token is an input character whose meaning depends on the characters around it.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum PartialToken {
|
||||
/// A partial token that unambiguously maps to a single token.
|
||||
Token(Token),
|
||||
/// A partial token that is a literal.
|
||||
Literal(String),
|
||||
/// A plus character '+'.
|
||||
Plus,
|
||||
/// A minus character '-'.
|
||||
Minus,
|
||||
/// A star character '*'.
|
||||
Star,
|
||||
/// A slash character '/'.
|
||||
Slash,
|
||||
/// A percent character '%'.
|
||||
Percent,
|
||||
/// A hat character '^'.
|
||||
Hat,
|
||||
/// A whitespace character, e.g. ' '.
|
||||
Whitespace,
|
||||
/// An equal-to character '='.
|
||||
Eq,
|
||||
/// An exclamation mark character '!'.
|
||||
ExclamationMark,
|
||||
/// A greater-than character '>'.
|
||||
Gt,
|
||||
/// A lower-than character '<'.
|
||||
Lt,
|
||||
/// An ampersand character '&'.
|
||||
Ampersand,
|
||||
/// A vertical bar character '|'.
|
||||
VerticalBar,
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
extern crate evalexpr;
|
||||
|
||||
use evalexpr::{error::*, *};
|
||||
|
||||
#[test]
|
||||
@ -764,3 +762,45 @@ fn test_type_errors_in_binary_operators() {
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_context() {
|
||||
let context = EmptyContext;
|
||||
assert_eq!(context.get_value("abc"), None);
|
||||
assert_eq!(context.call_function("abc", &Value::Empty), Err(EvalexprError::FunctionIdentifierNotFound("abc".to_owned())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hashmap_context_type_safety() {
|
||||
let mut context = context_map! {"a" => 5, "b" => 5.0}.unwrap();
|
||||
assert_eq!(eval_with_context_mut("a = 4", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("a = 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(4.0)}));
|
||||
assert_eq!(eval_with_context_mut("a += 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(8.0)}));
|
||||
assert_eq!(eval_with_context_mut("a -= 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(0.0)}));
|
||||
assert_eq!(eval_with_context_mut("a *= 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(16.0)}));
|
||||
assert_eq!(eval_with_context_mut("a /= 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(1.0)}));
|
||||
assert_eq!(eval_with_context_mut("a %= 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(0.0)}));
|
||||
assert_eq!(eval_with_context_mut("a ^= 4.0", &mut context), Err(EvalexprError::ExpectedInt {actual: Value::Float(256.0)}));
|
||||
|
||||
assert_eq!(eval_with_context_mut("b = 4.0", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("b = 4", &mut context), Err(EvalexprError::ExpectedFloat {actual: Value::Int(4)}));
|
||||
assert_eq!(eval_with_context_mut("b += 4", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("b -= 4", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("b *= 4", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("b /= 4", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("b %= 4", &mut context), Ok(Value::Empty));
|
||||
assert_eq!(eval_with_context_mut("b ^= 4", &mut context), Ok(Value::Empty));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_constructors() {
|
||||
assert_eq!(eval("a = true + \"4\""), Err(EvalexprError::ExpectedNumberOrString { actual: Value::Boolean(true) }));
|
||||
assert_eq!(eval("a = true && \"4\""), Err(EvalexprError::ExpectedBoolean { actual: Value::from("4") }));
|
||||
assert_eq!(eval_tuple("4"), Err(EvalexprError::ExpectedTuple { actual: Value::Int(4) }));
|
||||
assert_eq!(Value::Tuple(vec![Value::Int(4), Value::Int(5)]).as_fixed_len_tuple(3), Err(EvalexprError::ExpectedFixedLenTuple { expected_len: 3, actual: Value::Tuple(vec![Value::Int(4), Value::Int(5)]) }));
|
||||
assert_eq!(eval_empty("4"), Err(EvalexprError::ExpectedEmpty {actual: Value::Int(4)}));
|
||||
assert_eq!(eval("&"), Err(EvalexprError::UnmatchedPartialToken { first: PartialToken::Ampersand, second: None }));
|
||||
|
||||
assert_eq!(expect_function_argument_amount(2, 2), Ok(()));
|
||||
assert_eq!(expect_function_argument_amount(2, 3), Err(EvalexprError::WrongFunctionArgumentAmount { expected: 3, actual: 2 }));
|
||||
}
|
@ -12,3 +12,10 @@ fn test_serde() {
|
||||
assert_eq!(manual_tree.eval(), serde_tree.eval());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_serde_errors() {
|
||||
assert_eq!(ron::de::from_str::<Node>("[\"5==5\"]"), Err(ron::de::Error::Parser(ron::de::ParseError::ExpectedString, ron::de::Position{col:1,line:1})));
|
||||
assert_eq!(ron::de::from_str::<Node>("\"&\""), Err(ron::de::Error::Message("Found a partial token '&' that should be followed by another partial token.".to_owned())));
|
||||
}
|
Loading…
Reference in New Issue
Block a user