mod eval_tests { use relish::ast::{eval, lex, SYM_TABLE}; use relish::ast::{Args, Symbol, Ctr, Seg, ValueType, UserFn}; // TODO: write generalized testing routine on top of list of inputs #[test] fn eval_singlet() { let test_doc = "(1)".to_string(); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(ref initial_ast) => match eval(initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), test_doc) } }, } } #[test] fn eval_embedded_lists_no_funcs() { let test_doc = "(1 (1 2 3 4 5) 5)".to_string(); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), test_doc) } }, } } #[test] fn eval_function_call() { let test_doc = "('one' (echo 'unwrap_me'))".to_string(); let output = "('one' 'unwrap_me')"; { // we want the write lock to expire before eval let mut table_handle = SYM_TABLE.write().unwrap(); let test_external_func: Symbol = Symbol { name: String::from("echo"), args: Args::Lazy(1), has_undefined_symbols: false, value: ValueType::FuncForm( UserFn { arg_syms: vec!["input".to_string()], ast: Box::new(Seg::from( Box::new(Ctr::Seg(Seg::from( Box::from(Ctr::Symbol("input".to_string())), Box::from(Ctr::None)))), Box::new(Ctr::None), )), }), }; table_handle.insert(String::from("echo"), test_external_func); } match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), output) } }, } } #[test] fn eval_embedded_func_calls() { let test_doc = "('one' (echo (echo 'unwrap_me')))".to_string(); let output = "('one' 'unwrap_me')"; { let mut table_handle = SYM_TABLE.write().unwrap(); let test_external_func: Symbol = Symbol{ name: String::from("echo"), args: Args::Lazy(1), has_undefined_symbols: false, value: ValueType::FuncForm( UserFn { arg_syms: vec!["input".to_string()], ast: Box::new(Seg::from( Box::new(Ctr::Seg(Seg::from( Box::from(Ctr::Symbol("input".to_string())), Box::from(Ctr::None)))), Box::new(Ctr::None), )), }), }; table_handle.insert(String::from("echo"), test_external_func); } match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), output) } }, } } /* #[test] fn eval_bad_vars() { } #[test] fn eval_bad_func() { } #[test] fn eval_verify_all_elems_cloned() { }*/ }