diff --git a/src/main.rs b/src/main.rs index 2b2f784..b3974d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,3 +30,54 @@ fn main() { buffer.clear(); } } + + +#[cfg(test)] +mod tests { + use crate::*; + + fn calc(task: &str) -> i32 { + return eval(to_rpn(tokenizer(task))); + } + + #[test] + fn alg_order() { + assert_eq!(calc("2 + 3 * 4"), 14); + } + + #[test] + fn left_sub_assoc() { + assert_eq!(calc("8 - 4 - 2"), 2); + } + + #[test] + fn left_div_assoc() { + assert_eq!(calc("100 / 5 / 2"), 10); + } + + + #[test] + fn br_1() { + assert_eq!(calc("(2 + 3) * 4"), 20); + } + + #[test] + fn br_2() { + assert_eq!(calc("(3 + 5) * (2 - 1)"), 8); + } + + #[test] + fn br_3() { + assert_eq!(calc("(2 + (3 * (4 + 1)))"), 17); + } + + #[test] + fn br_4() { + assert_eq!(calc("((((1+2)+3)+4)+5)"), 15); + } + + #[test] + fn br_5() { + assert_eq!(calc("(1 + 2) * (3 + 4 * (5 + 6))"), 141); + } +} diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 24231b8..57bc7e4 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -47,3 +47,183 @@ pub fn tokenizer(task: &str) -> Vec { return tokens; } + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_addition() { + assert_eq!( + tokenizer("2+3"), + vec![Token::Number(2), Token::Addition, Token::Number(3)] + ); + } + + #[test] + fn test_subtraction() { + assert_eq!( + tokenizer("5-7"), + vec![Token::Number(5), Token::Substruction, Token::Number(7)] + ); + } + + #[test] + fn test_multiplication() { + assert_eq!( + tokenizer("4*9"), + vec![Token::Number(4), Token::Multiplication, Token::Number(9)] + ); + } + + #[test] + fn test_division() { + assert_eq!( + tokenizer("10/2"), + vec![Token::Number(10), Token::Division, Token::Number(2)] + ); + } + + #[test] + fn test_brackets() { + assert_eq!( + tokenizer("(1+2)"), + vec![ + Token::BracketOpen, + Token::Number(1), + Token::Addition, + Token::Number(2), + Token::BracketClose + ] + ); + } + + #[test] + fn test_nested_brackets() { + assert_eq!( + tokenizer("((3+4)*2)"), + vec![ + Token::BracketOpen, + Token::BracketOpen, + Token::Number(3), + Token::Addition, + Token::Number(4), + Token::BracketClose, + Token::Multiplication, + Token::Number(2), + Token::BracketClose + ] + ); + } + + #[test] + fn test_multidigit_numbers() { + assert_eq!( + tokenizer("123+456"), + vec![Token::Number(123), Token::Addition, Token::Number(456)] + ); + } + + #[test] + fn test_large_number_within_i32() { + assert_eq!( + tokenizer("2147483647"), + vec![Token::Number(2147483647)] + ); + } + + #[test] + #[should_panic(expected = "attempt to parse integer")] + fn test_number_out_of_i32_range() { + tokenizer("2147483648"); + } + + #[test] + fn test_ignore_spaces() { + assert_eq!( + tokenizer(" 1 + 2 "), + vec![Token::Number(1), Token::Addition, Token::Number(2)] + ); + } + + #[test] + fn test_tabs_and_newlines_ignored() { + assert_eq!( + tokenizer("1\t+\n2"), + vec![Token::Number(1), Token::Addition, Token::Number(2)] + ); + } + + #[test] + fn test_unknown_characters_ignored() { + assert_eq!( + tokenizer("2@3?4"), + vec![Token::Number(2), Token::Number(3), Token::Number(4)] + ); + } + + #[test] + fn test_only_unknown_characters() { + assert_eq!(tokenizer("@#$%"), vec![]); + } + + #[test] + fn test_empty_string() { + assert_eq!(tokenizer(""), vec![]); + } + + #[test] + fn test_unary_minus() { + assert_eq!( + tokenizer("-5"), + vec![Token::Substruction, Token::Number(5)] + ); + } + + #[test] + fn test_expression_with_unary_minus() { + assert_eq!( + tokenizer("3+-2"), + vec![ + Token::Number(3), + Token::Addition, + Token::Substruction, + Token::Number(2) + ] + ); + } + + #[test] + fn test_consecutive_operators() { + assert_eq!( + tokenizer("5*-3"), + vec![ + Token::Number(5), + Token::Multiplication, + Token::Substruction, + Token::Number(3) + ] + ); + } + + #[test] + fn test_complex_expression_no_spaces() { + assert_eq!( + tokenizer("12+34*(56-78)/90"), + vec![ + Token::Number(12), + Token::Addition, + Token::Number(34), + Token::Multiplication, + Token::BracketOpen, + Token::Number(56), + Token::Substruction, + Token::Number(78), + Token::BracketClose, + Token::Division, + Token::Number(90) + ] + ); + } +}