diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2d642a..c815517 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,26 @@ jobs: - name: cargo doc run: cargo doc --no-deps + test_wasm: + name: Test (wasm) + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + steps: + - uses: actions/checkout@master + - name: Install Rust and add wasm target + run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} && rustup target add wasm32-unknown-unknown + - name: Install wasm-pack + uses: taiki-e/cache-cargo-install-action@v1 + with: + tool: wasm-pack@0.12.1 + - name: cargo test + run: wasm-pack test --firefox --headless -- --features=wasm-bindgen + - name: cargo doc + run: cargo doc --no-deps --target=wasm32-unknown-unknown --features=wasm-bindgen + style: name: Style runs-on: ubuntu-latest @@ -59,14 +79,3 @@ jobs: git -c user.name='ci' -c user.email='ci' commit -m 'Deploy futures-timer API documentation' git push -f -q https://git:${{ secrets.github_token }}@github.com/${{ github.repository }} HEAD:gh-pages if: github.event_name == 'push' && github.event.ref == 'refs/heads/master' && github.repository == 'async-rs/futures-timer' - - check_wasm: - name: Check Wasm - needs: [test] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Install Rust and add wasm target - run: rustup update stable && rustup target add wasm32-unknown-unknown - - name: cargo check - run: cargo check --target wasm32-unknown-unknown --features wasm-bindgen diff --git a/Cargo.toml b/Cargo.toml index 8bc3472..fe9a3b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,10 @@ send_wrapper = { version = "0.4.0", optional = true } [dev-dependencies] async-std = { version = "1.0.1", features = ["attributes"] } +cfg-if = "1.0.0" futures = "0.3.1" +wasm-bindgen-test = "0.3.42" +web-time = "1.1.0" [features] wasm-bindgen = [ diff --git a/src/wasm.rs b/src/wasm.rs index 0df42d2..071b1bd 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -11,13 +11,15 @@ use std::{ /// A version of `Delay` that works on wasm. #[derive(Debug)] -pub struct Delay(SendWrapper); +pub struct Delay(Option>); impl Delay { /// Creates a new future which will fire at `dur` time into the future. #[inline] pub fn new(dur: Duration) -> Delay { - Self(SendWrapper::new(TimeoutFuture::new(dur.as_millis() as u32))) + Self(Some(SendWrapper::new(TimeoutFuture::new( + dur.as_millis() as u32 + )))) } /// Resets the timeout. @@ -30,7 +32,16 @@ impl Delay { impl Future for Delay { type Output = (); - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { - Pin::new(&mut *Pin::into_inner(self).0).poll(cx) + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + match self.0.as_mut() { + Some(delay) => match Pin::new(&mut **delay).poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(()) => { + self.0.take(); + Poll::Ready(()) + } + }, + None => Poll::Ready(()), + } } } diff --git a/tests/smoke.rs b/tests/smoke.rs index b2f172e..2675195 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -1,10 +1,22 @@ use std::error::Error; use std::pin::Pin; -use std::time::{Duration, Instant}; +use std::time::Duration; +use futures::FutureExt; use futures_timer::Delay; -#[async_std::test] +cfg_if::cfg_if! { + if #[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))] { + use wasm_bindgen_test::wasm_bindgen_test as async_test; + use web_time::Instant; + wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + } else { + use std::time::Instant; + use async_std::test as async_test; + } +} + +#[async_test] async fn works() { let i = Instant::now(); let dur = Duration::from_millis(100); @@ -12,7 +24,7 @@ async fn works() { assert!(i.elapsed() > dur); } -#[async_std::test] +#[async_test] async fn reset() -> Result<(), Box> { let i = Instant::now(); let dur = Duration::from_millis(100); @@ -21,6 +33,9 @@ async fn reset() -> Result<(), Box> { // Allow us to re-use a future Pin::new(&mut d).await; + // Reusing without resetting should return immediately + Pin::new(&mut d).now_or_never().unwrap(); + assert!(i.elapsed() > dur); let i = Instant::now(); diff --git a/tests/timeout.rs b/tests/timeout.rs index 0a8798d..cd963ac 100644 --- a/tests/timeout.rs +++ b/tests/timeout.rs @@ -1,9 +1,20 @@ use std::error::Error; -use std::time::{Duration, Instant}; +use std::time::Duration; use futures_timer::Delay; -#[async_std::test] +cfg_if::cfg_if! { + if #[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))] { + use wasm_bindgen_test::wasm_bindgen_test as async_test; + use web_time::Instant; + wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + } else { + use std::time::Instant; + use async_std::test as async_test; + } +} + +#[async_test] async fn smoke() -> Result<(), Box> { let dur = Duration::from_millis(10); let start = Instant::now(); @@ -12,7 +23,7 @@ async fn smoke() -> Result<(), Box> { Ok(()) } -#[async_std::test] +#[async_test] async fn two() -> Result<(), Box> { let dur = Duration::from_millis(10); Delay::new(dur).await;