1
//! Arithmetic edge cases beyond the basic `arithmetic_runtime` set:
2
//! constant folding of MOD, integer/ratio mix, division-by-zero
3
//! refusal, etc.
4

            
5
use super::common::{compile_and_validate, compile_expect_error, wrap_with_runtime_ratio};
6

            
7
#[test]
8
1
fn mod_constant_folds() {
9
1
    compile_and_validate("(mod 10 3)");
10
1
}
11

            
12
#[test]
13
1
fn mod_with_runtime_operand_errors() {
14
    // MOD currently refuses runtime args at compile time. Locks in the
15
    // "not yet supported" path so a future implementation either drops
16
    // the refusal or this test flips to compile_and_validate.
17
1
    let err = compile_expect_error(&wrap_with_runtime_ratio("(mod X 2)"));
18
1
    assert!(err.contains("MOD") || err.contains("runtime"), "got: {err}",);
19
1
}
20

            
21
#[test]
22
1
fn unary_negation_constant() {
23
1
    compile_and_validate("(- 5)");
24
1
}
25

            
26
#[test]
27
1
fn unary_negation_runtime() {
28
1
    compile_and_validate(&wrap_with_runtime_ratio("(- X)"));
29
1
}
30

            
31
#[test]
32
1
fn add_no_args_is_zero() {
33
1
    compile_and_validate("(+)");
34
1
}
35

            
36
#[test]
37
1
fn multiply_no_args_is_one() {
38
1
    compile_and_validate("(*)");
39
1
}
40

            
41
#[test]
42
1
fn single_arg_subtraction_is_negation() {
43
1
    compile_and_validate("(- 7)");
44
1
}
45

            
46
#[test]
47
1
fn nested_arithmetic_with_runtime() {
48
1
    compile_and_validate(&wrap_with_runtime_ratio("(+ (* (- X 1) 2) (/ X 4))"));
49
1
}
50

            
51
#[test]
52
1
fn division_by_zero_static_errors() {
53
1
    let err = compile_expect_error("(/ 1 0)");
54
1
    assert!(err.contains("zero") || err.contains("/"), "got: {err}");
55
1
}