use std::sync::Arc;
use cljrs_reader::Parser;
use cljrs_runtime::env::env::{Env, GlobalEnv};
use cljrs_value::Value;
fn make_env() -> (Arc<GlobalEnv>, Env) {
let globals = cljrs_runtime::Runtime::builder()
.execution_mode(cljrs_runtime::ExecutionMode::TreeWalk)
.eager_clojure_test(true)
.build()
.expect("runtime")
.into_globals();
let env = Env::new(globals.clone(), "user");
(globals, env)
}
fn eval_fresh(src: &str) -> Value {
let (_, mut env) = make_env();
let mut parser = Parser::new(src.to_string(), "<test>".to_string());
let forms = parser.parse_all().expect("parse error");
let mut result = Value::Nil;
for form in forms {
result = cljrs_runtime::interp::eval::eval(&form, &mut env).expect("eval error");
}
result
}
#[test]
fn into_lazy_seq_target_produces_cons() {
let result = eval_fresh("(into (map inc [1 2]) [9])");
let elems = eval_fresh("(vec (into (map inc [1 2]) [9]))");
if let Value::Vector(v) = elems {
let v = v.get();
assert_eq!(v.count(), 3, "expected 3 elements");
assert_eq!(v.nth(0), Some(&Value::Long(9)));
assert_eq!(v.nth(1), Some(&Value::Long(2)));
assert_eq!(v.nth(2), Some(&Value::Long(3)));
} else {
panic!("expected Vector after (vec ...), got {:?}", elems);
}
assert!(
!matches!(result, Value::Nil),
"into should not return nil for a non-empty lazy-seq target"
);
}
#[test]
fn into_lazy_seq_target_multiple_items() {
let elems = eval_fresh("(vec (into (map inc [10 20]) [1 2 3]))");
if let Value::Vector(v) = elems {
let v = v.get();
assert_eq!(v.count(), 5);
assert_eq!(v.nth(0), Some(&Value::Long(3)));
assert_eq!(v.nth(1), Some(&Value::Long(2)));
assert_eq!(v.nth(2), Some(&Value::Long(1)));
assert_eq!(v.nth(3), Some(&Value::Long(11)));
assert_eq!(v.nth(4), Some(&Value::Long(21)));
} else {
panic!("expected Vector, got {:?}", elems);
}
}
#[test]
fn into_lazy_seq_target_empty_source() {
let cnt = eval_fresh("(count (into (map inc [1 2]) []))");
assert_eq!(cnt, Value::Long(2));
}
#[test]
fn into_cons_target_produces_cons() {
let elems = eval_fresh("(vec (into (seq [1 2]) [9]))");
if let Value::Vector(v) = elems {
let v = v.get();
assert_eq!(v.count(), 3);
assert_eq!(v.nth(0), Some(&Value::Long(9)));
assert_eq!(v.nth(1), Some(&Value::Long(1)));
assert_eq!(v.nth(2), Some(&Value::Long(2)));
} else {
panic!("expected Vector, got {:?}", elems);
}
}
#[test]
fn into_lazy_seq_as_source_still_works() {
let result = eval_fresh("(into [] (map inc [1 2]))");
if let Value::Vector(v) = result {
let v = v.get();
assert_eq!(v.count(), 2);
assert_eq!(v.nth(0), Some(&Value::Long(2)));
assert_eq!(v.nth(1), Some(&Value::Long(3)));
} else {
panic!("expected Vector, got {:?}", result);
}
}
#[test]
fn into_list_target_still_correct() {
let elems = eval_fresh("(vec (into '(1 2) [9]))");
if let Value::Vector(v) = elems {
let v = v.get();
assert_eq!(v.count(), 3);
assert_eq!(v.nth(0), Some(&Value::Long(9)));
assert_eq!(v.nth(1), Some(&Value::Long(1)));
assert_eq!(v.nth(2), Some(&Value::Long(2)));
} else {
panic!("expected Vector, got {:?}", elems);
}
}