mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 01:05:32 +01:00
Adding tests
- functional tests - more tests - tests tests tests Signed-off-by: teo3300 <matteo.rogora@live.it>
This commit is contained in:
@ -1 +0,0 @@
|
||||
.git/hooks/pre-commit
|
||||
13
.git_hooks_pre-commit-shadow
Executable file
13
.git_hooks_pre-commit-shadow
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Quit when first command fails
|
||||
set -e
|
||||
|
||||
# format code in a consistent way
|
||||
cargo fmt
|
||||
|
||||
# yeet on any clippy warning
|
||||
cargo clippy -- -Dwarnings
|
||||
|
||||
# check test pass
|
||||
cargo test
|
||||
@ -50,7 +50,11 @@ pub fn ns_init() -> Env {
|
||||
"list?" => Fun(|a| Ok(Bool(a.iter().all(|el| matches!(el, List(_))))), "Return true if the first argument is a list, false otherwise"),
|
||||
"empty?" => Fun(|a| Ok(Bool(car(a)?.if_list()?.is_empty())), "Return true if the first parameter is an empty list, false otherwise, returns an error if the element is not a list"),
|
||||
"count" => Fun(|a| Ok(Int(car(a)?.if_list()?.len() as isize)), "Return the number of elements in the first argument"),
|
||||
"and" => Fun(|a| Ok(Bool(a.iter().all(|a| !matches!(a, Nil | Bool(false))))), "Returns false if at least one of the arguments is 'false' or 'nil', true otherwise"),
|
||||
"or" => Fun(|a| Ok(Bool(a.iter().any(|a| !matches!(a, Nil | Bool(false))))), "Returns false if all the arguments are 'false' or 'nil', true otherwise"),
|
||||
"xor" => Fun(|a| Ok(Bool(a.iter().filter(|a| !matches!(a, Nil | Bool(false))).count() == 1)), "Returns true if one of the arguments is different from 'nil' or 'false', false otherwise"),
|
||||
"not" => Fun(|a| Ok(Bool(matches!(car(a)?, Nil | Bool(false)))), "Negate the first argument"),
|
||||
"=" => Fun(mal_comp, "Return true if the first two parameters are the same type and content, in case of lists propagate to all elements"),
|
||||
"assert" => Fun(mal_assert, "Panic if one of the arguments is false")
|
||||
"assert" => Fun(mal_assert, "Return an error if assertion fails")
|
||||
)
|
||||
}
|
||||
|
||||
@ -4,11 +4,11 @@ use std::env::args;
|
||||
mod core;
|
||||
mod env;
|
||||
mod eval;
|
||||
mod mal_tests;
|
||||
mod parse_tools;
|
||||
mod printer;
|
||||
mod reader;
|
||||
mod step4_if_fn_do;
|
||||
mod tests;
|
||||
mod types;
|
||||
|
||||
use core::ns_init;
|
||||
|
||||
@ -16,19 +16,32 @@ mod functional {
|
||||
($file:expr) => {{
|
||||
use crate::core::ns_init;
|
||||
use crate::load_file;
|
||||
let env = ns_init();
|
||||
load_file!("core.mal", &env);
|
||||
load_file!(format!("tests/{}.mal", $file).as_str(), &env);
|
||||
load_file!(format!("tests/{}.mal", $file).as_str(), &ns_init());
|
||||
}};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fibonacci() {
|
||||
test!("fibonacci");
|
||||
fn assert_fail() {
|
||||
use crate::core::ns_init;
|
||||
use crate::load_file;
|
||||
assert!(matches!(
|
||||
load_file("tests/assert_fail.mal", &ns_init()),
|
||||
Err(_)
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_logic() {
|
||||
test!("logic")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_equals() {
|
||||
test!("equals");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fibonacci() {
|
||||
test!("fibonacci");
|
||||
}
|
||||
}
|
||||
45
src/types.rs
45
src/types.rs
@ -94,11 +94,11 @@ pub fn mal_comp(args: &[MalType]) -> MalRet {
|
||||
}
|
||||
|
||||
pub fn mal_assert(args: &[MalType]) -> MalRet {
|
||||
args.iter().for_each(|i| match i {
|
||||
M::Nil | M::Bool(false) => panic!(),
|
||||
_ => (),
|
||||
});
|
||||
if args.iter().any(|i| matches!(i, M::Nil | M::Bool(false))) {
|
||||
Err(MalErr::unrecoverable("Assertion failed"))
|
||||
} else {
|
||||
Ok(M::Nil)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
@ -184,3 +184,40 @@ pub fn unescape_str(s: &str) -> String {
|
||||
.replace("\\n", "\n")
|
||||
.replace("\\\"", "\"")
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Tests //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::types::mal_assert;
|
||||
use crate::types::MalType as M;
|
||||
|
||||
#[test]
|
||||
fn _mal_assert() {
|
||||
assert!(matches!(mal_assert(&[M::Nil]), Err(_)));
|
||||
assert!(matches!(mal_assert(&[M::Bool(false)]), Err(_)));
|
||||
assert!(matches!(mal_assert(&[M::Bool(true)]), Ok(_)));
|
||||
assert!(matches!(mal_assert(&[M::Int(1)]), Ok(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _escape_str() {
|
||||
use crate::types::escape_str;
|
||||
assert_eq!(escape_str(""), "\"\""); // add quotations
|
||||
assert_eq!(escape_str("\\"), "\"\\\\\""); // escape "\"
|
||||
assert_eq!(escape_str("\n"), "\"\\n\""); // escape "\n"
|
||||
assert_eq!(escape_str("\""), "\"\\\"\""); // escape "\""
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn _unescape_str() {
|
||||
use crate::types::unescape_str;
|
||||
assert_eq!(unescape_str("\"\""), ""); // remove quotations
|
||||
assert_eq!(unescape_str("\"a\""), "a"); // remove quotations
|
||||
assert_eq!(unescape_str("\"\\\\\""), "\\"); // unescape "\"
|
||||
assert_eq!(unescape_str("\"\\n\""), "\n"); // unescape "\n"
|
||||
assert_eq!(unescape_str("\"\\\"\""), "\""); // unescape "\""
|
||||
}
|
||||
}
|
||||
|
||||
1
tests/assert_fail.mal
Normal file
1
tests/assert_fail.mal
Normal file
@ -0,0 +1 @@
|
||||
(assert nil)
|
||||
31
tests/logic.mal
Normal file
31
tests/logic.mal
Normal file
@ -0,0 +1,31 @@
|
||||
; positive assert
|
||||
(assert true)
|
||||
(assert ())
|
||||
(assert 1)
|
||||
|
||||
; not
|
||||
(assert (not false))
|
||||
(assert (not nil))
|
||||
(assert (not (not true)))
|
||||
|
||||
; or
|
||||
(assert (not (or false)))
|
||||
(assert (or 1))
|
||||
(assert (or 1 nil false))
|
||||
(assert (or 1 1 1))
|
||||
(assert (or nil 1 false))
|
||||
(assert (not (or nil false)))
|
||||
(assert (not (or false nil)))
|
||||
|
||||
; and
|
||||
(assert (and 1))
|
||||
(assert (not (and nil)))
|
||||
(assert (and 1 1 1))
|
||||
(assert (not (and 1 nil false)))
|
||||
(assert (not (and nil false)))
|
||||
|
||||
; xor
|
||||
(assert (not (xor nil false nil)))
|
||||
(assert (xor nil 1 nil false nil))
|
||||
(assert (not (xor nil 1 false 1)))
|
||||
(assert (not (xor 1 nil 1 1)))
|
||||
Reference in New Issue
Block a user