1
// Tests for DOLIST special form
2
// These tests verify that DOLIST works correctly for list iteration
3

            
4
use nomiscript::{
5
    Reader, eval_program,
6
    runtime::{SymbolTable, Value},
7
};
8
use num_rational::Ratio;
9

            
10
8
fn eval_expr(code: &str) -> Result<Value, nomiscript::Error> {
11
8
    let program = Reader::parse(code)?;
12
8
    let mut symbols = SymbolTable::with_builtins();
13
8
    eval_program(&mut symbols, &program)
14
8
}
15

            
16
fn num(n: i64) -> Value {
17
    Value::Number(Ratio::from_integer(n))
18
}
19

            
20
#[cfg(test)]
21
mod dolist_basic_tests {
22
    use super::*;
23

            
24
    #[test]
25
1
    fn test_dolist_basic() {
26
1
        let result = eval_expr("(dolist (x '(1 2 3)) nil)");
27
1
        match &result {
28
            Err(e) => println!("Error: {e:?}"),
29
1
            Ok(v) => println!("Result: {v:?}"),
30
        }
31
1
        assert!(result.is_ok(), "Basic DOLIST should work");
32
1
        assert_eq!(result.unwrap(), Value::Nil);
33
1
    }
34

            
35
    #[test]
36
1
    fn test_dolist_with_result() {
37
1
        let result = eval_expr("(dolist (x '(1 2 3) 42) nil)");
38
1
        assert!(result.is_ok(), "DOLIST with result expression should work");
39
1
    }
40

            
41
    #[test]
42
1
    fn test_dolist_empty_list() {
43
1
        let result = eval_expr("(dolist (x '()) 'done)");
44
1
        assert!(result.is_ok(), "DOLIST with empty list should work");
45
1
    }
46

            
47
    #[test]
48
1
    fn test_dolist_nil_list() {
49
1
        let result = eval_expr("(dolist (x nil) 'done)");
50
1
        assert!(result.is_ok(), "DOLIST with nil list should work");
51
1
    }
52

            
53
    #[test]
54
1
    fn test_dolist_wrong_arity() {
55
1
        let result = eval_expr("(dolist)");
56
1
        assert!(result.is_err(), "DOLIST with no arguments should fail");
57
1
    }
58

            
59
    #[test]
60
1
    fn test_dolist_invalid_var_spec() {
61
1
        let result = eval_expr("(dolist x nil)");
62
1
        assert!(
63
1
            result.is_err(),
64
            "DOLIST with invalid variable spec should fail"
65
        );
66
1
    }
67

            
68
    #[test]
69
1
    fn test_dolist_var_not_symbol() {
70
1
        let result = eval_expr("(dolist (42 '(1 2 3)) nil)");
71
1
        assert!(
72
1
            result.is_err(),
73
            "DOLIST with non-symbol variable should fail"
74
        );
75
1
    }
76

            
77
    #[test]
78
1
    fn test_dolist_non_list_expression() {
79
1
        let result = eval_expr("(dolist (x 42) nil)");
80
1
        assert!(
81
1
            result.is_err(),
82
            "DOLIST with non-list expression should fail"
83
        );
84
1
    }
85
}