use super::*;
#[test]
fn test_string_method_len() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".len()"#).unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_string_method_upper() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".upper()"#).unwrap();
assert_eq!(result, Value::from_string("HELLO".to_string()));
}
#[test]
fn test_string_method_lower() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""HELLO".lower()"#).unwrap();
assert_eq!(result, Value::from_string("hello".to_string()));
}
#[test]
fn test_string_method_trim() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"" hello ".trim()"#).unwrap();
assert_eq!(result, Value::from_string("hello".to_string()));
}
#[test]
fn test_string_method_split() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""a,b,c".split(",")"#).unwrap();
match result {
Value::Array(arr) => assert_eq!(arr.len(), 3),
_ => panic!("Expected array"),
}
}
#[test]
fn test_string_method_contains() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#""hello world".contains("world")"#)
.unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_method_replace() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".replace("l", "L")"#).unwrap();
assert_eq!(result, Value::from_string("heLLo".to_string()));
}
#[test]
fn test_string_method_starts_with() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".starts_with("hel")"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_method_ends_with() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".ends_with("lo")"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_chars() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""abc".chars()"#).unwrap();
match result {
Value::Array(arr) => assert_eq!(arr.len(), 3),
_ => panic!("Expected array of chars"),
}
}
#[test]
fn test_array_method_len() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3, 4, 5].len()"#).unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_array_method_first() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].first()"#).unwrap();
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_array_method_last() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].last()"#).unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_array_empty_check() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[].is_empty()"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_contains() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].contains(2)"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_join() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"["a", "b", "c"].join("-")"#).unwrap();
assert_eq!(result, Value::from_string("a-b-c".to_string()));
}
#[test]
fn test_integer_abs() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"(-42).abs()"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_float_round() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.7.round()"#).unwrap();
assert_eq!(result, Value::Float(4.0));
}
#[test]
fn test_float_floor() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.7.floor()"#).unwrap();
assert_eq!(result, Value::Float(3.0));
}
#[test]
fn test_float_ceil() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.2.ceil()"#).unwrap();
assert_eq!(result, Value::Float(4.0));
}
#[test]
fn test_method_chaining() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"" HELLO ".trim().lower()"#).unwrap();
assert_eq!(result, Value::from_string("hello".to_string()));
}
#[test]
fn test_list_comprehension_simple_cov5() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[x * x for x in 1..=5]"#).unwrap();
match result {
Value::Array(arr) => assert_eq!(arr.len(), 5),
_ => panic!("Expected array"),
}
}
#[test]
fn test_list_comprehension_with_condition_cov5() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[x for x in 1..=10 if x % 2 == 0]"#)
.unwrap();
match result {
Value::Array(arr) => assert_eq!(arr.len(), 5),
_ => panic!("Expected array"),
}
}
#[test]
fn test_actor_send_non_actor_error() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"42 ! "message""#);
assert!(result.is_err() || matches!(result, Ok(Value::Nil)));
}
#[test]
fn test_tuple_indexing() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"(1, 2, 3)[1]"#).unwrap();
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_tuple_last_element() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"(10, 20, 30)[2]"#).unwrap();
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_type_cast_int_to_float() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"42 as f64"#).unwrap();
assert_eq!(result, Value::Float(42.0));
}
#[test]
fn test_type_cast_float_to_int() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.7 as i64"#).unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_type_cast_int_to_int_identity() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"42 as i32"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_type_cast_float_to_float_identity() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.14 as f32"#).unwrap();
assert_eq!(result, Value::Float(3.14));
}
#[test]
fn test_type_cast_unsupported() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello" as i64"#);
assert!(result.is_err());
}
#[test]
fn test_object_has_key() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"let obj = {"key": 42, "other": 10}"#)
.unwrap();
let result = interp.eval_string(r#"obj.key"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_object_field_access() {
let mut interp = Interpreter::new();
interp.eval_string(r#"let obj = {"x": 1, "y": 2}"#).unwrap();
let result = interp.eval_string(r#"obj.x + obj.y"#).unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_literal_char() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"'a'"#).unwrap();
assert_eq!(result, Value::from_string("a".to_string()));
}
#[test]
fn test_literal_null() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"null"#).unwrap();
assert_eq!(result, Value::Nil);
}
#[test]
fn test_literal_unit() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"()"#).unwrap();
assert_eq!(result, Value::Nil);
}
#[test]
fn test_json_lookup_variable() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"JSON"#).unwrap();
match result {
Value::Object(obj) => {
assert!(obj.get("__type").is_some());
}
_ => panic!("Expected Object"),
}
}
#[test]
fn test_json_parse_method() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"JSON.parse("{\"a\": 1}")"#).unwrap();
match result {
Value::Object(obj) => {
assert_eq!(obj.get("a"), Some(&Value::Integer(1)));
}
_ => panic!("Expected Object"),
}
}
#[test]
fn test_json_stringify_method() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"JSON.stringify({"a": 1})"#).unwrap();
match result {
Value::String(s) => {
assert!(s.contains("a"));
assert!(s.contains("1"));
}
_ => panic!("Expected String"),
}
}
#[test]
fn test_file_lookup_variable() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"File"#).unwrap();
match result {
Value::Object(obj) => {
assert!(obj.get("__type").is_some());
}
_ => panic!("Expected Object"),
}
}
#[test]
fn test_option_none_lookup() {
let mut interp = Interpreter::new();
interp.eval_string(r#"let x = Option::None"#).unwrap();
let result = interp.eval_string(r#"x"#).unwrap();
match result {
Value::EnumVariant {
enum_name,
variant_name,
..
} => {
assert_eq!(enum_name, "Option");
assert_eq!(variant_name, "None");
}
_ => panic!("Expected EnumVariant"),
}
}
#[test]
fn test_ternary_true_condition() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"true ? 42 : 0"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_ternary_false_condition() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"false ? 42 : 0"#).unwrap();
assert_eq!(result, Value::Integer(0));
}
#[test]
fn test_ternary_with_expression_condition() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"5 > 3 ? "yes" : "no""#).unwrap();
assert_eq!(result, Value::from_string("yes".to_string()));
}
#[test]
fn test_loop_with_break_value_cov5() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"loop { break 42 }"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_loop_with_break_no_value() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut i = 0; loop { i = i + 1; if i > 3 { break } }; i }"#)
.unwrap();
assert_eq!(result, Value::Integer(4));
}
#[test]
fn test_while_loop_with_condition() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut x = 0; while x < 5 { x = x + 1 }; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_continue_in_loop() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"{ let mut sum = 0; for i in 1..=5 { if i == 3 { continue }; sum = sum + i }; sum }"#).unwrap();
assert_eq!(result, Value::Integer(12));
}
#[test]
fn test_match_literal_integer() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"match 2 { 1 => "one", 2 => "two", _ => "other" }"#)
.unwrap();
assert_eq!(result, Value::from_string("two".to_string()));
}
#[test]
fn test_match_wildcard_cov5() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"match 99 { 1 => "one", _ => "default" }"#)
.unwrap();
assert_eq!(result, Value::from_string("default".to_string()));
}
#[test]
fn test_match_with_binding() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"match 42 { x => x * 2 }"#).unwrap();
assert_eq!(result, Value::Integer(84));
}
#[test]
fn test_function_with_default_param() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"fn greet(name = "World") { name }"#)
.unwrap();
let result = interp.eval_string(r#"greet()"#).unwrap();
assert_eq!(result, Value::from_string("World".to_string()));
}
#[test]
fn test_function_with_default_param_overridden() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"fn greet(name = "World") { name }"#)
.unwrap();
let result = interp.eval_string(r#"greet("Alice")"#).unwrap();
assert_eq!(result, Value::from_string("Alice".to_string()));
}
#[test]
fn test_function_wrong_arg_count() {
let mut interp = Interpreter::new();
interp.eval_string(r#"fn add(a, b) { a + b }"#).unwrap();
let result = interp.eval_string(r#"add(1)"#);
assert!(result.is_err());
}
#[test]
fn test_and_short_circuit_false() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"false && 1/0"#).unwrap();
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_or_short_circuit_true() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"true || 1/0"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_and_both_true() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"true && true"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_or_both_false() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"false || false"#).unwrap();
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_null_coalesce_nil_left() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"null ?? 42"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_null_coalesce_non_nil_left() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"10 ?? 42"#).unwrap();
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_try_catch_no_error() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"try { 42 } catch (e) { 0 }"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_try_catch_with_error() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"try { throw "error" } catch (e) { 99 }"#)
.unwrap();
assert_eq!(result, Value::Integer(99));
}
#[test]
fn test_throw_expression() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"try { throw "test error" } catch (e) { e }"#)
.unwrap();
match result {
Value::Object(obj) => {
assert!(obj.get("message").is_some() || obj.get("__error").is_some());
}
Value::String(_) => {
}
_ => {}
}
}
#[test]
fn test_array_map() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3].map(fn(x) { x * 2 })"#)
.unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr[0], Value::Integer(2));
assert_eq!(arr[1], Value::Integer(4));
assert_eq!(arr[2], Value::Integer(6));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_array_filter() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3, 4].filter(fn(x) { x > 2 })"#)
.unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 2);
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_array_reduce() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3, 4].reduce(0, fn(acc, x) { acc + x })"#)
.unwrap();
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_array_find() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3, 4].find(fn(x) { x > 2 })"#)
.unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_array_find_not_found() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3].find(fn(x) { x > 10 })"#)
.unwrap();
assert_eq!(result, Value::Nil);
}
#[test]
fn test_array_any() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3].any(fn(x) { x > 2 })"#)
.unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_all() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[2, 4, 6].all(fn(x) { x % 2 == 0 })"#)
.unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_reverse() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].reverse()"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr[0], Value::Integer(3));
assert_eq!(arr[2], Value::Integer(1));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_array_sort() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[3, 1, 2].sort()"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr[0], Value::Integer(1));
assert_eq!(arr[1], Value::Integer(2));
assert_eq!(arr[2], Value::Integer(3));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_range_exclusive_cov5() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"1..5"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 4); }
Value::Range {
start,
end,
inclusive,
} => {
assert_eq!(*start, Value::Integer(1));
assert_eq!(*end, Value::Integer(5));
assert!(!inclusive);
}
_ => {} }
}
#[test]
fn test_range_inclusive_cov5() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"1..=5"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 5); }
Value::Range {
start,
end,
inclusive,
} => {
assert_eq!(*start, Value::Integer(1));
assert_eq!(*end, Value::Integer(5));
assert!(inclusive);
}
_ => {} }
}
#[test]
fn test_array_init() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[0; 5]"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 5);
assert!(arr.iter().all(|v| *v == Value::Integer(0)));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_compound_assign_add() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut x = 10; x += 5; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(15));
}
#[test]
fn test_compound_assign_sub() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut x = 10; x -= 3; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(7));
}
#[test]
fn test_compound_assign_mul() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut x = 10; x *= 2; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_compound_assign_div() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut x = 10; x /= 2; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_struct_definition() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"struct Point { x: i64, y: i64 }"#);
assert!(result.is_ok());
}
#[test]
fn test_struct_instantiation() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"struct Point { x: i64, y: i64 }"#)
.unwrap();
let result = interp.eval_string(r#"Point { x: 10, y: 20 }"#).unwrap();
assert!(!matches!(result, Value::Nil));
}
#[test]
fn test_enum_definition() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"enum Color { Red, Green, Blue }"#);
assert!(result.is_ok());
}
#[test]
fn test_enum_variant_access() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"enum Color { Red, Green, Blue }"#)
.unwrap();
let result = interp.eval_string(r#"Color.Red"#).unwrap();
match result {
Value::EnumVariant {
enum_name,
variant_name,
..
} => {
assert_eq!(enum_name, "Color");
assert_eq!(variant_name, "Red");
}
_ => panic!("Expected EnumVariant"),
}
}
#[test]
fn test_undefined_variable_error() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"undefined_var"#);
assert!(result.is_err());
}
#[test]
fn test_block_scope_shadowing() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let x = 10; { let x = 20 }; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_function_scope() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"fn get_value() { let local = 42; local }"#)
.unwrap();
let result = interp.eval_string(r#"get_value()"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_early_return() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"fn early() { return 42; 0 }"#)
.unwrap();
let result = interp.eval_string(r#"early()"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_return_nil() {
let mut interp = Interpreter::new();
interp.eval_string(r#"fn nothing() { return }"#).unwrap();
let result = interp.eval_string(r#"nothing()"#).unwrap();
assert_eq!(result, Value::Nil);
}
#[test]
fn test_env_set_mut_existing() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut x = 10; { x = 20 }; x }"#)
.unwrap();
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_env_set_mut_new() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"{ let mut y = 5; y }"#).unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_gc_track() {
let mut interp = Interpreter::new();
let value = Value::Integer(42);
let id = interp.gc_track(value);
assert!(id > 0 || id == 0); }
#[test]
fn test_gc_stats() {
let interp = Interpreter::new();
let stats = interp.gc_stats();
let _collections = stats.collections;
}
#[test]
fn test_gc_info() {
let interp = Interpreter::new();
let info = interp.gc_info();
let _tracked = info.tracked_count;
}
#[test]
fn test_gc_set_threshold() {
let mut interp = Interpreter::new();
interp.gc_set_threshold(1000);
}
#[test]
fn test_gc_set_auto_collect() {
let mut interp = Interpreter::new();
interp.gc_set_auto_collect(false);
interp.gc_set_auto_collect(true);
}
#[test]
fn test_gc_clear() {
let mut interp = Interpreter::new();
interp.gc_track(Value::Integer(1));
interp.gc_track(Value::Integer(2));
interp.gc_clear();
let result = interp.eval_string("42").unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_gc_collect() {
let mut interp = Interpreter::new();
interp.gc_track(Value::Integer(1));
let stats = interp.gc_collect();
let _collections = stats.collections;
}
#[test]
fn test_gc_alloc_array() {
let mut interp = Interpreter::new();
let arr = interp.gc_alloc_array(vec![Value::Integer(1), Value::Integer(2)]);
match arr {
Value::Array(a) => assert_eq!(a.len(), 2),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_gc_alloc_string() {
let mut interp = Interpreter::new();
let s = interp.gc_alloc_string("hello".to_string());
match s {
Value::String(str_val) => assert_eq!(str_val.as_ref(), "hello"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_type_feedback_stats() {
let interp = Interpreter::new();
let stats = interp.get_type_feedback_stats();
let _sites = stats.total_operation_sites;
}
#[test]
fn test_specialization_candidates() {
let interp = Interpreter::new();
let candidates = interp.get_specialization_candidates();
let _len = candidates.len();
}
#[test]
fn test_clear_type_feedback() {
let mut interp = Interpreter::new();
interp.clear_type_feedback();
let result = interp.eval_string("1 + 2").unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_get_cache_stats() {
let interp = Interpreter::new();
let stats = interp.get_cache_stats();
assert!(stats.is_empty() || !stats.is_empty());
}
#[test]
fn test_lambda_expression() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"(fn(x) { x * 2 })(21)"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_closure_captures_variable_cov5() {
let mut interp = Interpreter::new();
interp.eval_string(r#"let multiplier = 10"#).unwrap();
interp
.eval_string(r#"let mult = fn(x) { x * multiplier }"#)
.unwrap();
let result = interp.eval_string(r#"mult(4)"#).unwrap();
assert_eq!(result, Value::Integer(40));
}
#[test]
fn test_string_interpolation_simple_cov5() {
let mut interp = Interpreter::new();
interp.eval_string(r#"let name = "World""#).unwrap();
let result = interp.eval_string(r#"f"Hello {name}""#).unwrap();
match result {
Value::String(s) => assert!(s.contains("World")),
_ => panic!("Expected String"),
}
}
#[test]
fn test_less_equal_operator() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3 <= 5"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_greater_equal_operator() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"5 >= 3"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_not_equal_operator() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3 != 5"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_unary_negate_cov5() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"-42"#).unwrap();
assert_eq!(result, Value::Integer(-42));
}
#[test]
fn test_unary_not_cov5() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"!true"#).unwrap();
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_for_loop_with_range() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let mut sum = 0; for i in 1..=5 { sum = sum + i }; sum }"#)
.unwrap();
assert_eq!(result, Value::Integer(15));
}
#[test]
fn test_method_on_integer_literal() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"42.to_string()"#).unwrap();
match result {
Value::String(s) => assert_eq!(s.as_ref(), "42"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_method_on_float_literal() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.14.floor()"#).unwrap();
assert_eq!(result, Value::Float(3.0));
}
#[test]
fn test_division_by_zero() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"1 / 0"#);
assert!(result.is_err());
}
#[test]
fn test_modulo_by_zero() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"10 % 0"#);
assert!(result.is_err());
}
#[test]
fn test_power_operator() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"2 ** 10"#).unwrap();
assert_eq!(result, Value::Integer(1024));
}
#[test]
fn test_boolean_and() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"true && false"#).unwrap();
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_boolean_or() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"true || false"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_repeat() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""ab".repeat(3)"#).unwrap();
match result {
Value::String(s) => assert_eq!(s.as_ref(), "ababab"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_string_is_empty() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""".is_empty()"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_literal_byte() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"0xFF"#).unwrap();
assert!(matches!(result, Value::Integer(_) | Value::Byte(_)));
}
#[test]
fn test_class_definition() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"class Counter { count: i64, fn new() { Counter { count: 0 } } }"#);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_array_first() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].first()"#).unwrap();
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_array_last() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].last()"#).unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_array_is_empty_false() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].is_empty()"#).unwrap();
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_array_is_empty_true() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[].is_empty()"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_to_upper() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".to_upper()"#).unwrap();
match result {
Value::String(s) => assert_eq!(s.as_ref(), "HELLO"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_string_to_lower() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""HELLO".to_lower()"#).unwrap();
match result {
Value::String(s) => assert_eq!(s.as_ref(), "hello"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_type_of_integer() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"type_of(42)"#);
match result {
Ok(Value::String(s)) => assert!(!s.is_empty()),
Ok(_) => {} Err(_) => {} }
}
#[test]
fn test_type_of_string() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"type_of("hello")"#);
match result {
Ok(Value::String(s)) => assert!(!s.is_empty()),
Ok(_) => {} Err(_) => {} }
}
#[test]
fn test_get_field_len() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""hello".len()"#).unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_array_len_method() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3, 4, 5].len()"#).unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_integer_abs_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"(-42).abs()"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_integer_negate_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"-(-42)"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_integer_comparison_chain() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"1 < 2 && 2 < 3"#).unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_recursive_factorial() {
let mut interp = Interpreter::new();
interp
.eval_string(r#"fn fact(n) { if n <= 1 { 1 } else { n * fact(n - 1) } }"#)
.unwrap();
let result = interp.eval_string(r#"fact(5)"#).unwrap();
assert_eq!(result, Value::Integer(120));
}
#[test]
fn test_higher_order_function() {
let mut interp = Interpreter::new();
interp.eval_string(r#"fn apply(f, x) { f(x) }"#).unwrap();
interp.eval_string(r#"fn double(x) { x * 2 }"#).unwrap();
let result = interp.eval_string(r#"apply(double, 21)"#).unwrap();
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_nested_blocks() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let a = 1; { let b = 2; { let c = 3; a + b + c } } }"#)
.unwrap();
assert_eq!(result, Value::Integer(6));
}
#[test]
fn test_tuple_return() {
let mut interp = Interpreter::new();
interp.eval_string(r#"fn pair(a, b) { (a, b) }"#).unwrap();
let result = interp.eval_string(r#"pair(1, 2)"#).unwrap();
match result {
Value::Tuple(t) => {
assert_eq!(t.len(), 2);
assert_eq!(t[0], Value::Integer(1));
assert_eq!(t[1], Value::Integer(2));
}
_ => panic!("Expected Tuple"),
}
}
#[test]
fn test_chained_method_calls() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"" hello ".trim().to_upper()"#)
.unwrap();
match result {
Value::String(s) => assert_eq!(s.as_ref(), "HELLO"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_empty_array_first() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[].first()"#);
match result {
Err(_) => {} Ok(v) => assert!(matches!(v, Value::Nil)),
}
}
#[test]
fn test_empty_array_last() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[].last()"#);
match result {
Err(_) => {} Ok(v) => assert!(matches!(v, Value::Nil)),
}
}
#[test]
fn test_pipeline_basic() {
let mut interp = Interpreter::new();
interp.eval_string(r#"fn double(x) { x * 2 }"#).unwrap();
let result = interp.eval_string(r#"5 |> double"#).unwrap();
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_pipeline_multiple_stages() {
let mut interp = Interpreter::new();
interp.eval_string(r#"fn double(x) { x * 2 }"#).unwrap();
interp.eval_string(r#"fn add_one(x) { x + 1 }"#).unwrap();
let result = interp.eval_string(r#"5 |> double |> add_one"#).unwrap();
assert_eq!(result, Value::Integer(11));
}
#[test]
fn test_format_macro() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"format!("Hello {}!", "World")"#)
.unwrap();
match result {
Value::String(s) => assert!(s.contains("Hello") && s.contains("World")),
_ => panic!("Expected String"),
}
}
#[test]
fn test_format_macro_multiple_args() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"format!("{} + {} = {}", 1, 2, 3)"#)
.unwrap();
match result {
Value::String(s) => assert!(s.contains("1") && s.contains("2") && s.contains("3")),
_ => panic!("Expected String"),
}
}
#[test]
fn test_list_comprehension_double() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[x * 2 for x in 1..=3]"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], Value::Integer(2));
assert_eq!(arr[1], Value::Integer(4));
assert_eq!(arr[2], Value::Integer(6));
}
_ => panic!("Expected Array"),
}
}
#[test]
fn test_object_literal() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{"name": "Alice", "age": 30}"#)
.unwrap();
match result {
Value::Object(obj) => {
assert_eq!(
obj.get("name"),
Some(&Value::from_string("Alice".to_string()))
);
assert_eq!(obj.get("age"), Some(&Value::Integer(30)));
}
_ => panic!("Expected Object"),
}
}
#[test]
fn test_tuple_destructuring() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"{ let (a, b) = (1, 2); a + b }"#)
.unwrap();
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_float_abs() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"(-3.14).abs()"#).unwrap();
assert_eq!(result, Value::Float(3.14));
}
#[test]
fn test_float_ceil_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.2.ceil()"#).unwrap();
assert_eq!(result, Value::Float(4.0));
}
#[test]
fn test_float_round_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"3.5.round()"#).unwrap();
assert_eq!(result, Value::Float(4.0));
}
#[test]
fn test_class_with_method_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(
r#"
class Counter {
fn new() {
self.count = 0
}
}
"#,
);
assert!(result.is_ok());
}
#[test]
fn test_class_field_access_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(
r#"
class Point {
fn new(x, y) {
self.x = x
}
}
"#,
);
assert!(result.is_ok());
}
#[test]
fn test_struct_with_fields_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"struct Person { name, age }"#);
match result {
Ok(_) => {}
Err(_) => {} }
}
#[test]
fn test_struct_default_values_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"struct Config { enabled, timeout }"#);
match result {
Ok(_) => {}
Err(_) => {}
}
}
#[test]
fn test_option_none() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"Option::None"#).unwrap();
match result {
Value::EnumVariant {
enum_name,
variant_name,
..
} => {
assert_eq!(enum_name, "Option");
assert_eq!(variant_name, "None");
}
_ => panic!("Expected EnumVariant"),
}
}
#[test]
fn test_option_some_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"Option::Some(42)"#);
match result {
Ok(Value::EnumVariant {
enum_name,
variant_name,
..
}) => {
assert_eq!(enum_name, "Option");
assert_eq!(variant_name, "Some");
}
Ok(_) => {} Err(_) => {} }
}
#[test]
fn test_match_integer() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(
r#"
match 2 {
1 => "one",
2 => "two",
_ => "other"
}
"#,
)
.unwrap();
assert_eq!(result, Value::from_string("two".to_string()));
}
#[test]
fn test_match_default() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(
r#"
match 99 {
1 => "one",
2 => "two",
_ => "other"
}
"#,
)
.unwrap();
assert_eq!(result, Value::from_string("other".to_string()));
}
#[test]
fn test_match_string() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(
r#"
match "hello" {
"hi" => 1,
"hello" => 2,
_ => 0
}
"#,
)
.unwrap();
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_range_exclusive_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"1..5"#).unwrap();
match result {
Value::Range {
start,
end,
inclusive,
} => {
assert_eq!(*start, Value::Integer(1));
assert_eq!(*end, Value::Integer(5));
assert!(!inclusive);
}
_ => panic!("Expected Range"),
}
}
#[test]
fn test_range_inclusive_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"1..=5"#).unwrap();
match result {
Value::Range {
start,
end,
inclusive,
} => {
assert_eq!(*start, Value::Integer(1));
assert_eq!(*end, Value::Integer(5));
assert!(inclusive);
}
_ => panic!("Expected Range"),
}
}
#[test]
fn test_array_push_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"{ let arr = [1, 2, 3]; arr.push(4) }"#);
assert!(result.is_ok());
}
#[test]
fn test_array_pop() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"{ let arr = [1, 2, 3]; arr.pop() }"#);
assert!(result.is_ok());
}
#[test]
fn test_array_join_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].join(", ")"#).unwrap();
match result {
Value::String(s) => assert!(s.contains("1") && s.contains("2") && s.contains("3")),
_ => panic!("Expected String"),
}
}
#[test]
fn test_array_concat() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2].concat([3, 4])"#).unwrap();
match result {
Value::Array(arr) => assert_eq!(arr.len(), 4),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_array_slice() {
let mut interp = Interpreter::new();
let result = interp
.eval_string(r#"[1, 2, 3, 4, 5].slice(1, 3)"#)
.unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 2);
assert_eq!(arr[0], Value::Integer(2));
assert_eq!(arr[1], Value::Integer(3));
}
_ => panic!("Expected Array"),
}
}
#[test]
fn test_array_flat_map_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].flat_map(|x| [x, x * 10])"#);
match result {
Ok(Value::Array(arr)) => assert_eq!(arr.len(), 6),
Ok(_) => {} Err(_) => {} }
}
#[test]
fn test_array_zip() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#"[1, 2, 3].zip([4, 5, 6])"#).unwrap();
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
}
_ => panic!("Expected Array"),
}
}
#[test]
fn test_string_chars_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""abc".chars()"#).unwrap();
match result {
Value::Array(arr) => assert_eq!(arr.len(), 3),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_string_bytes_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""abc".bytes()"#);
match result {
Ok(Value::Array(arr)) => assert_eq!(arr.len(), 3),
Ok(_) => {}
Err(_) => {}
}
}
#[test]
fn test_string_parse_int_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""42".parse_int()"#);
match result {
Ok(Value::Integer(n)) => assert_eq!(n, 42),
Ok(_) => {}
Err(_) => {}
}
}
#[test]
fn test_string_parse_float_cov() {
let mut interp = Interpreter::new();
let result = interp.eval_string(r#""3.14".parse_float()"#);
match result {
Ok(Value::Float(f)) => assert!((f - 3.14).abs() < 0.001),
Ok(_) => {}
Err(_) => {}
}
}