feat: expand standard library with Math module and new functions

- Add Math module: abs, min, max, sqrt, pow, floor, ceil, round
- Add List functions: isEmpty, find, any, all, take, drop
- Add String functions: startsWith, endsWith, toUpper, toLower, substring
- Add 12 tests for new standard library functions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 10:15:14 -05:00
parent 4eebaebb27
commit 961a861822
3 changed files with 507 additions and 0 deletions

View File

@@ -1377,6 +1377,110 @@ c")"#;
assert!(result.is_err());
assert!(result.unwrap_err().contains("downgrade"));
}
// Math module tests
#[test]
fn test_math_abs() {
let (result, _) = run_with_effects("let x = Math.abs(-42)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "42");
let (result, _) = run_with_effects("let x = Math.abs(42)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "42");
}
#[test]
fn test_math_min_max() {
let (result, _) = run_with_effects("let x = Math.min(3, 7)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "3");
let (result, _) = run_with_effects("let x = Math.max(3, 7)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "7");
}
#[test]
fn test_math_sqrt() {
let (result, _) = run_with_effects("let x = Math.sqrt(16)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "4");
}
#[test]
fn test_math_pow() {
let (result, _) = run_with_effects("let x = Math.pow(2, 10)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "1024");
}
#[test]
fn test_math_floor_ceil_round() {
let (result, _) = run_with_effects("let x = Math.floor(3.7)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "3");
let (result, _) = run_with_effects("let x = Math.ceil(3.2)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "4");
let (result, _) = run_with_effects("let x = Math.round(3.5)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "4");
}
// List module additional functions
#[test]
fn test_list_is_empty() {
let (result, _) = run_with_effects("let x = List.isEmpty([])", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "true");
let (result, _) = run_with_effects("let x = List.isEmpty([1, 2])", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "false");
}
#[test]
fn test_list_find() {
let source = "let x = List.find([1, 2, 3, 4, 5], fn(x: Int): Bool => x > 3)";
let (result, _) = run_with_effects(source, Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "Some(4)");
let source = "let x = List.find([1, 2, 3], fn(x: Int): Bool => x > 10)";
let (result, _) = run_with_effects(source, Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "None");
}
#[test]
fn test_list_any_all() {
let source = "let x = List.any([1, 2, 3], fn(x: Int): Bool => x > 2)";
let (result, _) = run_with_effects(source, Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "true");
let source = "let x = List.all([1, 2, 3], fn(x: Int): Bool => x > 0)";
let (result, _) = run_with_effects(source, Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "true");
let source = "let x = List.all([1, 2, 3], fn(x: Int): Bool => x > 2)";
let (result, _) = run_with_effects(source, Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "false");
}
#[test]
fn test_list_take_drop() {
let (result, _) = run_with_effects("let x = List.take([1, 2, 3, 4, 5], 3)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "[1, 2, 3]");
let (result, _) = run_with_effects("let x = List.drop([1, 2, 3, 4, 5], 2)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "[3, 4, 5]");
}
// String module additional functions
#[test]
fn test_string_starts_ends_with() {
let (result, _) = run_with_effects("let x = String.startsWith(\"hello\", \"he\")", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "true");
let (result, _) = run_with_effects("let x = String.endsWith(\"hello\", \"lo\")", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "true");
}
#[test]
fn test_string_case_conversion() {
let (result, _) = run_with_effects("let x = String.toUpper(\"hello\")", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "\"HELLO\"");
let (result, _) = run_with_effects("let x = String.toLower(\"HELLO\")", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "\"hello\"");
}
#[test]
fn test_string_substring() {
let (result, _) = run_with_effects("let x = String.substring(\"hello world\", 0, 5)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "\"hello\"");
let (result, _) = run_with_effects("let x = String.substring(\"hello\", 2, 4)", Value::Unit, Value::Unit).unwrap();
assert_eq!(result, "\"ll\"");
}
}
// Diagnostic rendering tests