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 assert_marker(result: Value) {
match result {
Value::Long(n) => assert_eq!(n, 42),
other => panic!("expected 42, got {other:?}"),
}
}
fn eval_fresh(src: &str) -> Result<Value, String> {
let (_, mut env) = make_env();
let mut parser = Parser::new(src.to_string(), "<test>".to_string());
let forms = parser.parse_all().map_err(|e| format!("{e:?}"))?;
let mut result = Value::Nil;
for form in forms {
result =
cljrs_runtime::interp::eval::eval(&form, &mut env).map_err(|e| format!("{e:?}"))?;
}
Ok(result)
}
#[test]
fn namespace_slot_resolves_a_reader_conditional() {
let result = eval_fresh(
"(ns t.a (:require [#?(:rust clojure.core :default clojure.core) :as core])) \
(core/inc 41)",
)
.expect("spec with a conditional namespace should load");
assert_marker(result);
}
#[test]
fn default_branch_is_taken_when_no_platform_key_matches() {
let result = eval_fresh(
"(ns t.b (:require [#?(:clj clojure.set :cljs cljs.core :default clojure.core) :as core])) \
(core/inc 41)",
)
.expect("the :default branch should be selected on :rust");
assert_marker(result);
}
#[test]
fn option_slot_conditionals_still_resolve() {
let result = eval_fresh(
"(ns t.c (:require [clojure.core #?(:cljs :refer-macros :default :as) core])) \
(core/inc 41)",
)
.expect("a conditional in the option position is the case that already worked");
assert_marker(result);
}
#[test]
fn plain_namespace_slot_is_unaffected() {
let result = eval_fresh("(ns t.d (:require [clojure.core :as core])) (core/inc 41)")
.expect("plain spec should be unaffected");
assert_marker(result);
}
#[test]
fn no_matching_branch_is_reported_as_such() {
let err = eval_fresh("(ns t.e (:require [#?(:clj clojure.core :cljs cljs.core) :as core]))")
.expect_err("no branch matches :rust");
assert!(
err.contains("no reader-conditional branch matched"),
"message should name the real cause, got: {err}"
);
}