aboutsummaryrefslogtreecommitdiffstats
path: root/src/test.rs
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2021-11-23 22:11:53 +0200
committerJan Tuomi <jans.tuomi@gmail.com>2021-11-25 09:53:44 +0200
commit044af4cb2dcc4e7683ceff0ecbd18d4023647eda (patch)
treee3ecd7251444e6ed9908376a287589f05764da5a /src/test.rs
parent4bfaeda8039acc2a25891a778a51ae7dce1e0d32 (diff)
Add some tests
Diffstat (limited to 'src/test.rs')
-rw-r--r--src/test.rs148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/test.rs b/src/test.rs
new file mode 100644
index 0000000..58f9e84
--- /dev/null
+++ b/src/test.rs
@@ -0,0 +1,148 @@
+use super::*;
+use runtime::*;
+use serial_test::serial;
+use std::collections::HashMap;
+use std::rc::Rc;
+use std::sync::atomic::Ordering;
+
+fn evaluate_from_source(
+ content: String,
+ initial_symbol_table: Option<HashMap<String, Rc<Term>>>,
+) -> ProcessResult {
+ use ast::Program;
+ use pest::Parser;
+
+ let parse_tree_result = lparser::LParser::parse(lparser::Rule::program, &content);
+
+ if parse_tree_result.is_err() {
+ return Err(format!("{}", parse_tree_result.unwrap_err()));
+ }
+
+ let mut parse_tree = parse_tree_result.unwrap();
+
+ let syntax_tree: Program = ast::from_parse_tree(&mut parse_tree);
+
+ runtime::process(&syntax_tree, initial_symbol_table)
+}
+
+fn initialize_before_test() {
+ VAR_ID_INC.store(0, Ordering::Relaxed);
+}
+
+#[test]
+#[serial]
+fn test_reduce_integer_primitive() -> Result<(), String> {
+ initialize_before_test();
+ let term = Term::Primitive(Value::Integer(123));
+ let (result_term, _) = reduce_term(&HashMap::new(), Rc::new(term.clone()), &None, false)?;
+ assert_eq!(*result_term, term);
+ Ok(())
+}
+
+#[test]
+#[serial]
+fn test_reduce_string_primitive() -> Result<(), String> {
+ initialize_before_test();
+ let term = Term::Primitive(Value::String(String::from("foobar")));
+ let (result_term, _) = reduce_term(&HashMap::new(), Rc::new(term.clone()), &None, false)?;
+ assert_eq!(*result_term, term);
+ Ok(())
+}
+
+#[test]
+#[serial]
+fn test_reduce_id_call() -> Result<(), String> {
+ initialize_before_test();
+ let source = "
+ id 1;
+ ";
+ let (terms, symbol_table) = evaluate_from_source(String::from(source), None)?;
+ assert_eq!(terms.len(), 1);
+
+ let term = &terms[0];
+ let (result_term, _) = reduce_term(&symbol_table, Rc::clone(term), &None, false)?;
+
+ let expected = Term::Primitive(Value::Integer(1));
+ assert_eq!(*result_term, expected);
+ Ok(())
+}
+
+#[test]
+#[serial]
+fn test_reduce_id_call_negative() -> Result<(), String> {
+ initialize_before_test();
+ let source = "
+ id 1;
+ ";
+ let (terms, symbol_table) = evaluate_from_source(String::from(source), None)?;
+ assert_eq!(terms.len(), 1);
+
+ let term = &terms[0];
+ let (result_term, _) = reduce_term(&symbol_table, Rc::clone(term), &None, false)?;
+
+ let expected = Term::Primitive(Value::Integer(2));
+ assert_ne!(*result_term, expected);
+ Ok(())
+}
+
+#[test]
+#[serial]
+fn test_define_parameterized_func() -> Result<(), String> {
+ initialize_before_test();
+ let source = "
+ f a b = b a;
+ ";
+ let (terms, symbol_table) = evaluate_from_source(String::from(source), None)?;
+ assert_eq!(terms.len(), 0);
+
+ let term = symbol_table.get("f").ok_or("f not in symbol table")?;
+
+ let (result_term, _) = reduce_term(&symbol_table, Rc::clone(term), &None, false)?;
+
+ let expected = Term::Abstraction(
+ 0,
+ Rc::new(Term::Abstraction(
+ 1,
+ Rc::new(Term::Application(
+ Rc::new(Term::Variable(1)),
+ Rc::new(Term::Variable(0)),
+ )),
+ )),
+ );
+ assert_eq!(*result_term, expected);
+ Ok(())
+}
+
+#[test]
+#[serial]
+fn test_reduce_parameterized_func() -> Result<(), String> {
+ initialize_before_test();
+ let source = "
+ f 10 id;
+ ";
+
+ let predefined_f = Rc::new(Term::Abstraction(
+ 0,
+ Rc::new(Term::Abstraction(
+ 1,
+ Rc::new(Term::Application(
+ Rc::new(Term::Variable(1)),
+ Rc::new(Term::Variable(0)),
+ )),
+ )),
+ ));
+
+ let mut initial_symbol_table: HashMap<String, Rc<Term>> = HashMap::new();
+ initial_symbol_table.insert(String::from("f"), Rc::clone(&predefined_f));
+
+ let (terms, symbol_table) =
+ evaluate_from_source(String::from(source), Some(initial_symbol_table))?;
+ assert_eq!(terms.len(), 1);
+ let term = &terms[0];
+
+ let (result_term, _) = repeatedly_reduce_term(&symbol_table, Rc::clone(term), &None, false)?;
+
+ let expected = Term::Primitive(Value::Integer(10));
+ assert_eq!(*result_term, expected);
+ Ok(())
+}