use crate::{Effect, Eval, Script};
#[test]
fn add() {
let script = Script::compile("1 2 +");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[3]);
}
#[test]
fn add_wraps_on_signed_overflow() {
let script = Script::compile("2147483647 1 +");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[-2147483648]);
}
#[test]
fn add_wraps_on_unsigned_overflow() {
let script = Script::compile("-1 1 +");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[0]);
}
#[test]
fn subtract() {
let script = Script::compile("2 1 -");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[1]);
}
#[test]
fn subtract_wraps_on_signed_overflow() {
let script = Script::compile("-2147483648 1 -");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[2147483647]);
}
#[test]
fn subtract_wraps_on_unsigned_overflow() {
let script = Script::compile("0 1 -");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[-1]);
}
#[test]
fn multiply() {
let script = Script::compile("2 3 *");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[6]);
}
#[test]
fn multiply_wraps_on_signed_overflow() {
let script = Script::compile("2147483647 2 *");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[-2]);
}
#[test]
fn multiply_wraps_on_unsigned_overflow() {
let script = Script::compile("-1 2 *");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[-2]);
}
#[test]
fn divide() {
let script = Script::compile("5 2 /");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[2, 1]);
}
#[test]
fn divide_treats_its_inputs_as_signed() {
let script = Script::compile("5 -2 /");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::OutOfOperators);
assert_eq!(eval.operand_stack.to_i32_slice(), &[-2, 1]);
}
#[test]
fn divide_by_zero_triggers_effect() {
let script = Script::compile("1 0 /");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::DivisionByZero);
assert_eq!(eval.operand_stack.to_i32_slice(), &[]);
}
#[test]
fn divide_triggers_effect_on_overflow() {
let script = Script::compile("-2147483648 -1 /");
let mut eval = Eval::new();
let (effect, _) = eval.run(&script);
assert_eq!(effect, Effect::IntegerOverflow);
assert_eq!(eval.operand_stack.to_i32_slice(), &[]);
}