cunarist / tokio-with-wasm

Mimicking tokio functionalies on web browsers
MIT License
42 stars 4 forks source link

[Question] How would I use this in running tests? #3

Open dannytoomey opened 4 months ago

dannytoomey commented 4 months ago

Hello! Thank you for this project, I see a great need for it!

I'm trying to run a test using this package and I'm having trouble understanding how to set the wasm-bindgen target to web. Here is the commend I tried -

wasm-pack test --node --test wasm --target web

Which gave me the following error -

Error loading target specification: Could not find specification for target "web"

My test is in the wasm file specified in the -- test flag. This test uses the #[wasm_bindgen_test] decorator, if relevant. The function it tests calls tokio::task::spawn_blocking and is wrapped in the #[wasm_bindgen] and #[no_mangle] decorators.

Thanks for your help!

temeddix commented 4 months ago

Hi @dannytoomey , welcome :)

Could you try putting the target in front of other arguments?

Like this:

wasm-pack test --target web --node --test wasm

If this doesn't work, please let me know.

dannytoomey commented 4 months ago

Thanks so much for your prompt reply @temeddix ! That did not work, unfortunately. Here's the error I received:

Error: Must specify at least one of `--node`, `--chrome`, `--firefox`, or `--safari`
Caused by: Must specify at least one of `--node`, `--chrome`, `--firefox`, or `--safari`
temeddix commented 4 months ago

FYI, I will share the command that actually works though it's not for tests.(It's being used in Rinf)

wasm-pack --quiet build ./my_crate --out-dir ./output --no-typescript --target web -- -Z build-std=std,panic_abort

I'm not really experienced in wasm-pack with test code, but I'll try to share the solution after searching for it.

dannytoomey commented 4 months ago

Thanks! That does work for builds, though it does not appear to work for tests. In case it's useful, here's a little more context on what I'm trying to do.

I'm making a demo for learning purposes to understand how WebAssembly works. I'm testing performance with the following Fibonacci function, which I'm hoping to use tokio_with_wasm to run asynchronously.

use tokio_with_wasm::tokio;
use wasm_bindgen::prelude::*;

#[no_mangle]
pub fn fib_rs(n: u32) -> u32 {
    if n <= 1 {
        return n;
    } else {
        return fib_rs(n - 1) + fib_rs(n - 2);
    }
}

#[wasm_bindgen]
#[no_mangle]
pub async fn get_fibs_tokio_wasm(n1: u32, n2: u32) -> u32 {
    let fut_1 = tokio::task::spawn_blocking(move || fib_rs(n1));
    let fut_2 = tokio::task::spawn_blocking(move || fib_rs(n2));
    let fib_1 = fut_1.await.unwrap();
    let fib_2 = fut_2.await.unwrap();
    return fib_1 + fib_2;
}

I'm able to test with with cargo test, but since it requires tokio to run, I'm hoping to stick to #[wasm_bindgen_test] so I can do everything in the wasm runtime. I'm trying to test the above function with the following test.

#[wasm_bindgen_test]
async fn test_get_fibs_tokio_wasm_exec() {
    let n = 35;
    let now = std::time::Instant::now();
    {
        let _ = fib_rs(n);
        let _ = fib_rs(n);
    }
    let single_elapsed = now.elapsed().as_secs_f32();
    let now = std::time::Instant::now();
    {
        let _ = js_sys::Promise::resolve(&JsValue::from(get_fibs_tokio_wasm(n, n).await));
    }
    let para_elapsed = now.elapsed().as_secs_f32();
    // if get_fibs is properly async, this should be ~2x as fast,
    // though the ratio won't be exactly the same between runs
    assert!(0.6 > para_elapsed / single_elapsed && para_elapsed / single_elapsed > 0.4);
}

The only way I'm aware of running the #[wasm_bindgen_test] is with wasm-pack, though if that's not a good tool to use for this purpose, I'd be eager to use something else! My main concern is being able to run the test function in a wasm runtime.