#[macro_use]
extern crate generator;
use generator::*;
#[test]
fn generator_is_done() {
let mut g = Gn::<()>::new(||{
_yield_!();
});
g.next();
assert!(!g.is_done());
g.next();
assert!(g.is_done());
}
#[test]
fn test_yield() {
let mut g = Gn::new(|| {
_yield_!(10);
20
});
let i = g.send(());
assert!(i == 10);
let j = g.next();
assert!(j.unwrap() == 20);
}
#[test]
#[should_panic]
fn test_yield_with_type_error() {
let mut g = Gn::<()>::new(|| {
yield_with(10u32);
20i32
});
g.next();
}
#[test]
#[should_panic]
fn test_get_yield_type_error() {
let mut g = Gn::<u32>::new(|| {
get_yield::<i32>();
});
g.send(10);
}
#[test]
#[should_panic]
fn test_deep_yield_with_type_error() {
let mut g = Gn::<()>::new(|| {
let mut g = Gn::<()>::new(|| {
yield_with(0);
});
g.next();
});
g.next();
}
#[test]
fn test_scoped() {
use std::rc::Rc;
use std::cell::RefCell;
let x = Rc::new(RefCell::new(10));
let x1 = x.clone();
let mut g = Gn::<()>::new(move || {
*x1.borrow_mut() = 20;
_yield_!();
*x1.borrow_mut() = 5;
});
g.next();
assert!(*x.borrow() == 20);
g.next();
assert!(*x.borrow() == 5);
assert!(g.is_done());
}
#[test]
fn test_scoped_1() {
let mut x = 10;
{
let mut g = Gn::<()>::new(|| {
x = 5;
});
g.next();
}
assert!(x == 5);
}
#[test]
fn test_inner_ref() {
use std::mem;
let mut g = Gn::<()>::new(||-> &mut u32 {
let mut x: u32 = 10;
{
let y: &mut u32 = unsafe { mem::transmute(&mut x) };
_yield_!(y);
}
assert!(x == 5);
unsafe { mem::transmute(&mut x) }
});
let a = g.next().unwrap();
assert!(*a == 10);
*a = 5;
}
#[test]
fn test_drop() {
let mut x = 10;
{
Gn::<()>::new(|| {
x = 1;
_yield_!();
x = 5;
});
}
assert!(x == 5);
}
#[test]
fn test_ill_drop() {
let mut x = 10u32;
{
Gn::<u32>::new(|| {
x = 5;
x = _yield!();
});
}
assert!(x == 5);
}
#[test]
fn test_loop_drop() {
let mut x = 10u32;
{
Gn::<()>::new(|| {
x = 5;
loop {
_yield_!();
}
});
}
assert!(x == 5);
}
#[test]
fn test_panic_inside() {
let mut x = 10;
{
Gn::<()>::new(|| {
x = 5;
panic!("panic inside!");
});
}
assert!(x == 5);
}
#[test]
#[allow(unreachable_code)]
fn test_cancel() {
let mut g = Gn::<()>::new(|| {
let mut i = 0;
loop {
_yield_!(i);
i += 1;
}
i
});
loop {
let i = g.next().unwrap();
if i > 10 {
g.cancel();
break;
}
}
assert!(g.is_done());
}
#[test]
#[should_panic]
fn test_yield_from_functor_context() {
yield_with(0);
}
#[test]
fn test_yield_from_generator_context() {
let mut g = Gn::<()>::new(|| {
let mut g1 = Gn::<()>::new(|| {
yield_with(5);
10
});
let i = g1.send(());
yield_with(i);
0
});
let n = g.send(());
assert!(n == 5);
let n = g.send(());
assert!(n == 0);
}
#[test]
fn test_yield_from() {
let mut g = Gn::<()>::new(|| {
let g1 = Gn::<()>::new(|| {
yield_with(5);
10
});
yield_from(g1);
0
});
let n = g.send(());
assert!(n == 5);
let n = g.send(());
assert!(n == 10);
let n = g.send(());
assert!(n == 0);
assert!(g.is_done());
}
#[test]
fn test_yield_from_send() {
let mut g = Gn::<u32>::new(|| {
let g1 = Gn::<u32>::new(|| {
let mut i: u32 = _yield!(1u32);
i = _yield!(i * 2);
i * 2
});
yield_from(g1);
0u32
});
let n = g.send(3);
assert!(n == 1);
let n = g.send(4);
assert!(n == 6);
let n = g.send(10);
assert!(n == 8);
let n = g.send(0);
assert!(n == 0);
assert!(g.is_done());
}
#[test]
#[should_panic]
fn test_yield_from_send_type_miss_match() {
let mut g = Gn::<u32>::new(|| {
let g1 = Gn::<u32>::new(|| {
let mut i: u32 = _yield!(1u32);
i = _yield!(i * 2);
i * 2
});
yield_from(g1);
0
});
let n = g.send(3);
assert!(n == 1);
let n = g.send(4);
assert!(n == 6);
let n = g.send(10);
assert!(n == 8);
let n = g.send(0);
assert!(n == 0);
assert!(g.is_done());
}
#[test]
#[should_panic]
fn test_stack_overflow() {
let clo = || {
println!("this would overflow the stack");
};
Gn::<()>::new_opt(clo, 100);
}