diff --git a/examples/threads/threads.txs b/examples/threads/threads.txs index 7396bb40..34286a5d 100644 --- a/examples/threads/threads.txs +++ b/examples/threads/threads.txs @@ -6,12 +6,12 @@ spawn_fn = thread["spawn"] join_fn = thread["join"] do task_a() - time.sleep(100) + time.sleep(200) say "Task A completed on worker thread." end do task_b() - time.sleep(50) + time.sleep(10) say "Task B completed on worker thread." end diff --git a/stdlib/src/testing.rs b/stdlib/src/testing.rs index 1c180934..4162517d 100644 --- a/stdlib/src/testing.rs +++ b/stdlib/src/testing.rs @@ -160,3 +160,143 @@ impl StdlibRegistry { ); } } + +#[cfg(test)] +mod tests { + use super::*; + use techscript_runtime::RuntimeConfig; + + #[test] + fn test_register_testing() { + let mut registry = StdlibRegistry { + modules: HashMap::new(), + }; + registry.register_testing(); + + assert!(registry.has_module("std.testing")); + let module = registry.get_module("std.testing").unwrap(); + assert_eq!(module.name, "std.testing"); + assert_eq!(module.version, "1.0.0"); + assert_eq!(module.exports.len(), 6); + assert!(module.exports.contains_key("assert")); + assert!(module.exports.contains_key("assert_eq")); + assert!(module.exports.contains_key("assert_ne")); + assert!(module.exports.contains_key("mock_fn")); + assert!(module.exports.contains_key("mock_object")); + assert!(module.exports.contains_key("benchmark")); + } + + #[test] + fn test_testing_functions() { + let mut registry = StdlibRegistry { + modules: HashMap::new(), + }; + registry.register_testing(); + let module = registry.get_module("std.testing").unwrap(); + let mut ctx = RuntimeContext::new(RuntimeConfig::default()); + + // assert + let assert_fn = module.exports.get("assert").unwrap(); + assert_eq!(assert_fn.arity(), 2); + assert!(assert_fn + .call( + &mut ctx, + vec![ + RuntimeValue::Bool(true), + RuntimeValue::Str("ok".to_string()) + ] + ) + .is_ok()); + assert!(assert_fn + .call( + &mut ctx, + vec![ + RuntimeValue::Bool(false), + RuntimeValue::Str("failed".to_string()) + ] + ) + .is_err()); + + // assert_eq + let assert_eq_fn = module.exports.get("assert_eq").unwrap(); + assert_eq!(assert_eq_fn.arity(), 3); + assert!(assert_eq_fn + .call( + &mut ctx, + vec![ + RuntimeValue::Int(42), + RuntimeValue::Int(42), + RuntimeValue::Str("numbers match".to_string()) + ] + ) + .is_ok()); + assert!(assert_eq_fn + .call( + &mut ctx, + vec![ + RuntimeValue::Int(42), + RuntimeValue::Int(100), + RuntimeValue::Str("numbers differ".to_string()) + ] + ) + .is_err()); + + // assert_ne + let assert_ne_fn = module.exports.get("assert_ne").unwrap(); + assert_eq!(assert_ne_fn.arity(), 3); + assert!(assert_ne_fn + .call( + &mut ctx, + vec![ + RuntimeValue::Int(42), + RuntimeValue::Int(100), + RuntimeValue::Str("numbers differ".to_string()) + ] + ) + .is_ok()); + assert!(assert_ne_fn + .call( + &mut ctx, + vec![ + RuntimeValue::Int(42), + RuntimeValue::Int(42), + RuntimeValue::Str("numbers match".to_string()) + ] + ) + .is_err()); + + // mock_fn + let mock_fn = module.exports.get("mock_fn").unwrap(); + assert_eq!(mock_fn.arity(), 1); + let mock_res = mock_fn + .call(&mut ctx, vec![RuntimeValue::Int(123)]) + .unwrap(); + if let RuntimeValue::Function(func) = mock_res { + let res = func.call(&mut ctx, vec![]).unwrap(); + assert_eq!(res, RuntimeValue::Int(123)); + } else { + panic!("Expected RuntimeValue::Function"); + } + + // mock_object + let mock_obj_fn = module.exports.get("mock_object").unwrap(); + assert_eq!(mock_obj_fn.arity(), 1); + let obj_res = mock_obj_fn + .call(&mut ctx, vec![RuntimeValue::Str("test_obj".to_string())]) + .unwrap(); + assert_eq!(obj_res, RuntimeValue::Str("test_obj".to_string())); + + // benchmark + let bench_fn = module.exports.get("benchmark").unwrap(); + assert_eq!(bench_fn.arity(), 2); + let mock_res = mock_fn.call(&mut ctx, vec![RuntimeValue::Null]).unwrap(); + let bench_res = bench_fn + .call(&mut ctx, vec![mock_res, RuntimeValue::Int(5)]) + .unwrap(); + if let RuntimeValue::Float(elapsed) = bench_res { + assert!(elapsed >= 0.0); + } else { + panic!("Expected RuntimeValue::Float"); + } + } +}