extern crate desync;
extern crate futures;
use desync::Desync;
use wasm_bindgen_test::*;
mod scheduler;
use self::scheduler::timeout::*;
use futures::prelude::*;
use futures::future;
use std::sync::*;
use std::time::*;
use std::thread::*;
#[derive(Debug)]
struct TestData {
val: u32
}
#[test]
#[wasm_bindgen_test]
fn retrieve_data_synchronously() {
let desynced = Desync::new(TestData { val: 0 });
assert!(desynced.sync(|data| data.val) == 0);
}
#[test]
#[wasm_bindgen_test]
fn retrieve_data_into_local_var() {
let desynced = Desync::new(TestData { val: 42 });
let mut val = 0;
desynced.sync(|data| val = data.val);
assert!(val == 42);
}
#[test]
#[wasm_bindgen_test]
fn update_data_asynchronously() {
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
sleep(Duration::from_millis(100));
data.val = 42;
});
assert!(desynced.sync(|data| data.val) == 42);
}
#[test]
#[wasm_bindgen_test]
#[cfg(not(miri))] fn update_data_asynchronously_1000_times() {
for _i in 0..1000 {
timeout(|| {
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
data.val = 42;
});
desynced.desync(|data| {
data.val = 43;
});
assert!(desynced.sync(|data| data.val) == 43);
}, 500);
}
}
#[test]
#[wasm_bindgen_test]
fn update_data_with_future() {
timeout(|| {
use futures::executor;
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
sleep(Duration::from_millis(100));
data.val = 42;
});
executor::block_on(async {
let future = desynced.future_desync(|data| { future::ready(data.val) }.boxed());
assert!(future.await.unwrap() == 42);
});
}, 500);
}
#[test]
#[wasm_bindgen_test]
#[cfg(not(miri))] fn update_data_with_future_1000_times() {
use futures::executor;
for _i in 0..1000 {
timeout(|| {
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
data.val = 42;
});
desynced.desync(|data| {
data.val = 43;
});
executor::block_on(async {
let future = desynced.future_desync(|data| Box::pin(future::ready(data.val)));
assert!(future.await.unwrap() == 43);
});
}, 500);
}
}
#[test]
#[wasm_bindgen_test]
fn update_data_with_future_sync() {
timeout(|| {
use futures::executor;
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
sleep(Duration::from_millis(100));
data.val = 42;
});
executor::block_on(async {
let future = desynced.future_sync(|data| { future::ready(data.val) }.boxed());
assert!(future.await.unwrap() == 42);
});
}, 500);
}
#[test]
#[wasm_bindgen_test]
#[cfg(not(miri))] fn update_data_with_future_sync_1000_times() {
use futures::executor;
for _i in 0..1000 {
timeout(|| {
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
data.val = 42;
});
desynced.desync(|data| {
data.val = 43;
});
executor::block_on(async {
let future = desynced.future_sync(|data| future::ready(data.val).boxed());
assert!(future.await.unwrap() == 43);
});
}, 500);
}
}
#[test]
#[wasm_bindgen_test]
fn dropping_while_running_isnt_obviously_bad() {
let desynced = Desync::new(TestData { val: 0 });
desynced.desync(|data| {
sleep(Duration::from_millis(100));
data.val = 42;
});
desynced.desync(|data| {
sleep(Duration::from_millis(100));
data.val = 42;
});
}
#[test]
#[wasm_bindgen_test]
fn wait_for_future() {
timeout(|| {
use futures::executor;
use futures::channel::oneshot;
let desynced = Desync::new(0);
let (future_tx, future_rx) = oneshot::channel();
desynced.desync(|val| {
sleep(Duration::from_millis(100));
assert!(*val == 0);
*val = 1;
});
let future = desynced.after(future_rx, |val, future_result| {
assert!(*val == 1);
*val = future_result.unwrap();
4
});
desynced.desync(move |val| { assert!(*val == 2); *val = 3 });
executor::block_on(async {
future_tx.send(2).unwrap();
assert!(future.await == Ok(4));
assert!(desynced.sync(|val| *val) == 3);
})
}, 500);
}
#[test]
fn future_and_sync() {
sleep(Duration::from_millis(1000));
use std::thread;
use futures::channel::oneshot;
let (send, recv) = oneshot::channel::<i32>();
let core = Desync::new(0);
let sync_request = Desync::new(None);
let _ = sync_request.future_desync(move |data| {
async move {
let result = core.future_desync(move |_core| {
async move {
Some(recv.await.unwrap())
}.boxed()
}).await;
*data = result.unwrap();
}.boxed()
});
thread::spawn(move || {
thread::sleep(Duration::from_millis(50));
send.send(42).ok();
});
let result = sync_request.sync(|req| req.take());
assert!(result == Some(42));
}
#[test]
#[wasm_bindgen_test]
fn double_future_and_sync() {
use std::thread;
let core = Arc::new(Desync::new(()));
let initiator_1 = Desync::new(None);
let initiator_2 = Desync::new(None);
let initiator_3 = Desync::new(None);
let core_1 = Arc::clone(&core);
initiator_1.future_desync(move |val| {
async move {
*val = core_1.future_desync(move |_| {
async move { thread::sleep(Duration::from_millis(400)); Some(1) }.boxed()
}).await.unwrap();
}.boxed()
}).detach();
let core_2 = Arc::clone(&core);
initiator_2.future_desync(move |val| {
async move {
thread::sleep(Duration::from_millis(100));
*val = core_2.future_desync(move |_| {
async move { thread::sleep(Duration::from_millis(200)); Some(2) }.boxed()
}).await.unwrap();
}.boxed()
}).detach();
let core_3 = Arc::clone(&core);
initiator_3.future_desync(move |val| {
async move {
thread::sleep(Duration::from_millis(200));
*val = core_3.future_desync(move |_| {
async move { thread::sleep(Duration::from_millis(200)); Some(3) }.boxed()
}).await.unwrap();
}.boxed()
}).detach();
assert!(initiator_3.sync(|val| { *val }) == Some(3));
assert!(initiator_2.sync(|val| { *val }) == Some(2));
assert!(initiator_1.sync(|val| { *val }) == Some(1));
}
#[test]
#[wasm_bindgen_test]
fn try_sync_succeeds_on_idle_queue() {
timeout(|| {
let core = Desync::new(0);
let sync_result = core.try_sync(|val| {
*val = 42;
1
});
assert!(sync_result == Ok(1));
assert!(core.sync(|val| *val) == 42);
}, 500);
}
#[test]
#[wasm_bindgen_test]
fn try_sync_succeeds_on_idle_queue_after_async_job() {
timeout(|| {
use std::thread;
let core = Desync::new(0);
core.desync(|_val| thread::sleep(Duration::from_millis(50)));
core.sync(|_val| { });
let sync_result = core.try_sync(|val| {
*val= 42;
1
});
assert!(sync_result == Ok(1));
assert!(core.sync(|val| *val) == 42);
}, 500);
}
#[test]
#[wasm_bindgen_test]
fn try_sync_fails_on_busy_queue() {
timeout(|| {
use std::sync::mpsc::*;
let core = Desync::new(0);
let (tx, rx) = channel();
core.desync(move |_val| { rx.recv().ok(); });
let sync_result = core.try_sync(|val| {
*val = 42;
1
});
assert!(sync_result.is_err());
tx.send(1).ok();
assert!((core.sync(|val| *val)) == 0);
}, 500);
}