#![allow(clippy::ignore_without_reason)] #![allow(missing_docs)]
use serde_json::Value as JsonValue;
fn parse_repl_output(json: &str) -> Result<JsonValue, serde_json::Error> {
serde_json::from_str(json)
}
#[test]
fn test_wasm_repl_evaluates_arithmetic() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl.eval("1 + 2").expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true, "Evaluation should succeed");
assert_eq!(
json["display"].as_str().unwrap().trim(),
"3",
"Should display evaluated result, not AST"
);
assert!(json["error"].is_null(), "Should have no error");
}
}
#[test]
fn test_wasm_repl_function_definition() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl
.eval("fun greet(name) { \"Hello, \" + name }; greet(\"World\")")
.expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true, "Evaluation should succeed");
assert_eq!(
json["display"].as_str().unwrap().trim(),
"Hello, World",
"Should execute function and return result"
);
}
}
#[test]
fn test_wasm_repl_single_expression_evaluation() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl.eval("let x = 10; x + 5").expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true);
assert_eq!(json["display"].as_str().unwrap().trim(), "15");
}
}
#[test]
fn test_wasm_repl_syntax_error() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl
.eval("let x = ")
.expect("Eval should return error JSON");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], false, "Should fail on syntax error");
assert!(
json["error"].as_str().unwrap().contains("Parse error"),
"Error should mention parse error"
);
}
}
#[test]
fn test_wasm_repl_runtime_error() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl
.eval("undefined_variable")
.expect("Eval should return error JSON");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], false, "Should fail on undefined variable");
assert!(
json["error"].as_str().is_some(),
"Should have error message"
);
}
}
#[test]
fn test_wasm_repl_string_operations() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl
.eval("\"Hello\" + \" \" + \"World\"")
.expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true);
assert_eq!(json["display"].as_str().unwrap().trim(), "Hello World");
}
}
#[test]
fn test_wasm_repl_array_operations() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl.eval("[1, 2, 3].length()").expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true);
assert_eq!(json["display"].as_str().unwrap().trim(), "3");
}
}
#[test]
fn test_wasm_repl_match_expression() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl
.eval("match 1 { 1 => \"one\" _ => \"other\" }")
.expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true);
assert_eq!(json["display"].as_str().unwrap().trim(), "one");
}
}
#[test]
fn test_wasm_repl_loop_execution() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let code = r"
let mut sum = 0;
let mut i = 0;
loop {
if i >= 5 { break; }
sum = sum + i;
i = i + 1;
}
sum
";
let output = repl.eval(code).expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true);
assert_eq!(
json["display"].as_str().unwrap().trim(),
"10",
"0+1+2+3+4 = 10"
);
}
}
#[cfg(test)]
mod property_tests {
use super::*;
#[test]
fn proptest_integer_evaluation() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
for n in -100..100 {
let mut repl = WasmRepl::new().expect("Failed to create REPL");
let output = repl.eval(&n.to_string()).expect("Eval failed");
let json: JsonValue = parse_repl_output(&output).expect("Invalid JSON");
assert_eq!(json["success"], true, "Integer {n} should evaluate");
assert_eq!(
json["display"].as_str().unwrap().trim(),
n.to_string(),
"Integer {n} should display correctly"
);
}
}
}
#[test]
fn proptest_arithmetic_commutativity() {
#[cfg(not(target_arch = "wasm32"))]
{
use ruchy::wasm::repl::WasmRepl;
for a in 0..20 {
for b in 0..20 {
let mut repl1 = WasmRepl::new().expect("Failed to create REPL");
let mut repl2 = WasmRepl::new().expect("Failed to create REPL");
let expr1 = format!("{a} + {b}");
let expr2 = format!("{b} + {a}");
let out1 = repl1.eval(&expr1).expect("Eval failed");
let out2 = repl2.eval(&expr2).expect("Eval failed");
let json1: JsonValue = parse_repl_output(&out1).expect("Invalid JSON");
let json2: JsonValue = parse_repl_output(&out2).expect("Invalid JSON");
assert_eq!(
json1["display"], json2["display"],
"{a} + {b} should equal {b} + {a}"
);
}
}
}
}
}