mod tools; use tools::*; #[test] fn fundamental_usage() { let source = program!({ use spork::*; fn test() {} pub fn main() { let mut table = DispatchTable::new(); table.insert(test); spork(table); Builder::new().spawn(test, ()).unwrap().join().unwrap(); } }); let (stdout, stderr) = tools::run_program(source, ""); assert_eq!(stdout, ""); assert_eq!(stderr, ""); } #[test] fn demo_add_function() { let source = program!({ use spork::*; fn add(a: i32, b: i32) -> i32 { a + b } pub fn main() { let mut table = DispatchTable::new(); table.insert(add); spork(table); assert_eq!(spawn!(|| add(1, 2)).unwrap().join().unwrap(), 3); } }); let (stdout, stderr) = tools::run_program(source, ""); assert_eq!(stdout, ""); assert_eq!(stderr, ""); } #[test] fn closure() { let source = program!({ use spork::*; pub fn main() { let add = |a, b| a + b; let mut table = DispatchTable::new(); table.insert(add); spork(table); assert_eq!(spawn!(|| add(1, 2)).unwrap().join().unwrap(), 3); } }); let (stdout, stderr) = tools::run_program(source, ""); assert_eq!(stdout, ""); assert_eq!(stderr, ""); } #[test] fn move_closure() { let source = program!({ use spork::*; pub fn main() { let x = "hello ".to_owned(); let add = |a: String| x + &a; let add_handle = CallableHandle::of(&add); let mut table = DispatchTable::new(); table.insert(add); spork(table); assert_eq!( spawn!(|| ref add_handle("world".into())) .unwrap() .join() .unwrap(), "hello world" ); } }); let (stdout, stderr) = tools::run_program(source, ""); assert_eq!(stdout, ""); assert_eq!(stderr, ""); } #[test] fn many() { let source = program!({ use spork::*; pub fn test_a() {} pub fn test_b(x: u32) -> u32 { x } pub fn test_c(x: f32) -> f32 { x } pub fn test_d(x: String) -> String { x } pub fn main() { let mut table = DispatchTable::new(); table.insert(test_a); table.insert(test_b); table.insert(test_c); table.insert(test_d); spork(table); spawn!(|| test_a()).unwrap().join().unwrap(); assert_eq!(spawn!(|| test_b(42)).unwrap().join().unwrap(), 42); assert_eq!(spawn!(|| test_c(12.3)).unwrap().join().unwrap(), 12.3); assert_eq!( spawn!(|| test_d("Hello, world!".into())) .unwrap() .join() .unwrap(), "Hello, world!" ); } }); let (stdout, stderr) = tools::run_program(source, ""); assert_eq!(stdout, ""); assert_eq!(stderr, ""); } #[test] fn nested() { let source = program!({ use spork::*; pub fn recurse(level: usize) { if level > 0 { spawn!(|| recurse(level - 1)).unwrap().join().unwrap() } println!("Level {}", level); } pub fn main() { let mut table = DispatchTable::new(); table.insert(recurse); spork(table); spawn!(|| recurse(10)).unwrap().join().unwrap(); } }); let (stdout, stderr) = tools::run_program(source, ""); assert_eq!( stdout, "\ Level 0\n\ Level 1\n\ Level 2\n\ Level 3\n\ Level 4\n\ Level 5\n\ Level 6\n\ Level 7\n\ Level 8\n\ Level 9\n\ Level 10\n\ " ); assert_eq!(stderr, ""); } #[test] fn child_panic_but_caught() { let source = program!({ use spork::*; fn add(a: i32, b: i32) -> i32 { going_to_catch_unwind(|| { let _ = std::panic::catch_unwind(|| { panic!("test panic"); }); }); a + b } pub fn main() { let mut table = DispatchTable::new(); table.insert(add); spork(table); assert_eq!(spawn!(|| add(1, 2)).unwrap().join().unwrap(), 3); } }); let (stdout, stderr) = run_program(source, ""); if !stderr.contains("test panic") { panic!( "Missing error message. stdout: {}\nstderr: {}", stdout, stderr ); } }