// Copyright 2017 Kyle Mayes // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #[macro_use] extern crate dice; use dice::syntax; use dice::{Binary, Expression, Fold, Reroll}; macro_rules! parse { ($string:expr) => ({ match syntax::parse($string) { Ok(expression) => expression, Err(error) => panic!("{}", error), } }); } macro_rules! assert_parse_eq { ($string:expr, $($tt:tt)*) => ({ assert_eq!(parse!($string), Expression::$($tt)*); }); } #[test] fn test_parse_ok() { use Binary::*; use Expression::*; use Fold::*; assert_parse_eq!("24", Constant(24)); assert_parse_eq!("d12", Die(d!(12), None)); assert_parse_eq!("d12 reroll 2", Die(d!(12), Some(Reroll::new(2)))); assert_parse_eq!("2d6", Dice(d!(2, 6), None, Sum)); assert_parse_eq!("2d6 drop minimum", Dice(d!(2, 6), None, DropMinimum)); assert_parse_eq!("2d6 drop maximum", Dice(d!(2, 6), None, DropMaximum)); assert_parse_eq!("2d6 minimum", Dice(d!(2, 6), None, Minimum)); assert_parse_eq!("2d6 maximum", Dice(d!(2, 6), None, Maximum)); assert_parse_eq!("2d6 reroll 2", Dice(d!(2, 6), Some(Reroll::new(2)), Sum)); assert_parse_eq!("2d6 reroll 2 drop minimum", Dice(d!(2, 6), Some(Reroll::new(2)), DropMinimum)); assert_parse_eq!("2d6 reroll 2 drop maximum", Dice(d!(2, 6), Some(Reroll::new(2)), DropMaximum)); assert_parse_eq!("2d6 reroll 2 minimum", Dice(d!(2, 6), Some(Reroll::new(2)), Minimum)); assert_parse_eq!("2d6 reroll 2 maximum", Dice(d!(2, 6), Some(Reroll::new(2)), Maximum)); macro_rules! b { ($b:expr, $l:expr, $r:expr) => (Box::new(Binary($b, $l, $r))); } macro_rules! c { ($c:expr) => (Box::new(Constant($c))); } let e = parse!("1 + 2 * 3 - 4"); assert_eq!(e, Binary(Subtract, b!(Add, c!(1), b!(Multiply, c!(2), c!(3))), c!(4))); let e = parse!("(1 + 2) * 3 - 4"); assert_eq!(e, Binary(Subtract, b!(Multiply, b!(Add, c!(1), c!(2)), c!(3)), c!(4))); let e = parse!("1 + 2 * (3 - 4)"); assert_eq!(e, Binary(Add, c!(1), b!(Multiply, c!(2), b!(Subtract, c!(3), c!(4))))); let e = parse!("(1 + 2) * (3 - 4)"); assert_eq!(e, Binary(Multiply, b!(Add, c!(1), c!(2)), b!(Subtract, c!(3), c!(4)))); } #[test] fn test_parse_err() { macro_rules! assert_error_eq { ($string:expr, $start:expr, $end:expr, $message:expr) => ({ let error = syntax::parse($string).unwrap_err(); assert_eq!(error.range.start, $start); assert_eq!(error.range.end, $end); assert_eq!(error.message, $message); }); } assert_error_eq!("", 0, 0, "expected `(`, `d`, or an integer"); assert_error_eq!("4294967296", 0, 10, "integer out of range"); assert_error_eq!("d", 1, 1, "expected non-zero integer"); assert_error_eq!("d0", 1, 2, "expected non-zero integer"); assert_error_eq!("d4294967296", 1, 11, "integer out of range"); assert_error_eq!("d12 reroll", 10, 10, "expected non-zero integer"); assert_error_eq!("d12 reroll 0", 11, 12, "expected non-zero integer"); assert_error_eq!("d12 reroll 4294967296", 11, 21, "integer out of range"); assert_error_eq!("0d6", 0, 1, "expected non-zero integer"); assert_error_eq!("4294967296d6", 0, 10, "integer out of range"); assert_error_eq!("2d6 sum", 4, 7, "expected `drop`, `minimum`, or `maximum`"); assert_error_eq!("2d6 drop", 8, 8, "expected `minimum` or `maximum`"); assert_error_eq!("2d6 drop sum", 9, 12, "expected `minimum` or `maximum`"); assert_error_eq!("24 24", 3, 5, "expected binary operator"); assert_error_eq!("d12 24", 4, 6, "expected binary operator"); assert_error_eq!("2d6 24", 4, 6, "expected binary operator"); assert_error_eq!("(1 + 2 * 3 - 4", 14, 14, "expected `)` or a binary operator"); }