#[cfg(test)]
mod format_blots_tests {
use crate::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn test_format_blots_simple() {
let source = "x = [1, 2, 3]";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(formatted, "x = [1, 2, 3]");
}
#[wasm_bindgen_test]
fn test_format_blots_multiline() {
let source = "{name: \"Alice\", age: 30, email: \"alice@example.com\", address: \"123 Main Street\"}";
let result = format_blots(source, Some(30)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(formatted.contains("\n"));
assert!(formatted.contains("{"));
}
#[wasm_bindgen_test]
fn test_format_blots_preserves_comments() {
let source = "// This is a comment\nx = [1, 2, 3]\n// Another comment\ny = x + 1";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(formatted.contains("// This is a comment"));
assert!(formatted.contains("// Another comment"));
assert!(formatted.contains("x = [1, 2, 3]"));
assert!(formatted.contains("y = x + 1"));
}
#[wasm_bindgen_test]
fn test_format_blots_default_max_columns() {
let source = "x = 1";
let result = format_blots(source, None).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(formatted, "x = 1");
}
#[wasm_bindgen_test]
fn test_format_blots_invalid_syntax() {
let source = "x = [1, 2,";
let result = format_blots(source, Some(80));
assert!(result.is_err());
}
#[wasm_bindgen_test]
fn test_format_blots_multiple_statements() {
let source = "x = 1\ny = 2\nz = x + y";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
let lines: Vec<&str> = formatted.lines().collect();
assert_eq!(lines.len(), 3);
assert_eq!(lines[0], "x = 1");
assert_eq!(lines[1], "y = 2");
assert_eq!(lines[2], "z = x + y");
}
#[wasm_bindgen_test]
fn test_format_blots_end_of_line_comments() {
let source = "x = 5 // this is a comment\ny = 10";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
let lines: Vec<&str> = formatted.lines().collect();
assert_eq!(lines.len(), 2);
assert_eq!(lines[0], "x = 5 // this is a comment");
assert_eq!(lines[1], "y = 10");
}
#[wasm_bindgen_test]
fn test_format_blots_mixed_comments() {
let source = "// standalone comment\nx = 1 // end-of-line comment\ny = 2";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
let lines: Vec<&str> = formatted.lines().collect();
assert_eq!(lines.len(), 3);
assert_eq!(lines[0], "// standalone comment");
assert_eq!(lines[1], "x = 1 // end-of-line comment");
assert_eq!(lines[2], "y = 2");
}
#[wasm_bindgen_test]
fn test_format_blots_preserves_empty_lines() {
let source = "x = 1\n\ny = 2\n\n\n\nz = 3";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(formatted, "x = 1\n\ny = 2\n\n\nz = 3");
let lines: Vec<&str> = formatted.lines().collect();
assert_eq!(lines.len(), 6); }
#[wasm_bindgen_test]
fn test_format_blots_no_empty_lines() {
let source = "x = 1\ny = 2\nz = 3";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(formatted, "x = 1\ny = 2\nz = 3");
let lines: Vec<&str> = formatted.lines().collect();
assert_eq!(lines.len(), 3);
}
#[wasm_bindgen_test]
fn test_format_blots_preserves_output_keyword() {
let source = "output x = 42\noutput y = [1, 2, 3]\nz = 10";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(formatted.contains("output x = 42"));
assert!(formatted.contains("output y = [1, 2, 3]"));
assert!(formatted.contains("z = 10"));
let lines: Vec<&str> = formatted.lines().collect();
assert_eq!(lines.len(), 3);
assert_eq!(lines[0], "output x = 42");
assert_eq!(lines[1], "output y = [1, 2, 3]");
assert_eq!(lines[2], "z = 10");
}
#[wasm_bindgen_test]
fn test_format_blots_output_with_via() {
let source = "output result = items via i => i * 2";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(formatted.contains("output result = items via"));
assert!(formatted.starts_with("output result"));
}
#[wasm_bindgen_test]
fn test_format_blots_comments_inside_list() {
let source = "[\n// leading comment\n1,\n2, // trailing comment\n]";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(
formatted.contains("// leading comment"),
"Leading comment inside list should be preserved. Got: {}",
formatted
);
assert!(
formatted.contains("// trailing comment"),
"Trailing comment inside list should be preserved. Got: {}",
formatted
);
}
#[wasm_bindgen_test]
fn test_format_blots_comments_inside_record() {
let source = "{\n// leading comment\na: 1,\nb: 2, // trailing comment\n}";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(
formatted.contains("// leading comment"),
"Leading comment inside record should be preserved. Got: {}",
formatted
);
assert!(
formatted.contains("// trailing comment"),
"Trailing comment inside record should be preserved. Got: {}",
formatted
);
}
#[wasm_bindgen_test]
fn test_format_blots_comments_inside_nested_structures() {
let source = "{\n items: [\n // first item\n 1,\n 2, // second\n ],\n}";
let result = format_blots(source, Some(80)).unwrap();
let formatted: String = serde_wasm_bindgen::from_value(result).unwrap();
assert!(
formatted.contains("// first item"),
"Comment in nested list should be preserved. Got: {}",
formatted
);
assert!(
formatted.contains("// second"),
"Trailing comment in nested list should be preserved. Got: {}",
formatted
);
}
}
#[cfg(test)]
mod evaluate_tests {
use crate::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn test_evaluate_simple_expression() {
let source = "output result = 1 + 2";
let inputs = serde_wasm_bindgen::to_value(&serde_json::json!({})).unwrap();
let result = evaluate(source, inputs).unwrap();
let result_obj: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(result_obj["outputs"], serde_json::json!(["result"]));
}
#[wasm_bindgen_test]
fn test_evaluate_with_inputs() {
let source = "output doubled = inputs.x * 2";
use indexmap::IndexMap;
let mut inputs_map: IndexMap<String, SerializableValue> = IndexMap::new();
inputs_map.insert("x".to_string(), SerializableValue::Number(5.0));
let inputs = serde_wasm_bindgen::to_value(&inputs_map).unwrap();
let result = evaluate(source, inputs).unwrap();
let result_obj: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(result_obj["outputs"], serde_json::json!(["doubled"]));
let bindings = &result_obj["bindings"];
assert_eq!(bindings["doubled"]["Number"], serde_json::json!(10));
}
#[wasm_bindgen_test]
fn test_evaluate_input_reference() {
let source = "output result = inputs.x + inputs.y";
use indexmap::IndexMap;
let mut inputs_map: IndexMap<String, SerializableValue> = IndexMap::new();
inputs_map.insert("x".to_string(), SerializableValue::Number(3.0));
inputs_map.insert("y".to_string(), SerializableValue::Number(7.0));
let inputs = serde_wasm_bindgen::to_value(&inputs_map).unwrap();
let result = evaluate(source, inputs).unwrap();
let result_obj: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(
result_obj["bindings"]["result"]["Number"],
serde_json::json!(10)
);
}
#[wasm_bindgen_test]
fn test_evaluate_list_operations() {
let source = "output result = [1, 2, 3] + [4, 5, 6]";
let inputs = serde_wasm_bindgen::to_value(&serde_json::json!({})).unwrap();
let result = evaluate(source, inputs).unwrap();
let result_obj: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert!(result_obj["bindings"]["result"]["List"].is_array());
let list = &result_obj["bindings"]["result"]["List"];
assert_eq!(list[0]["Number"], serde_json::json!(5));
assert_eq!(list[1]["Number"], serde_json::json!(7));
assert_eq!(list[2]["Number"], serde_json::json!(9));
}
#[wasm_bindgen_test]
fn test_evaluate_multiline_source() {
let source = "x = inputs.a * 2\ny = inputs.b + 10\noutput result = x + y";
use indexmap::IndexMap;
let mut inputs_map: IndexMap<String, SerializableValue> = IndexMap::new();
inputs_map.insert("a".to_string(), SerializableValue::Number(5.0));
inputs_map.insert("b".to_string(), SerializableValue::Number(3.0));
let inputs = serde_wasm_bindgen::to_value(&inputs_map).unwrap();
let result = evaluate(source, inputs).unwrap();
let result_obj: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(result_obj["outputs"], serde_json::json!(["result"]));
assert_eq!(
result_obj["bindings"]["result"]["Number"],
serde_json::json!(23)
);
assert_eq!(result_obj["bindings"]["x"]["Number"], serde_json::json!(10));
assert_eq!(result_obj["bindings"]["y"]["Number"], serde_json::json!(13));
}
#[wasm_bindgen_test]
fn test_evaluate_multiline_with_comments() {
let source = "x = inputs.a * 2\ny = inputs.b + 10\n\n// hi\noutput result = x + y";
use indexmap::IndexMap;
let mut inputs_map: IndexMap<String, SerializableValue> = IndexMap::new();
inputs_map.insert("a".to_string(), SerializableValue::Number(5.0));
inputs_map.insert("b".to_string(), SerializableValue::Number(3.0));
let inputs = serde_wasm_bindgen::to_value(&inputs_map).unwrap();
let result = evaluate(source, inputs).unwrap();
let result_obj: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(result_obj["outputs"], serde_json::json!(["result"]));
assert_eq!(
result_obj["bindings"]["result"]["Number"],
serde_json::json!(23)
);
}
#[wasm_bindgen_test]
fn test_evaluate_invalid_syntax() {
let source = "output result = 1 +";
let inputs = serde_wasm_bindgen::to_value(&serde_json::json!({})).unwrap();
let result = evaluate(source, inputs);
assert!(result.is_err());
}
}
#[cfg(test)]
mod tokenize_tests {
use crate::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn test_tokenize_simple() {
let source = "1 + 2";
let result = tokenize(source).unwrap();
let tokens: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert!(!tokens.is_empty());
}
#[wasm_bindgen_test]
fn test_tokenize_with_identifiers() {
let source = "x = 42";
let result = tokenize(source).unwrap();
let tokens: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert!(!tokens.is_empty());
}
#[wasm_bindgen_test]
fn test_tokenize_complex_expression() {
let source = "[1, 2, 3] + [4, 5, 6]";
let result = tokenize(source).unwrap();
let tokens: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert!(!tokens.is_empty());
}
}
#[cfg(test)]
mod get_built_in_function_names_tests {
use crate::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn test_get_built_in_function_names() {
let result = get_built_in_function_names().unwrap();
let names: Vec<String> = serde_wasm_bindgen::from_value(result).unwrap();
assert!(!names.is_empty());
assert!(names.contains(&"map".to_string()));
assert!(names.contains(&"filter".to_string()));
assert!(names.contains(&"reduce".to_string()));
assert!(names.contains(&"sum".to_string()));
}
}
#[cfg(test)]
mod get_constants_tests {
use crate::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn test_get_constants() {
let result = get_constants().unwrap();
let constants: serde_json::Value = serde_wasm_bindgen::from_value(result).unwrap();
assert!(constants["constants"].is_object());
let const_obj = &constants["constants"]["Record"];
assert!(const_obj["pi"]["Number"].is_number());
assert!(const_obj["e"]["Number"].is_number());
}
}
#[cfg(test)]
mod evaluate_inline_expressions_tests {
use crate::*;
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn test_evaluate_inline_expressions_single() {
let expressions = serde_wasm_bindgen::to_value(&vec!["1 + 2"]).unwrap();
let inputs = serde_wasm_bindgen::to_value(&serde_json::json!({})).unwrap();
let result = evaluate_inline_expressions(expressions, inputs).unwrap();
let results: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0]["value"]["Number"], serde_json::json!(3));
}
#[wasm_bindgen_test]
fn test_evaluate_inline_expressions_multiple() {
let expressions = serde_wasm_bindgen::to_value(&vec!["x * 2", "x + 5", "x - 1"]).unwrap();
use indexmap::IndexMap;
let mut inputs_map: IndexMap<String, SerializableValue> = IndexMap::new();
inputs_map.insert("x".to_string(), SerializableValue::Number(10.0));
let inputs = serde_wasm_bindgen::to_value(&inputs_map).unwrap();
let result = evaluate_inline_expressions(expressions, inputs).unwrap();
let results: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(results.len(), 3);
assert_eq!(results[0]["value"]["Number"], serde_json::json!(20));
assert_eq!(results[1]["value"]["Number"], serde_json::json!(15));
assert_eq!(results[2]["value"]["Number"], serde_json::json!(9));
}
#[wasm_bindgen_test]
fn test_evaluate_inline_expressions_with_error() {
let expressions = serde_wasm_bindgen::to_value(&vec!["1 + 2", "invalid +"]).unwrap();
let inputs = serde_wasm_bindgen::to_value(&serde_json::json!({})).unwrap();
let result = evaluate_inline_expressions(expressions, inputs).unwrap();
let results: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(results.len(), 2);
assert_eq!(results[0]["value"]["Number"], serde_json::json!(3));
assert!(results[1]["error"].is_string());
}
#[wasm_bindgen_test]
fn test_evaluate_inline_expressions_with_inputs() {
let expressions =
serde_wasm_bindgen::to_value(&vec!["\"Hello, \" + name", "age >= 18"]).unwrap();
use indexmap::IndexMap;
let mut inputs_map: IndexMap<String, SerializableValue> = IndexMap::new();
inputs_map.insert(
"name".to_string(),
SerializableValue::String("Alice".to_string()),
);
inputs_map.insert("age".to_string(), SerializableValue::Number(30.0));
let inputs = serde_wasm_bindgen::to_value(&inputs_map).unwrap();
let result = evaluate_inline_expressions(expressions, inputs).unwrap();
let results: Vec<serde_json::Value> = serde_wasm_bindgen::from_value(result).unwrap();
assert_eq!(results.len(), 2);
assert_eq!(
results[0]["value"]["String"],
serde_json::json!("Hello, Alice")
);
assert_eq!(results[1]["value"]["Bool"], serde_json::json!(true));
}
}