use aethershell::{env::Env, eval, parser};
fn eval_code(code: &str, env: &mut Env) -> aethershell::value::Value {
let stmts = parser::parse_program(code).unwrap();
eval::eval_program(&stmts, env).unwrap()
}
#[test]
fn private_by_default() {
let mut env = Env::default();
eval_code("let x = 42", &mut env);
assert!(env.get_var("x").is_some());
assert!(!env.is_exported("x"));
}
#[test]
fn pub_let_is_exported() {
let mut env = Env::default();
eval_code("pub let x = 42", &mut env);
assert!(env.get_var("x").is_some());
assert!(env.is_exported("x"));
}
#[test]
fn pub_shorthand_is_exported() {
let mut env = Env::default();
eval_code("pub x = 100", &mut env);
assert!(env.get_var("x").is_some());
assert!(env.is_exported("x"));
}
#[test]
fn multiple_pub_declarations() {
let mut env = Env::default();
eval_code(
r#"
pub let a = 1
let b = 2
pub let c = 3
"#,
&mut env,
);
assert!(env.get_var("a").is_some());
assert!(env.get_var("b").is_some());
assert!(env.get_var("c").is_some());
assert!(env.is_exported("a"));
assert!(!env.is_exported("b"));
assert!(env.is_exported("c"));
}
#[test]
fn export_statement() {
let mut env = Env::default();
eval_code(
r#"
let x = 1
let y = 2
export { x, y }
"#,
&mut env,
);
assert!(env.is_exported("x"));
assert!(env.is_exported("y"));
}
#[test]
fn export_with_alias() {
let mut env = Env::default();
eval_code(
r#"
let add = fn(a, b) => a + b
export { add as plus }
"#,
&mut env,
);
assert!(env.get_var("add").is_some());
assert!(env.is_exported("plus"));
}
#[test]
fn exported_vars_filter() {
let mut env = Env::default();
eval_code(
r#"
pub let public_a = 1
let private_b = 2
pub let public_c = 3
let private_d = 4
"#,
&mut env,
);
let exported = env.exported_vars();
assert!(exported.contains_key("public_a"));
assert!(exported.contains_key("public_c"));
assert!(!exported.contains_key("private_b"));
assert!(!exported.contains_key("private_d"));
}
#[test]
fn pub_function() {
let mut env = Env::default();
eval_code(
r#"
pub let add = fn(a, b) => a + b
let result = add(2, 3)
"#,
&mut env,
);
assert!(env.is_exported("add"));
assert!(!env.is_exported("result"));
let result = env.get_var("result").unwrap();
assert_eq!(result.as_int().unwrap(), 5);
}
#[test]
fn visibility_local_access() {
let mut env = Env::default();
let result = eval_code(
r#"
let helper = fn(x) => x * 2
pub let double_add = fn(a, b) => helper(a) + helper(b)
double_add(3, 4)
"#,
&mut env,
);
assert_eq!(result.as_int().unwrap(), 14);
assert!(!env.is_exported("helper"));
assert!(env.is_exported("double_add"));
}
#[test]
fn exports_iterator() {
let mut env = Env::default();
eval_code(
r#"
pub let a = 1
pub let b = 2
let c = 3
"#,
&mut env,
);
let exports: Vec<String> = env.exports().cloned().collect();
assert!(exports.contains(&"a".to_string()));
assert!(exports.contains(&"b".to_string()));
assert!(!exports.contains(&"c".to_string()));
}