Lines
93.75 %
Functions
92.31 %
Branches
100 %
// Tests for MAP and MAP* family functions
// These tests verify that MAP, MAPCAR, MAPC work correctly
use nomiscript::{
Reader, eval_program,
runtime::{SymbolTable, Value},
};
use num_rational::Ratio;
fn eval_expr(code: &str) -> Result<Value, nomiscript::Error> {
let program = Reader::parse(code)?;
let mut symbols = SymbolTable::with_builtins();
eval_program(&mut symbols, &program)
}
fn num(n: i64) -> Value {
Value::Number(Ratio::from_integer(n))
#[cfg(test)]
mod map_function_tests {
use super::*;
#[test]
fn test_map_basic() {
let result = eval_expr("(map '+ '(1 2 3) '(10 20 30))").unwrap();
// Should return a list of sums: (11 22 33)
assert_eq!(result, Value::String("(11 22 33)".to_string()));
fn test_map_single_list() {
let result = eval_expr("(map 'car '((1 2) (3 4) (5 6)))").unwrap();
// Should return (1 3 5)
assert_eq!(result, Value::String("(1 3 5)".to_string()));
fn test_map_empty_list() {
let result = eval_expr("(map '+ '())").unwrap();
// Should return empty list
assert_eq!(result, Value::String("()".to_string()));
fn test_map_unequal_length_lists() {
let result = eval_expr("(map '+ '(1 2 3) '(10 20))").unwrap();
// Should process only 2 elements (shortest list)
assert_eq!(result, Value::String("(11 22)".to_string()));
fn test_map_wrong_arity() {
let result = eval_expr("(map '+)");
assert!(
result.is_err(),
"MAP with insufficient arguments should fail"
);
fn test_map_non_list_argument() {
let result = eval_expr("(map '+ 42)");
assert!(result.is_err(), "MAP with non-list argument should fail");
mod mapcar_macro_tests {
fn test_mapcar_basic() {
let result = eval_expr("(mapcar '+ '(1 2 3))");
match &result {
Err(e) => println!("Error: {e:?}"),
Ok(v) => println!("Result: {v:?}"),
assert!(result.is_ok(), "MAPCAR should work as alias for MAP");
fn test_mapcar_with_lambda() {
let code = r"
(mapcar (lambda (x) (* x 2)) '(1 2 3 4))
";
let result = eval_expr(code);
assert!(result.is_ok(), "MAPCAR with lambda should work");
fn test_mapcar_multiple_lists() {
let result = eval_expr("(mapcar '+ '(1 2) '(10 20))");
assert!(result.is_ok(), "MAPCAR with multiple lists should work");
mod mapc_macro_tests {
fn test_mapc_basic() {
let result = eval_expr("(mapc 'car '((1 2) (3 4)))");
assert!(result.is_ok(), "MAPC should work for side effects");
// MAPC should return the original list
fn test_mapc_side_effects() {
let _code = r"
(let ((counter 0))
(mapc (lambda (x) (setq counter (+ counter 1))) '(a b c))
counter)
// This test would work if we had SETQ implemented
// For now just test that MAPC doesn't error
assert!(result.is_ok(), "MAPC should execute without error");